Repository: joke2k/faker
Pull request #1938 (2023-10-23 14:34:30)

Add geo for cs_CZ
### What does this change

Add geo for cs_CZ

### What was wrong

Missing geo for cs_CZ


Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index cc8e119f..2e0a366a 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 19.11.0
+current_version = 19.11.1
 files = VERSION faker/__init__.py docs/conf.py
 commit = True
 tag = True
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7e0e82b..3ae44832 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 ## Changelog
 
+### [v19.11.1 - 2023-10-24](https://github.com/joke2k/faker/compare/v19.11.0...v19.11.1)
+
+* Fix handling for finnish ssn where `min_age` and `max_age` are the same. Thanks @Pakkanen1.
+
 ### [v19.11.0 - 2023-10-18](https://github.com/joke2k/faker/compare/v19.10.0...v19.11.0)
 
 * Add a few street names to `cs_CZ`. Thanks @george0st.
diff --git a/VERSION b/VERSION
index 22131b00..6a16e51a 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-19.11.0
+19.11.1
diff --git a/docs/conf.py b/docs/conf.py
index fdd04567..12823fcf 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 = "19.11.0"
+version = "19.11.1"
 # The full version, including alpha/beta/rc tags.
-release = "19.11.0"
+release = "19.11.1"
 
 # 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 c70cce16..27ebd963 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 = "19.11.0"
+VERSION = "19.11.1"
 
 __all__ = ("Factory", "Generator", "Faker")
diff --git a/faker/providers/geo/cs_CZ/__init__.py b/faker/providers/geo/cs_CZ/__init__.py
new file mode 100644
index 00000000..13296317
--- /dev/null
+++ b/faker/providers/geo/cs_CZ/__init__.py
@@ -0,0 +1,73 @@
+from .. import Provider as GeoProvider
+
+
+class Provider(GeoProvider):
+    # Source:
+    #   https://www.latlong.net/category/cities-59-15.html
+    #   https://github.com/33bcdd/souradnice-mest
+    land_coords = (
+        ("50.50301", "13.63617", "Most", "CZ", "Europe/Prague"),
+        ("50.23271", "12.87117", "Karlovy Vary", "CZ", "Europe/Prague"),
+        ("50.073658", "14.418540", "Praha", "CZ", "Europe/Prague"),
+        ("49.144482", "15.006139", "Jindřichův Hradec", "CZ", "Europe/Prague"),
+        ("48.975658", "14.480255", "České Budějovice", "CZ", "Europe/Prague"),
+        ("50.511002", "14.150558", "Terezín", "CZ", "Europe/Prague"),
+        ("49.183239", "15.454273", "Telč", "CZ", "Europe/Prague"),
+        ("49.952431", "15.268654", "Kutná Hora", "CZ", "Europe/Prague"),
+        ("49.593777", "17.250879", "Olomouc", "CZ", "Europe/Prague"),
+        ("49.738430", "13.373637", "Plzeň", "CZ", "Europe/Prague"),
+        ("48.812737", "14.317466", "Český Krumlov", "CZ", "Europe/Prague"),
+        ("49.195061", "16.606836", "Brno", "CZ", "Europe/Prague"),
+        ("50.598427", "13.610242", "Litvínov", "CZ", "Europe/Prague"),
+        ("49.820923", "18.262524", "Ostrava", "CZ", "Europe/Prague"),
+        ("49.967305", "14.086384", "Beroun", "CZ", "Europe/Prague"),
+        ("50.678620", "14.539799", "Česká Lípa", "CZ", "Europe/Prague"),
+        ("50.772656", "14.212861", "DĚČÍN", "CZ", "Europe/Prague"),
+        ("49.682031", "18.367422", "FRÝDEK-MÍSTEK", "CZ", "Europe/Prague"),
+        ("49.780492", "18.430725", "HAVÍŘOV", "CZ", "Europe/Prague"),
+        ("49.052354", "14.434371", "Hluboká nad Vltavou", "CZ", "Europe/Prague"),
+        ("50.210461", "15.825311", "HRADEC KRÁLOVÉ", "CZ", "Europe/Prague"),
+        ("50.463598", "13.410837", "Chomutov", "CZ", "Europe/Prague"),
+        ("50.703569", "15.429698", "Jablonec nad Jizerou", "CZ", "Europe/Prague"),
+        ("50.722153", "15.170414", "Jablonec nad Nisou", "CZ", "Europe/Prague"),
+        ("50.435433", "15.361144", "Jičín", "CZ", "Europe/Prague"),
+        ("49.415860", "15.595469", "Jihlava", "CZ", "Europe/Prague"),
+        ("49.939604", "14.188146", "Karlštejn", "CZ", "Europe/Prague"),
+        ("49.856752", "18.543319", "KARVINÁ", "CZ", "Europe/Prague"),
+        ("50.141799", "14.106846", "Kladno", "CZ", "Europe/Prague"),
+        ("50.525685", "14.047429", "Lhotka nad Labem", "CZ", "Europe/Prague"),
+        ("49.890040", "13.581715", "Lhotka u Radnic", "CZ", "Europe/Prague"),
+        ("50.055957", "16.268803", "Lhoty u Potštejna", "CZ", "Europe/Prague"),
+        ("50.766380", "15.054439", "Liberec", "CZ", "Europe/Prague"),
+        ("49.772128", "15.676917", "Maleč", "CZ", "Europe/Prague"),
+        ("50.413525", "14.908538", "Mladá Boleslav", "CZ", "Europe/Prague"),
+        ("49.425534", "16.256425", "Moravecké Pavlovice", "CZ", "Europe/Prague"),
+        ("49.940760", "17.894899", "Opava", "CZ", "Europe/Prague"),
+        ("49.916939", "17.869927", "Otice", "CZ", "Europe/Prague"),
+        ("50.034409", "15.781299", "Pardubice", "CZ", "Europe/Prague"),
+        ("49.472549", "17.106851", "PROSTĚJOV", "CZ", "Europe/Prague"),
+        ("49.456579", "17.450330", "PŘEROV", "CZ", "Europe/Prague"),
+        ("50.072880", "15.802625", "Ráby", "CZ", "Europe/Prague"),
+        ("49.458626", "18.143131", "Rožnov pod Radhoštěm", "CZ", "Europe/Prague"),
+        ("49.981095", "16.877925", "Ruda nad Moravou", "CZ", "Europe/Prague"),
+        ("50.020519", "17.377529", "Rudná pod Pradědem", "CZ", "Europe/Prague"),
+        ("50.454193", "16.036726", "Slatina nad Úpou", "CZ", "Europe/Prague"),
+        ("49.377245", "17.670437", "Slavkov pod Hostýnem", "CZ", "Europe/Prague"),
+        ("49.153354", "16.876598", "Slavkov u Brna", "CZ", "Europe/Prague"),
+        ("49.991014", "15.350597", "Svatý Mikuláš", "CZ", "Europe/Prague"),
+        ("49.977941", "16.971875", "Šumperk", "CZ", "Europe/Prague"),
+        ("49.413089", "14.677566", "Tábor", "CZ", "Europe/Prague"),
+        ("50.644558", "13.835384", "Teplice", "CZ", "Europe/Prague"),
+        ("49.214887", "15.879652", "Třebíč", "CZ", "Europe/Prague"),
+        ("49.677731", "18.670890", "Třinec", "CZ", "Europe/Prague"),
+        ("50.151203", "16.078551", "Týniště nad Orlicí", "CZ", "Europe/Prague"),
+        ("50.661216", "14.053246", "ÚSTÍ NAD LABEM", "CZ", "Europe/Prague"),
+        ("49.139664", "18.008570", "Valašské Klobouky", "CZ", "Europe/Prague"),
+        ("49.471904", "17.971237", "Valašské Meziříčí", "CZ", "Europe/Prague"),
+        ("49.954364", "16.164268", "Vysoké Mýto", "CZ", "Europe/Prague"),
+        ("49.224537", "17.662863", "ZLÍN", "CZ", "Europe/Prague"),
+        ("50.538847", "16.213389", "Žďár nad Metují", "CZ", "Europe/Prague"),
+        ("50.119855", "16.069446", "Žďár nad Orlicí", "CZ", "Europe/Prague"),
+        ("49.564288", "15.939507", "Žďár nad Sázavou", "CZ", "Europe/Prague"),
+        ("49.696057", "15.813706", "Ždírec nad Doubravou", "CZ", "Europe/Prague"),
+    )
diff --git a/faker/providers/ssn/fi_FI/__init__.py b/faker/providers/ssn/fi_FI/__init__.py
index 8e8bba6c..016782c0 100644
--- a/faker/providers/ssn/fi_FI/__init__.py
+++ b/faker/providers/ssn/fi_FI/__init__.py
@@ -26,7 +26,10 @@ class Provider(SsnProvider):
             checksum_characters = "0123456789ABCDEFHJKLMNPRSTUVWXY"
             return checksum_characters[int(hetu) % 31]
 
