From 71f4a471f8c4fe41a6bdee8e3c326c51804ee854 Mon Sep 17 00:00:00 2001 From: Adam Kamor Date: Thu, 30 Apr 2026 13:02:14 -0400 Subject: [PATCH] adding preserve area code --- docs/source/redact/generator_metadata.rst | 2 ++ .../metadata_tests/test_payload_serialization.py | 8 ++++++++ .../test_phone_number_generator_metadata_json.py | 12 +++++++++++- .../phone_number_generator_metadata.py | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/source/redact/generator_metadata.rst b/docs/source/redact/generator_metadata.rst index 59f7f90..0f36c03 100644 --- a/docs/source/redact/generator_metadata.rst +++ b/docs/source/redact/generator_metadata.rst @@ -105,6 +105,7 @@ Phone number synthesis * ``use_us_phone_number_generator`` (bool, default ``False``) -- When ``True``, generated telephone numbers use a US phone number format. * ``replace_invalid_numbers`` (bool, default ``True``) -- When ``True``, detected telephone numbers that are not valid are still replaced with synthesized values. +* ``preserve_us_area_code`` (bool, default ``False``) -- When ``True`` and ``use_us_phone_number_generator`` is also ``True``, the area code of the original phone number is preserved in the synthesized value. .. code-block:: python @@ -114,6 +115,7 @@ Phone number synthesis "PHONE_NUMBER": PhoneNumberGeneratorMetadata( use_us_phone_number_generator=True, replace_invalid_numbers=True, + preserve_us_area_code=True, ), } diff --git a/tests/tests/metadata_tests/test_payload_serialization.py b/tests/tests/metadata_tests/test_payload_serialization.py index 18a65e1..158375d 100644 --- a/tests/tests/metadata_tests/test_payload_serialization.py +++ b/tests/tests/metadata_tests/test_payload_serialization.py @@ -379,6 +379,7 @@ def test_to_payload_defaults(self): assert payload["swaps"] == {} assert payload["useUsPhoneNumberGenerator"] is False assert payload["replaceInvalidNumbers"] is True + assert payload["preserveUsAreaCode"] is False assert payload["constantValue"] is None def test_to_payload_with_values(self): @@ -386,6 +387,7 @@ def test_to_payload_with_values(self): generator_version=GeneratorVersion.V2, use_us_phone_number_generator=True, replace_invalid_numbers=False, + preserve_us_area_code=True, swaps={"555-1234": "555-5678"}, constant_value="REDACTED" ) @@ -396,6 +398,7 @@ def test_to_payload_with_values(self): assert payload["swaps"] == {"555-1234": "555-5678"} assert payload["useUsPhoneNumberGenerator"] is True assert payload["replaceInvalidNumbers"] is False + assert payload["preserveUsAreaCode"] is True assert payload["constantValue"] == "REDACTED" def test_from_payload_defaults(self): @@ -407,6 +410,7 @@ def test_from_payload_defaults(self): assert metadata.swaps == {} assert metadata.use_us_phone_number_generator is False assert metadata.replace_invalid_numbers is True + assert metadata.preserve_us_area_code is False assert metadata.constant_value is None def test_from_payload_with_values(self): @@ -416,6 +420,7 @@ def test_from_payload_with_values(self): "swaps": {"111": "222"}, "useUsPhoneNumberGenerator": True, "replaceInvalidNumbers": False, + "preserveUsAreaCode": True, "constantValue": "REDACTED" } metadata = PhoneNumberGeneratorMetadata.from_payload(payload) @@ -425,6 +430,7 @@ def test_from_payload_with_values(self): assert metadata.swaps == {"111": "222"} assert metadata.use_us_phone_number_generator is True assert metadata.replace_invalid_numbers is False + assert metadata.preserve_us_area_code is True assert metadata.constant_value == "REDACTED" def test_from_payload_invalid_generator_raises(self): @@ -438,6 +444,7 @@ def test_roundtrip(self): generator_version=GeneratorVersion.V2, use_us_phone_number_generator=True, replace_invalid_numbers=False, + preserve_us_area_code=True, swaps={"phone1": "phone2"}, constant_value="REDACTED" ) @@ -450,6 +457,7 @@ def test_roundtrip(self): assert restored.swaps == original.swaps assert restored.use_us_phone_number_generator == original.use_us_phone_number_generator assert restored.replace_invalid_numbers == original.replace_invalid_numbers + assert restored.preserve_us_area_code == original.preserve_us_area_code assert restored.constant_value == original.constant_value diff --git a/tests/tests/metadata_tests/test_phone_number_generator_metadata_json.py b/tests/tests/metadata_tests/test_phone_number_generator_metadata_json.py index 05f6217..160ad8c 100644 --- a/tests/tests/metadata_tests/test_phone_number_generator_metadata_json.py +++ b/tests/tests/metadata_tests/test_phone_number_generator_metadata_json.py @@ -12,6 +12,7 @@ def test_json_dumps_works_directly(self): generator_version=GeneratorVersion.V2, use_us_phone_number_generator=True, replace_invalid_numbers=False, + preserve_us_area_code=True, swaps={"555-1234": "555-5678"} ) json_str = json.dumps(metadata) @@ -22,6 +23,7 @@ def test_json_dumps_works_directly(self): assert parsed["generatorVersion"] == "V2" assert parsed["useUsPhoneNumberGenerator"] is True assert parsed["replaceInvalidNumbers"] is False + assert parsed["preserveUsAreaCode"] is True assert parsed["swaps"] == {"555-1234": "555-5678"} def test_json_includes_type_field(self): @@ -43,6 +45,7 @@ def test_json_roundtrip_with_defaults(self): assert restored.generator_version == original.generator_version assert restored.use_us_phone_number_generator == original.use_us_phone_number_generator assert restored.replace_invalid_numbers == original.replace_invalid_numbers + assert restored.preserve_us_area_code == original.preserve_us_area_code assert restored.swaps == original.swaps def test_json_roundtrip_with_custom_values(self): @@ -51,6 +54,7 @@ def test_json_roundtrip_with_custom_values(self): generator_version=GeneratorVersion.V2, use_us_phone_number_generator=True, replace_invalid_numbers=False, + preserve_us_area_code=True, swaps={"phone1": "phone2"} ) json_str = json.dumps(original) @@ -61,17 +65,20 @@ def test_json_roundtrip_with_custom_values(self): assert restored.generator_version == GeneratorVersion.V2 assert restored.use_us_phone_number_generator is True assert restored.replace_invalid_numbers is False + assert restored.preserve_us_area_code is True assert restored.swaps == {"phone1": "phone2"} def test_attribute_access_works(self): """Property-based attribute access should work.""" metadata = PhoneNumberGeneratorMetadata( use_us_phone_number_generator=True, - replace_invalid_numbers=False + replace_invalid_numbers=False, + preserve_us_area_code=True ) assert metadata.use_us_phone_number_generator is True assert metadata.replace_invalid_numbers is False + assert metadata.preserve_us_area_code is True assert metadata.custom_generator == GeneratorType.PhoneNumber def test_attribute_setter_works(self): @@ -79,11 +86,14 @@ def test_attribute_setter_works(self): metadata = PhoneNumberGeneratorMetadata() metadata.use_us_phone_number_generator = True metadata.replace_invalid_numbers = False + metadata.preserve_us_area_code = True assert metadata.use_us_phone_number_generator is True assert metadata["useUsPhoneNumberGenerator"] is True assert metadata.replace_invalid_numbers is False assert metadata["replaceInvalidNumbers"] is False + assert metadata.preserve_us_area_code is True + assert metadata["preserveUsAreaCode"] is True def test_dict_access_works(self): """Direct dict access should work.""" diff --git a/tonic_textual/classes/generator_metadata/phone_number_generator_metadata.py b/tonic_textual/classes/generator_metadata/phone_number_generator_metadata.py index 356ee00..838552d 100644 --- a/tonic_textual/classes/generator_metadata/phone_number_generator_metadata.py +++ b/tonic_textual/classes/generator_metadata/phone_number_generator_metadata.py @@ -20,6 +20,10 @@ class PhoneNumberGeneratorMetadata(BaseMetadata): When ``True``, phone numbers that are detected but are not valid phone numbers are replaced with synthesized values. Default is ``True``. + preserve_us_area_code : bool + When ``True`` and ``use_us_phone_number_generator`` is also ``True``, + the area code of the original phone number is preserved in the + synthesized value. Default is ``False``. """ def __init__( @@ -27,6 +31,7 @@ def __init__( generator_version: GeneratorVersion = GeneratorVersion.V1, use_us_phone_number_generator: bool = False, replace_invalid_numbers: bool = True, + preserve_us_area_code: bool = False, swaps: Optional[Dict[str,str]] = {}, constant_value: Optional[str] = None, ): @@ -38,6 +43,7 @@ def __init__( ) self["useUsPhoneNumberGenerator"] = use_us_phone_number_generator self["replaceInvalidNumbers"] = replace_invalid_numbers + self["preserveUsAreaCode"] = preserve_us_area_code @property def use_us_phone_number_generator(self) -> bool: @@ -55,6 +61,14 @@ def replace_invalid_numbers(self) -> bool: def replace_invalid_numbers(self, value: bool): self["replaceInvalidNumbers"] = value + @property + def preserve_us_area_code(self) -> bool: + return self["preserveUsAreaCode"] + + @preserve_us_area_code.setter + def preserve_us_area_code(self, value: bool): + self["preserveUsAreaCode"] = value + def to_payload(self) -> Dict: return dict(self) @@ -72,6 +86,7 @@ def from_payload(payload: Dict) -> "PhoneNumberGeneratorMetadata": generator_version=base_metadata.generator_version, use_us_phone_number_generator=payload.get("useUsPhoneNumberGenerator", False), replace_invalid_numbers=payload.get("replaceInvalidNumbers", True), + preserve_us_area_code=payload.get("preserveUsAreaCode", False), swaps=base_metadata.swaps, constant_value=base_metadata.constant_value )