Repository: joke2k/faker
Pull request #853 (2018-10-26 14:44:08)

ru_RU license plates added
### What does this changes

Adds ru_RU license plates to providers/automotive

### What was wrong

faker license_plate -l ru_RU
02V MG9

### How this fixes it

faker license_plate -l ru_RU
Т174AB57



Patch:
diff --git a/faker/providers/address/de_AT/__init__.py b/faker/providers/address/de_AT/__init__.py
index 900aea1d..2baafedb 100644
--- a/faker/providers/address/de_AT/__init__.py
+++ b/faker/providers/address/de_AT/__init__.py
@@ -151,6 +151,12 @@ class Provider(AddressProvider):
     def state(self):
         return self.random_element(self.states)
 
+    def postcode(self):
+        return self.bothify(self.random_element(self.postcode_formats))
+
+    def city_with_postcode(self):
+        return self.postcode() + " " + self.random_element(self.cities)
+
     def latitude(self):
         return self.geo_coordinate(center=47.60707, radius=1)
 
diff --git a/faker/providers/automotive/ru_RU/__init__.py b/faker/providers/automotive/ru_RU/__init__.py
new file mode 100644
index 00000000..f56f3107
--- /dev/null
+++ b/faker/providers/automotive/ru_RU/__init__.py
@@ -0,0 +1,210 @@
+# coding=utf-8
+
+
+from __future__ import unicode_literals
+from .. import Provider as AutomotiveProvider
+
+
+class Provider(AutomotiveProvider):
+
+    # https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Russia
+    license_plate_letters = ('A', 'B', 'E', 'M', 'Н', 'О', 'Р', 'С', 'Т', 'У', 'Х')
+
+    license_plate_suffix = (
+        # Republic of Adygea
+        '01',
+        # Republic of Bashkortostan
+        '02', '102',
+        # Republic of Buryatia
+        '03',
+        # Altai Republic
+        '04',
+        # Republic of Dagestan
+        '05',
+        # Republic of Ingushetia
+        '06',
+        # Kabardino-Balkar Republic
+        '07',
+        # Republic of Kalmykia
+        '08',
+        # Karachay-Cherkess Republic
+        '09',
+        # Republic of Karelia
+        '10',
+        # Komi Republic
+        '11',
+        # Mari El Republic
+        '12',
+        # Republic of Mordovia
+        '13', '113',
+        # Sakha Republic
+        '14',
+        # Republic of North Ossetia–Alania
+        '15',
+        # Republic of Tatarstan
+        '16', '116', '716',
+        # Tuva Republic
+        '17',
+        # Udmurt Republic
+        '18',
+        # Republic of Khakassia
+        '19',
+        # Chechen Republic
+        '20', '95',
+        # Chuvash Republic
+        '21', '121',
+        # Altai Krai
+        '22',
+        # Krasnodar Krai
+        '23', '93', '123',
+        # Krasnoyarsk Krai
+        '24', '84', '88', '124',
+        # Primorsky Krai
+        '25', '125',
+        # Stavropol Krai
+        '26', '126',
+        # Khabarovsk Krai
+        '27',
+        # Amur Oblast
+        '28',
+        # Arkhangelsk Oblast
+        '29',
+        # Astrakhan Oblast
+        '30',
+        # Belgorod Oblast
+        '31',
+        # Bryansk Oblast
+        '32',
+        # Vladimir Oblast
+        '33',
+        # Volgograd Oblast
+        '34', '134',
+        # Vologda Oblast
+        '35',
+        # Voronezh Oblast
+        '36', '136',
+        # Ivanovo Oblast
+        '37',
+        # Irkutsk Oblast
+        '38', '85', '38',
+        # Kaliningrad Oblast
+        '39', '91',
+        # Kaluga Oblast
+        '40',
+        # Kamchatka Krai
+        '41', '82',
+        # Kemerovo Oblast
+        '42', '142',
+        # Kirov Oblast
+        '43',
+        # Kostroma Oblast
+        '44',
+        # Kurgan Oblast
+        '45',
+        # Kursk Oblast
+        '46',
+        # Leningrad Oblast
+        '47',
+        # Lipetsk Oblast
+        '48',
+        # Magadan Oblast
+        '49',
+        # Moscow Oblast
+        '50', '90', '150', '190', '750',
+        # Murmansk Oblast
+        '51',
+        # Nizhny Novgorod Oblast
+        '52', '152',
+        # Novgorod Oblast
+        '53',
+        # Novosibirsk Oblast
+        '54', '154',
+        # Omsk Oblast
+        '55',
+        # Orenburg Oblast
+        '56',
+        # Oryol Oblast
+        '57',
+        # Penza Oblast
+        '58',
+        # Perm Krai
+        '59', '81', '159',
+        # Pskov Oblast
+        '60',
+        # Rostov Oblast
+        '61', '161',
+        # Ryazan Oblast
+        '62',
+        # Samara Oblast
+        '63', '163', '763',
+        # Saratov Oblast
+        '64', '164',
+        # Sakhalin Oblast
+        '65',
+        # Sverdlovsk Oblast
+        '66', '96', '196',
+        # Smolensk Oblast
+        '67',
+        # Tambov Oblast
+        '68',
+        # Tver Oblast
+        '69',
+        # Tomsk Oblast
+        '70',
+        # Tula Oblast
+        '71',
+        # Tyumen Oblast
+        '72',
+        # Ulyanovsk Oblast
+        '73', '173',
+        # Chelyabinsk Oblast
+        '74', '174',
+        # Zabaykalsky Krai
+        '75', '80',
+        # Yaroslavl Oblast
+        '76',
+        # Moscow
+        '77', '97', '99', '177', '197', '199', '777', '799',
+        # St. Petersburg
+        '78', '98', '178', '198',
+        # Jewish Autonomous Oblast
+        '79',
+        # Agin-Buryat Okrug / "Former Buryat Autonomous District of Aginskoye"
+        '80',
+        # Komi-Permyak Okrug / "Former Komi-Permyak Autonomous District"
+        '81',
+        # Republic of Crimea / De jure part of Ukraine as Autonomous Republic. Annexed by Russia in 2014.
+        '82',
+        # Koryak Okrug / "Former Koryak Autonomous District"
+        '82',
+        # Nenets Autonomous Okrug (Nenetsia)
+        '83',
+        # Taymyr Autonomous Okrug / "Former Taymyr (Dolgan-Nenets) Autonomous District"
+        '84',
+        # Ust-Orda Buryat Okrug / "Former Buryat Autonomous District of Ust-Ordynskoy"
+        '85',
+        # Khanty-Mansi Autonomous Okrug
+        '86', '186',
+        # Chukotka Autonomous Okrug
+        '87',
+        # Evenk Autonomous Okrug / "Former Evenk Autonomous District"
+        '88',
+        # Yamalo-Nenets Autonomous Okrug
+        '89',
+        # Sevastopol / De jure part of Ukraine as City with special status. Annexed by Russia in 2014.
+        '92',
+        # Territories outside of the Russian Federation,
+        # served by the bodies of internal affairs of the Russian Federation, such as Baikonur
+        '94',
+    )
+
+    license_plate_number = (
+        '##%'
+    )
+
+    def license_plate(self):
+        return self.random_element(self.license_plate_letters) + \
+               self.numerify(self.generator.parse(self.license_plate_number)) + \
+               self.random_element(self.license_plate_letters) + \
+               self.random_element(self.license_plate_letters) + \
+               self.random_element(self.license_plate_suffix)


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
index 1787c563..f07d43da 100644
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -142,15 +142,19 @@ class TestDeAT(unittest.TestCase):
 
     def test_postcode(self):
         postcode = self.factory.postcode()
