Repository: joke2k/faker
Pull request #1857 (2023-05-03 06:09:18)

Add zh_TW automotive license_plate rules and test functions
### What does this change

add zh_TW automotive license_plate rules

### What was wrong

was not implemented ever. 

### How this fixes it

will generate the fake license plate data in zh_TW locale

Fixes #...



Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index b6f33f98..d865cb3b 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 18.6.1
+current_version = 18.6.2
 files = VERSION faker/__init__.py docs/conf.py
 commit = True
 tag = True
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4762759a..95f88849 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,12 @@
 ## Changelog
 
+### [v18.6.2 - 2023-05-03](https://github.com/joke2k/faker/compare/v18.6.1...v18.6.2)
+
+*  Improve accuracy of departments in `fr_FR` provider `postcode`. Thanks @tonial.
+
 ### [v18.6.1 - 2023-05-02](https://github.com/joke2k/faker/compare/v18.6.0...v18.6.1)
 
-*  Fix `ssn` provider for `zh_TW`. Thanks @cyanghsieh.
+* Fix `ssn` provider for `zh_TW`. Thanks @cyanghsieh.
 
 ### [v18.6.0 - 2023-04-27](https://github.com/joke2k/faker/compare/v18.5.1...v18.6.0)
 
diff --git a/VERSION b/VERSION
index 219ed4bd..fc558a42 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-18.6.1
+18.6.2
diff --git a/docs/conf.py b/docs/conf.py
index ac629858..b0c2c3d6 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -51,9 +51,9 @@ copyright = "2014, Daniele Faraglia"
 # built documents.
 #
 # The short X.Y version.
-version = "18.6.1"
+version = "18.6.2"
 # The full version, including alpha/beta/rc tags.
-release = "18.6.1"
+release = "18.6.2"
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/faker/__init__.py b/faker/__init__.py
index 62aa6ec7..740d7bc3 100644
--- a/faker/__init__.py
+++ b/faker/__init__.py
@@ -2,6 +2,6 @@ from faker.factory import Factory
 from faker.generator import Generator
 from faker.proxy import Faker
 
-VERSION = "18.6.1"
+VERSION = "18.6.2"
 
 __all__ = ("Factory", "Generator", "Faker")
diff --git a/faker/providers/address/fr_FR/__init__.py b/faker/providers/address/fr_FR/__init__.py
index fa7010da..1125716e 100644
--- a/faker/providers/address/fr_FR/__init__.py
+++ b/faker/providers/address/fr_FR/__init__.py
@@ -46,7 +46,6 @@ class Provider(AddressProvider):
     address_formats = ("{{street_address}}\n{{postcode}} {{city}}",)
 
     building_number_formats = ("%", "%#", "%#", "%#", "%##")
-    postcode_formats = ("#####",)
     countries = (
         "Afghanistan",
         "Afrique du sud",
@@ -467,3 +466,13 @@ class Provider(AddressProvider):
         :example: '59'
         """
         return self.department()[0]
+
+    def postcode(self) -> str:
+        """
+        Randomly returns a postcode generated from existing french depertment number.
+        exemple: '33260'
+        """
+        department = self.department_number()
+        if department in ["2A", "2B"]:
+            department = "20"
+        return f"{department}{self.random_number(digits=5 - len(department))}"
diff --git a/faker/providers/automotive/zh_TW/__init__.py b/faker/providers/automotive/zh_TW/__init__.py
new file mode 100644
index 00000000..25542670
--- /dev/null
+++ b/faker/providers/automotive/zh_TW/__init__.py
@@ -0,0 +1,19 @@
+from .. import Provider as AutomotiveProvider
+
+
+class Provider(AutomotiveProvider):
+    """Implement automotive provider for ``zh_TW`` locale.
+
+    Sources:
+    - https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Taiwan
+
+    """
+
+    license_formats = (
+        "####-??",
+        "??-####",
+        # Commercial vehicles since 2012
+        "???-###",
+        # New format since 2014
+        "???-####",
+    )


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
index 0a0e2cbb..0e5c47ef 100644
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -865,6 +865,17 @@ class TestFrFr:
             assert isinstance(department_number, str)
             assert department_number in department_numbers
 
+    def test_postcode(self, faker, num_samples):
+        department_numbers = [dept_num for dept_num, dept_name in FrFrAddressProvider.departments]
+        for _ in range(num_samples):
+            postcode = faker.postcode()
+            assert isinstance(postcode, str)
+            assert (
+                postcode[:3] in department_numbers  # for 3 digits deparments number
+                or postcode[:2] == "20"  # for Corsica : "2A" or "2B"
+                or postcode[:2] in department_numbers  # any other
+            )
+
 
 class TestHeIl:
     """Test he_IL address provider methods"""
diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py
index 7768b531..654d4388 100644
--- a/tests/providers/test_automotive.py
+++ b/tests/providers/test_automotive.py
@@ -316,3 +316,14 @@ class TestNlBe(_SimpleAutomotiveTestMixin):
     """Test nl_BE automotive provider methods"""
 
     license_plate_pattern: Pattern = re.compile(r"(\d{3}-[A-Z]{3})|" r"([A-Z]{3}-\d{3})|" r"([1-2]-[A-Z]{3}-\d{3})")
+
+
+class TestZhTw(_SimpleAutomotiveTestMixin):
+    """Test zh_TW automotive provider methods"""
+
+    license_plate_pattern: Pattern = re.compile(
+        r"([A-Z]{2}-\d{4})|"  # prior 2012 v1
+        r"(\d{4}-[A-Z]{2})|"  # prior 2012 v2
+        r"([A-Z]{3}-\d{4})|"  # new format since 2014
+        r"([A-Z]{3}-\d{3})",  # commercial cars since 2012
+    )