-        age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
+        if min_age == max_age:
+            age = datetime.timedelta(days=min_age * 365)
+        else:
+            age = datetime.timedelta(days=self.generator.random.randrange(min_age * 365, max_age * 365))
         birthday = datetime.date.today() - age
         hetu_date = "%02d%02d%s" % (
             birthday.day,


Test patch:
diff --git a/tests/providers/test_geo.py b/tests/providers/test_geo.py
index c043896d..e71b6678 100644
--- a/tests/providers/test_geo.py
+++ b/tests/providers/test_geo.py
@@ -79,6 +79,22 @@ class TestEnUS(unittest.TestCase):
         assert Decimal(loc[0])  # Should be able to cast first two elements of tuple to Decimal
         assert Decimal(loc[1])
 
+class TestCsCz(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("cs_CZ")
+        Faker.seed(0)
+
+    def test_location_on_land(self):
+        loc = self.fake.location_on_land()
+        assert isinstance(loc, tuple)
+        assert len(loc) == 5
+        assert Decimal(loc[0])  # Should be able to cast first two elements of tuple to Decimal
+        assert Decimal(loc[1])
+        assert isinstance(loc[2], str)  # Place is a string
+        assert isinstance(loc[3], str)  # Country code is a string
+        assert len(loc[3]) == 2  # Country code is two letters
+        assert isinstance(loc[4], str)  # Timezone is a string
+
 
 class TestDeAT(unittest.TestCase):
     """Tests in addresses in the de_AT locale"""
diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py
index 6765f54c..0672c086 100644
--- a/tests/providers/test_ssn.py
+++ b/tests/providers/test_ssn.py
@@ -793,6 +793,18 @@ class TestFiFI(unittest.TestCase):
         for _ in range(100):
             assert re.search(r"^FI\d{8}$", self.fake.vat_id())
 
+    def test_ssn_without_age_range(self):
+        current_year = datetime.now().year
+        age = current_year - 1995
+        ssn = self.fake.ssn(min_age=age, max_age=age, artificial=True)
+        assert "95-" in ssn
+        age = current_year - 2013
+        ssn = self.fake.ssn(min_age=age, max_age=age, artificial=True)
+        assert "13A" in ssn
+        age = current_year - 1898
+        ssn = self.fake.ssn(min_age=age, max_age=age, artificial=True)
+        assert "98+" in ssn
+
 
 class TestFrFR(unittest.TestCase):
     def setUp(self):