-        assert re.match("\d{4}", postcode)
+        assert re.match(r"\d{4}", postcode)
+
+    def test_city_with_postcode(self):
+        city_with_postcode = self.factory.city_with_postcode()
+        assert isinstance(city_with_postcode, string_types)
 
     def test_latitude(self):
         latitude = self.factory.latitude()
-        assert re.match("4[6-8]\.\d+", str(latitude))
+        assert re.match(r"4[6-8]\.\d+", str(latitude))
 
     def test_longitude(self):
         longitude = self.factory.longitude()
-        assert re.match("1[1-5]\.\d+", str(longitude))
+        assert re.match(r"1[1-5]\.\d+", str(longitude))
 
 
 class TestDeDE(unittest.TestCase):
@@ -244,7 +248,7 @@ class TestEnAU(unittest.TestCase):
     def test_postcode(self):
         for _ in range(100):
             postcode = self.factory.postcode()
-            assert re.match("\d{4}", postcode)
+            assert re.match(r"\d{4}", postcode)
 
     def test_state(self):
         state = self.factory.state()
@@ -277,7 +281,7 @@ class TestEnNZ(unittest.TestCase):
     def test_postcode(self):
         for _ in range(100):
             postcode = self.factory.postcode()
-            assert re.match("\d{4}", postcode)
+            assert re.match(r"\d{4}", postcode)
 
 
 class TestEnCA(unittest.TestCase):
@@ -289,18 +293,18 @@ class TestEnCA(unittest.TestCase):
     def test_postcode(self):
         for _ in range(100):
             postcode = self.factory.postcode()
-            assert re.match("[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]",
+            assert re.match(r"[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]",
                             postcode)
 
     def test_postalcode(self):
         for _ in range(100):
             postalcode = self.factory.postalcode()
-            assert re.match("[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]",
+            assert re.match(r"[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]",
                             postalcode)
 
     def test_postal_code_letter(self):
         postal_code_letter = self.factory.postal_code_letter()
-        assert re.match("[A-Z]", postal_code_letter)
+        assert re.match(r"[A-Z]", postal_code_letter)
 
     def test_province(self):
         province = self.factory.province()
@@ -363,29 +367,29 @@ class TestEnUS(unittest.TestCase):
     def test_postcode(self):
         for _ in range(100):
             postcode = self.factory.postcode()
-            assert re.match("\d{5}", postcode)
+            assert re.match(r"\d{5}", postcode)
 
     def test_zipcode(self):
         for _ in range(100):
             zipcode = self.factory.zipcode()
-            assert re.match("\d{5}", zipcode)
+            assert re.match(r"\d{5}", zipcode)
 
     def test_zipcode_plus4(self):
         for _ in range(100):
             zipcode_plus4 = self.factory.zipcode_plus4()
-            assert re.match("\d{5}(-\d{4})", zipcode_plus4)
+            assert re.match(r"\d{5}(-\d{4})", zipcode_plus4)
 
     def test_military_ship(self):
         military_ship = self.factory.military_ship()
         assert isinstance(military_ship, string_types)
         assert military_ship in EnUsProvider.military_ship_prefix
-        assert re.match("[A-Z]", military_ship)
+        assert re.match(r"[A-Z]", military_ship)
 
     def test_military_state(self):
         military_state = self.factory.military_state()
         assert isinstance(military_state, string_types)
         assert military_state in EnUsProvider.military_state_abbr
-        assert re.match("[A-Z]", military_state)
+        assert re.match(r"[A-Z]", military_state)
 
     def test_military_apo(self):
         military_apo = self.factory.military_apo()
@@ -483,15 +487,15 @@ class TestJaJP(unittest.TestCase):
 
         chome = self.factory.chome()
         assert isinstance(chome, string_types)
-        assert re.match("\d{1,2}丁目", chome)
+        assert re.match(r"\d{1,2}丁目", chome)
 
         ban = self.factory.ban()
         assert isinstance(ban, string_types)
-        assert re.match("\d{1,2}番", ban)
+        assert re.match(r"\d{1,2}番", ban)
 
         gou = self.factory.gou()
         assert isinstance(gou, string_types)
-        assert re.match("\d{1,2}号", gou)
+        assert re.match(r"\d{1,2}号", gou)
 
         building_name = self.factory.building_name()
         assert isinstance(building_name, string_types)
@@ -499,11 +503,11 @@ class TestJaJP(unittest.TestCase):
 
         postcode = self.factory.postcode()
         assert isinstance(postcode, string_types)
-        assert re.match("\d{3}-\d{4}", postcode)
+        assert re.match(r"\d{3}-\d{4}", postcode)
 
         zipcode = self.factory.zipcode()
         assert isinstance(zipcode, string_types)
-        assert re.match("\d{3}-\d{4}", zipcode)
+        assert re.match(r"\d{3}-\d{4}", zipcode)
 
         address = self.factory.address()
         assert isinstance(address, string_types)
@@ -518,15 +522,15 @@ class TestKoKR(unittest.TestCase):
     def test_address(self):
         postcode = self.factory.postcode()
         assert isinstance(postcode, string_types)
-        assert re.match("\d{5}", postcode)
+        assert re.match(r"\d{5}", postcode)
 
         postal_code = self.factory.postal_code()
         assert isinstance(postal_code, string_types)
-        assert re.match("\d{5}", postal_code)
+        assert re.match(r"\d{5}", postal_code)
 
         old_postal_code = self.factory.old_postal_code()
         assert isinstance(old_postal_code, string_types)
-        assert re.match("\d{3}-\d{3}", old_postal_code)
+        assert re.match(r"\d{3}-\d{3}", old_postal_code)
 
 
 class TestNeNP(unittest.TestCase):
diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py
index c46c2a24..784fe1d0 100644
--- a/tests/providers/test_automotive.py
+++ b/tests/providers/test_automotive.py
@@ -27,7 +27,7 @@ class TestHuHU(unittest.TestCase):
 
     def test_hu_HU_plate_format(self):
         plate = self.factory.license_plate()
-        assert re.match("[A-Z]{3}-\d{3}", plate), "%s is not in the correct format." % plate
+        assert re.match(r"[A-Z]{3}-\d{3}", plate), "%s is not in the correct format." % plate
 
 
 class TestDeDe(unittest.TestCase):
diff --git a/tests/providers/test_bank.py b/tests/providers/test_bank.py
index 2e58af46..b8f13714 100644
--- a/tests/providers/test_bank.py
+++ b/tests/providers/test_bank.py
@@ -14,7 +14,7 @@ class TestNoNO(unittest.TestCase):
 
     def test_bban(self):
         bban = self.factory.bban()
-        assert re.match("\d{11}", bban)
+        assert re.match(r"\d{11}", bban)
 
 
 class TestPlPL(unittest.TestCase):
@@ -25,8 +25,8 @@ class TestPlPL(unittest.TestCase):
 
     def test_bban(self):
         bban = self.factory.bban()
-        assert re.match("\d{26}", bban)
+        assert re.match(r"\d{26}", bban)
 
     def test_iban(self):
         iban = self.factory.iban()
-        assert re.match("PL\d{26}", iban)
+        assert re.match(r"PL\d{26}", iban)
diff --git a/tests/providers/test_file.py b/tests/providers/test_file.py
index 2d256076..fdc7780c 100644
--- a/tests/providers/test_file.py
+++ b/tests/providers/test_file.py
@@ -24,7 +24,7 @@ class TestFile(unittest.TestCase):
             assert re.search(r'\/\w+\/\w+\.(bmp|gif|jpeg|jpg|png|tiff)', file_path)
 
     def test_unix_device(self):
-        reg_device = re.compile('^/dev/(vd|sd|xvd)[a-z]$')
+        reg_device = re.compile(r'^/dev/(vd|sd|xvd)[a-z]$')
         # Test default
         for _ in range(100):
             path = self.factory.unix_device()
@@ -36,7 +36,7 @@ class TestFile(unittest.TestCase):
             assert path.startswith('/dev/sd')
 
     def test_unix_partition(self):
-        reg_part = re.compile('^/dev/(vd|sd|xvd)[a-z]\d$')
+        reg_part = re.compile(r'^/dev/(vd|sd|xvd)[a-z]\d$')
         # Test default
         for _ in range(100):
             path = self.factory.unix_partition()