Repository: joke2k/faker
Pull request #2084 (2024-08-10 14:02:25)

Incorrect City Spelling in uk_UA locale
### What does this change

The names of the following cities have been changed:

- Zaporizhia
- Odessa
- Khmelnytsky
- Kiev
- Uzhgorod
- Zaporozhye

### What was wrong

The current city names are not responding internationally recognized spelling.
[Wiki list of cities in Ukraine with correct spelling.](https://en.wikipedia.org/wiki/List_of_cities_in_Ukraine)
[Wiki list of administrative divisions in Ukraine with correct spelling.](https://en.wikipedia.org/wiki/Administrative_divisions_of_Ukraine)

### How this fixes it

- Zaporizhia -> Zaporizhzhia
- Odessa -> Odesa
- Khmelnytsky -> Khmelnytskyi
- Kiev -> Kyiv
- Uzhgorod -> Uzhhorod
- Zaporozhye -> Zaporizhzhia



Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 5248cdcf..b08a55d4 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 26.3.0
+current_version = 28.0.0
 files = VERSION faker/__init__.py docs/conf.py
 commit = True
 tag = True
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55a288c6..edf57d70 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
 ## Changelog
 
+### [v28.0.0 - 2024-08-23](https://github.com/joke2k/faker/compare/v27.4.0...v28.0.0)
+
+* Fix `pydecimal` handling of `positive` keyword. Thanks @tahzeer.
+
+### [v27.4.0 - 2024-08-21](https://github.com/joke2k/faker/compare/v27.3.0...v27.4.0)
+
+* Add person provider for `pk_PK` locale. Thanks @c2-tlhah
+
+### [v27.3.0 - 2024-08-21](https://github.com/joke2k/faker/compare/v27.2.0...v27.3.0)
+
+* Add providers for `vi_VN` locale. Thanks @ntd1683.
+
+### [v27.2.0 - 2024-08-21](https://github.com/joke2k/faker/compare/v27.1.0...v27.2.0)
+
+* Split names in `en_IN` person provider. Thanks @wh0th3h3llam1.
+
+### [v27.1.0 - 2024-08-21](https://github.com/joke2k/faker/compare/v27.0.0...v27.1.0)
+
+* Add address providoer for `en_MS` local. Thanks @carlosfunk.
+
+### [v27.0.0 - 2024-08-12](https://github.com/joke2k/faker/compare/v26.3.0...v27.0.0)
+
+* Re-introduce `part_of_speech` argument to `words()` method.
+
 ### [v26.3.0 - 2024-08-08](https://github.com/joke2k/faker/compare/v26.2.0...v26.3.0)
 
 * Extend `ro_RO` company localization with prefixes. Thanks @DDSNA.
diff --git a/VERSION b/VERSION
index c4697fd5..0b4dfcf0 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-26.3.0
+28.0.0
diff --git a/docs/coding_style.rst b/docs/coding_style.rst
index ba763397..fba24e91 100644
--- a/docs/coding_style.rst
+++ b/docs/coding_style.rst
@@ -11,6 +11,12 @@ Please include `type hints`_ for every provider method you write. An overview of
 
 You can find our complete flake8 configuration in the tox.ini_ file.
 
+Use `is` instead of `==` when comparing a variable to `None`, `False`, or `True` (see https://www.flake8rules.com/rules/E711.html)::
+
+
+    if my_var is None:
+        ...  # do something
+
 
 Data Sets
 ---------
@@ -21,6 +27,9 @@ and/or origin of the data. If the source is a wiki, please also include the date
 We only accept new data if it's coming from statistical sources, such as census or government institutions.
 This includes names and their distribution.
 
+You may include multiple sources, but each name must come from a source. We will not accept list of names compiled
+exclusively by contributors.
+
 
 Name Lists
 ----------
diff --git a/docs/conf.py b/docs/conf.py
index 1d5e8110..6fcd234e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -51,9 +51,9 @@ copyright = f"2014-{datetime.now().year}, Daniele Faraglia"
 # built documents.
 #
 # The short X.Y version.
-version = "26.3.0"
+version = "28.0.0"
 # The full version, including alpha/beta/rc tags.
-release = "26.3.0"
+release = "28.0.0"
 
 # 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 c58b8e56..f9d75d2e 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 = "26.3.0"
+VERSION = "28.0.0"
 
 __all__ = ("Factory", "Generator", "Faker")
diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py
index add840a7..fec2f1b0 100644
--- a/faker/providers/__init__.py
+++ b/faker/providers/__init__.py
@@ -108,6 +108,7 @@ class BaseProvider:
             "NG",
             "NZ",
             "PH",
+            "PK",
             "SG",
             "US",
             "ZA",
diff --git a/faker/providers/address/en_MS/__init__.py b/faker/providers/address/en_MS/__init__.py
new file mode 100644
index 00000000..0983ff6e
--- /dev/null
+++ b/faker/providers/address/en_MS/__init__.py
@@ -0,0 +1,486 @@
+from collections import OrderedDict
+from typing import Dict, List, Optional
+
+from ... import ElementsType
+from ..en import Provider as AddressProvider
+
+# https://en.wikipedia.org/wiki/Addresses_in_Malaysia
+
+
+class Provider(AddressProvider):
+    # 'Bandar' and 'Taman' are the most common township prefix
+    # https://en.wikipedia.org/wiki/Template:Greater_Kuala_Lumpur > Townships
+    # https://en.wikipedia.org/wiki/Template:Johor > Townships
+    # https://en.wikipedia.org/wiki/Template:Kedah > Townships
+    # https://en.wikipedia.org/wiki/Template:Kelantan > Townships
+    # https://en.wikipedia.org/wiki/Template:Melaka > Townships
+    # https://en.wikipedia.org/wiki/Template:Negeri_Sembilan > Townships
+    # https://en.wikipedia.org/wiki/Template:Perak > Townships
+    # https://en.wikipedia.org/wiki/Template:Penang > Townships
+    # https://en.wikipedia.org/wiki/Template:Selangor > Townships
+    # https://en.wikipedia.org/wiki/Template:Terengganu > Townships
+
+    city_prefixes = (
+        "Alam",
+        "Apartment",
+        "Ara",
+        "Bandar",
+        "Bandar",
+        "Bandar",
+        "Bandar",
+        "Bandar",
+        "Bandar",
+        "Bandar Bukit",
+        "Bandar Seri",
+        "Bandar Sri",
+        "Bandar Baru",
+        "Batu",
+        "Bukit",
+        "Desa",
+        "Damansara",
+        "Kampung",
+        "Kampung Baru",
+        "Kampung Baru",
+        "Kondominium",
+        "Kota",
+        "Laman",
+        "Lembah",
+        "Medan",
+        "Pandan",
+        "Pangsapuri",
+        "Petaling",
+        "Puncak",
+        "Seri",
+        "Sri",
+        "Taman",
+        "Taman",
+        "Taman",
+        "Taman",
+        "Taman",
+        "Taman",
+        "Taman Desa",
+    )
+
+    city_suffixes = (
+        "Aman",
+        "Amanjaya",
+        "Anggerik",
+        "Angkasa",
+        "Antarabangsa",
+        "Awan",
+        "Bahagia",
+        "Bangsar",
+        "Baru",
+        "Belakong",
+        "Bendahara",
+        "Bestari",
+        "Bintang",
+        "Brickfields",
+        "Casa",
+        "Changkat",
+        "Country Heights",
+        "Damansara",
+        "Damai",
+        "Dato Harun",
+        "Delima",
+        "Duta",
+        "Flora",
+        "Gembira",
+        "Genting",
+        "Harmoni",
+        "Hartamas",
+        "Impian",
+        "Indah",
+        "Intan",
+        "Jasa",
+        "Jaya",
+        "Keramat",
+        "Kerinchi",
+        "Kiara",
+        "Kinrara",
+        "Kuchai",
+        "Laksamana",
+        "Mahkota",
+        "Maluri",
+        "Manggis",
+        "Maxwell",
+        "Medan",
+        "Melawati",
+        "Menjalara",
+        "Meru",
+        "Mulia",
+        "Mutiara",
+        "Pahlawan",
+        "Perdana",
+        "Pertama",
+        "Permai",
+        "Pelangi",
+        "Petaling",
+        "Pinang",
+        "Puchong",
+        "Puteri",
+        "Putra",
+        "Rahman",
+        "Rahmat",
+        "Raya",
+        "Razak",
+        "Ria",
+        "Saujana",
+        "Segambut",
+        "Selamat",
+        "Selatan",
+        "Semarak",
+        "Sentosa",
+        "Seputeh",
+        "Setapak",
+        "Setia Jaya",
+        "Sinar",
+        "Sungai Besi",
+        "Sungai Buaya",
+        "Sungai Long",
+        "Suria",
+        "Tasik Puteri",
+        "Tengah",
+        "Timur",
+        "Tinggi",
+        "Tropika",
+        "Tun Hussein Onn",
+        "Tun Perak",
+        "Tunku",
+        "Ulu",
+        "Utama",
+        "Utara",
+        "Wangi",
+    )
+
+    # https://en.wikipedia.org/wiki/States_and_federal_territories_of_Malaysia
+    states: Dict[str, List[str]] = {
+        "JHR": ["Johor Darul Ta'zim", "Johor"],
+        "KDH": ["Kedah Darul Aman", "Kedah"],
+        "KTN": ["Kelantan Darul Naim", "Kelantan"],
+        "KUL": ["KL", "Kuala Lumpur", "WP Kuala Lumpur"],
+        "LBN": ["Labuan"],
+        "MLK": ["Malacca", "Melaka"],
+        "NSN": ["Negeri Sembilan Darul Khusus", "Negeri Sembilan"],
+        "PHG": ["Pahang Darul Makmur", "Pahang"],
+        "PNG": ["Penang", "Pulau Pinang"],
+        "PRK": ["Perak Darul Ridzuan", "Perak"],
+        "PLS": ["Perlis Indera Kayangan", "Perlis"],
+        "PJY": ["Putrajaya"],
+        "SBH": ["Sabah"],
+        "SWK": ["Sarawak"],
+        "SGR": ["Selangor Darul Ehsan", "Selangor"],
+        "TRG": ["Terengganu Darul Iman", "Terengganu"],
+    }
+
+    states_postcode = {
+        "PLS": [(1000, 2800)],
+        "KDH": [(5000, 9810)],
+        "PNG": [(10000, 14400)],
+        "KTN": [(15000, 18500)],
+        "TRG": [(20000, 24300)],
+        "PHG": [
+            (25000, 28800),
+            (39000, 39200),
+            (49000, 69000),
+        ],
+        "PRK": [(30000, 36810)],
+        "SGR": [(40000, 48300), (63000, 68100)],
+        "KUL": [(50000, 60000)],
+        "PJY": [(62000, 62988)],
+        "NSN": [(70000, 73509)],
+        "MLK": [(75000, 78309)],
+        "JHR": [(79000, 86900)],
+        "LBN": [(87000, 87033)],
+        "SBH": [(88000, 91309)],
+        "SWK": [(93000, 98859)],
+    }
+
+    city_prefix_abbrs: ElementsType[str] = (
+        "SS",
+        "Seksyen ",
+        "PJS",
+        "PJU",
+        "USJ ",
+    )
+
+    def city_prefix_abbr(self) -> str:
+        return self.random_element(self.city_prefix_abbrs)
+
+    city_formats: ElementsType[str] = (
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix}} {{city_suffix}}",
+        "{{city_prefix_abbr}}%",
+        "{{city_prefix_abbr}}%#",
+        "{{city_prefix_abbr}}%#?",
+    )
+
+    def city(self) -> str:
+        pattern: str = self.bothify(self.random_element(self.city_formats))
+        return self.generator.parse(pattern)
+
+    # https://en.wikipedia.org/wiki/List_of_roads_in_Kuala_Lumpur#Standard_translations
+    street_prefixes: ElementsType[str] = [
+        "Jln",
+        "Jln",
+        "Jalan",
+        "Jalan",
+        "Jalan",
+        "Lorong",
+    ]
+
+    def street_prefix(self) -> str:
+        return self.random_element(self.street_prefixes)
+
+    # https://en.wikipedia.org/wiki/List_of_roads_in_Kuala_Lumpur
+    # https://en.wikipedia.org/wiki/List_of_roads_in_Ipoh
+    # https://en.wikipedia.org/wiki/Transportation_in_Seremban#Inner_city_roads
+    # https://en.wikipedia.org/wiki/List_of_streets_in_George_Town,_Penang
+    street_suffixes: ElementsType[str] = [
+        "Air Itam",
+        "Alor",
+        "Ampang",
+        "Ampang Hilir",
+        "Anson",
+        "Ariffin",
+        "Bangsar",
+        "Baru",
+        "Bellamy",
+        "Birch",
+        "Bijih Timah",
+        "Bukit Aman",
+        "Bukit Bintang",
+        "Bukit Petaling",
+        "Bukit Tunku",
+        "Cantonment",
+        "Cenderawasih",
+        "Chan Sow Lin",
+        "Chow Kit",
+        "Cinta",
+        "Cochrane",
+        "Conlay",
+        "D. S. Ramanathan",
+        "Damansara",
+        "Dang Wangi",
+        "Davis",
+        "Dewan Bahasa",
+        "Dato Abdul Rahman",
+        "Dato'Keramat",
+        "Dato' Maharaja Lela",
+        "Doraisamy",
+        "Eaton",
+        "Faraday",
+        "Galloway",
+        "Genting Klang",
+        "Gereja",
+        "Hang Jebat",
+        "Hang Kasturi",
+        "Hang Lekir",
+        "Hang Lekiu",
+        "Hang Tuah",
+        "Hospital",
+        "Imbi",
+        "Istana",
+        "Jelutong",
+        "Kampung Attap",
+        "Kebun Bunga",
+        "Kedah",
+        "Keliling",
+        "Kia Peng",
+        "Kinabalu",
+        "Kuala Kangsar",
+        "Kuching",
+        "Ledang",
+        "Lembah Permai",
+        "Loke Yew",
+        "Lt. Adnan",
+        "Lumba Kuda",
+        "Madras",
+        "Magazine",
+        "Maharajalela",
+        "Masjid",
+        "Maxwell",
+        "Mohana Chandran",
+        "Muda",
+        "P. Ramlee",
+        "Padang Kota Lama",
+        "Pahang",
+        "Pantai Baharu",
+        "Parlimen",
+        "Pasar",
+        "Pasar Besar",
+        "Perak",
+        "Perdana",
+        "Petaling",
+        "Prangin",
+        "Pudu",
+        "Pudu Lama",
+        "Raja",
+        "Raja Abdullah",
+        "Raja Chulan",
+        "Raja Laut",
+        "Rakyat",
+        "Residensi",
+        "Robson",
+        "S.P. Seenivasagam",
+        "Samarahan 1",
+        "Selamat",
+        "Sempadan",
+        "Sentul",
+        "Serian 1",
+        "Sasaran",
+        "Sin Chee",
+        "Sultan Abdul Samad",
+        "Sultan Azlan Shah",
+        "Sultan Iskandar",
+        "Sultan Ismail",
+        "Sultan Sulaiman",
+        "Sungai Besi",
+        "Syed Putra",
+        "Tan Cheng Lock",
+        "Thambipillay",
+        "Tugu",
+        "Tuanku Abdul Halim",
+        "Tuanku Abdul Rahman",
+        "Tun Abdul Razak",
+        "Tun Dr Ismail",
+        "Tun H S Lee",
+        "Tun Ismail",
+        "Tun Perak",
+        "Tun Razak",
+        "Tun Sambanthan",
+        "U-Thant",
+        "Utama",
+        "Vermont",
+        "Vivekananda",
+        "Wan Kadir",
+        "Wesley",
+        "Wisma Putra",
+        "Yaacob Latif",
+        "Yap Ah Loy",
+        "Yap Ah Shak",
+        "Yap Kwan Seng",
+        "Yew",
+        "Zaaba",
+        "Zainal Abidin",
+    ]
+
+    street_name_formats: ElementsType[str] = (
+        "{{street_prefix}} %",
+        "{{street_prefix}} %/%",
+        "{{street_prefix}} %/%#",
+        "{{street_prefix}} %/%?",
+        "{{street_prefix}} %/%#?",
+        "{{street_prefix}} %?",
+        "{{street_prefix}} %#?",
+        "{{street_prefix}} {{street_suffix}}",
+        "{{street_prefix}} {{street_suffix}} %",
+        "{{street_prefix}} {{street_suffix}} %/%",
+        "{{street_prefix}} {{street_suffix}} %/%#",
+        "{{street_prefix}} {{street_suffix}} %/%?",
+        "{{street_prefix}} {{street_suffix}} %/%#?",
+        "{{street_prefix}} {{street_suffix}} %?",
+        "{{street_prefix}} {{street_suffix}} %#?",
+    )
+
+    def street_name(self) -> str:
+        """
+        :example: 'Crist Parks'
+        """
+        pattern: str = self.bothify(self.random_element(self.street_name_formats))
+        return self.generator.parse(pattern)
+
+    building_prefixes: ElementsType[str] = [
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "No. ",
+        "No. ",
+        "No. ",
+        "Lot ",
+    ]
+
+    def building_prefix(self) -> str:
+        return self.random_element(self.building_prefixes)
+
+    building_number_formats: ElementsType[str] = (
+        "%",
+        "%",
+        "%",
+        "%#",
+        "%#",
+        "%#",
+        "%#",
+        "%##",
+        "%-%",
+        "?-##-##",
+        "%?-##",
+    )
+
+    def building_number(self) -> str:
+        return self.bothify(self.random_element(self.building_number_formats))
+
+    street_address_formats: ElementsType[str] = ("{{building_prefix}}{{building_number}}, {{street_name}}",)
+
+    def city_state(self) -> str:
+        """Return the complete city address with matching postcode and state
+
+        Example: 55100 Bukit Bintang, Kuala Lumpur
+        """
+        state: str = self.random_element(self.states.keys())
+        postcode = self.postcode_in_state(state)
+        city = self.city()
+        state_name: str = self.random_element(self.states[state])
+
+        return f"{postcode} {city}, {state_name}"
+
+    # https://en.wikipedia.org/wiki/Addresses_in_Malaysia
+    # street number, street name, region, and town/city, state.
+    address_formats = OrderedDict((("{{street_address}}, {{city}}, {{city_state}}", 100.0),))
+
+    def city_prefix(self) -> str:
+        return self.random_element(self.city_prefixes)
+
+    def administrative_unit(self) -> str:
+        return self.random_element(self.states[self.random_element(self.states.keys())])
+
+    state = administrative_unit
+
+    def postcode_in_state(self, state_abbr: Optional[str] = None) -> str:
+        """
+        :returns: A random postcode within the provided state
+
+        :param state: A state
+
+        Example: 55100
+        https://en.wikipedia.org/wiki/Postal_codes_in_Malaysia#States
+        """
+
+        if state_abbr is None:
+            state_abbr = self.random_element(self.states.keys())
+
+        try:
+            # some states have multiple ranges so first pick one, then generate a random postcode
+            range = self.generator.random.choice(self.states_postcode[state_abbr])
+            postcode = "%d" % (self.generator.random.randint(*range))
+
+            # zero left pad up until desired length (some have length 3 or 4)
+            target_postcode_len = 5
+            current_postcode_len = len(postcode)
+            if current_postcode_len < target_postcode_len:
+                pad = target_postcode_len - current_postcode_len
+                postcode = f"{'0'*pad}{postcode}"
+
+            return postcode
+        except KeyError as e:
+            raise KeyError("State Abbreviation not found in list") from e
+
+    def postcode(self) -> str:
+        return self.postcode_in_state(None)
diff --git a/faker/providers/address/vi_VN/__init__.py b/faker/providers/address/vi_VN/__init__.py
new file mode 100644
index 00000000..64bade2f
--- /dev/null
+++ b/faker/providers/address/vi_VN/__init__.py
@@ -0,0 +1,307 @@
+"""This module provides address-related functionalities for Vietnamese addresses."""
+
+from collections import OrderedDict
+from typing import Optional, Tuple
+
+from .. import Provider as AddressProvider
+
+
+class Provider(AddressProvider):
+    """Provider for generating Vietnamese addresses.
+    Sources:
+
+    # https://vi.wikipedia.org/wiki/B%E1%BA%A3n_m%E1%BA%ABu:K%C3%BD_hi%E1%BB%87u_quy_%C6%B0%E1%BB%9Bc_c%C3%A1c_t%E1%BB%89nh_th%C3%A0nh_Vi%E1%BB%87t_Nam
+    """
+
+    city_prefixes = ("Thành phố", "Quận", "Huyện", "Thị xã")
+
+    city_suffixes = (
+        "Thành phố",
+        "Quận",
+        "Huyện",
+        "Thị xã",
+        "Xã",
+        "Phường",
+    )
+
+    building_number_formats = ("###", "##", "#")
+
+    street_suffixes = (
+        "Đường",
+        "Ngõ",
+        "Hẻm",
+        "Làng",
+        "Khu",
+        "Tổ",
+        "Số",
+        "Dãy",
+    )
+
+    postcode_formats = ("######",)
+
+    provinces = (
+        "An Giang",
+        "Bà Rịa – Vũng Tàu",
+        "Bạc Liêu",
+        "Bắc Kạn",
+        "Bắc Giang",
+        "Bắc Ninh",
+        "Bến Tre",
+        "Bình Dương",
+        "Bình Định",
+        "Bình Phước",
+        "Bình Thuận",
+        "Cà Mau",
+        "Cao Bằng",
+        "Cần Thơ",
+        "Đà Nẵng",
+        "Đắk Lắk",
+        "Đắk Nông",
+        "Điện Biên",
+        "Đồng Nai",
+        "Đồng Tháp",
+        "Gia Lai",
+        "Hà Giang",
+        "Hà Nam",
+        "Hà Nội",
+        "Hà Tĩnh",
+        "Hải Dương",
+        "Hải Phòng",
+        "Hậu Giang",
+        "Hòa Bình",
+        "Thành phố Hồ Chí Minh",
+        "Hưng Yên",
+        "Khánh Hòa",
+        "Kiên Giang",
+        "Kon Tum",
+        "Lai Châu",
+        "Lạng Sơn",
+        "Lào Cai",
+        "Lâm Đồng",
+        "Long An",
+        "Nam Định",
+        "Nghệ An",
+        "Ninh Bình",
+        "Ninh Thuận",
+        "Phú Thọ",
+        "Phú Yên",
+        "Quảng Bình",
+        "Quảng Nam",
+        "Quảng Ngãi",
+        "Quảng Ninh",
+        "Quảng Trị",
+        "Sóc Trăng",
+        "Sơn La",
+        "Tây Ninh",
+        "Thái Bình",
+        "Thái Nguyên",
+        "Thanh Hóa",
+        "Thừa Thiên Huế",
+        "Tiền Giang",
+        "Trà Vinh",
+        "Tuyên Quang",
+        "Vĩnh Long",
+        "Vĩnh Phúc",
+        "Yên Bái",
+    )
+
+    provinces_abbr = (
+        "AG",
+        "BV",
+        "BL",
+        "BK",
+        "BG",
+        "BN",
+        "BT",
+        "BD",
+        "BĐ",
+        "BP",
+        "BTh",
+        "CM",
+        "CB",
+        "CT",
+        "ĐNa",
+        "ĐL",
+        "ĐNo",
+        "ĐB",
+        "ĐN",
+        "ĐT",
+        "GL",
+        "HG",
+        "HNa",
+        "HN",
+        "HT",
+        "HD",
+        "HP",
+        "HGi",
+        "HB",
+        "SG",
+        "HY",
+        "KH",
+        "KG",
+        "KT",
+        "LC",
+        "LS",
+        "LCa",
+        "LĐ",
+        "LA",
+        "NĐ",
+        "NA",
+        "NB",
+        "NT",
+        "PT",
+        "PY",
+        "QB",
+        "QNa",
+        "QNg",
+        "QN",
+        "QT",
+        "ST",
+        "SL",
+        "TN",
+        "TB",
+        "TNg",
+        "TH",
+        "TTH",
+        "TG",
+        "TV",
+        "TQ",
+        "VL",
+        "VP",
+        "YB",
+    )
+
+    provinces_postcode = {
+        "AG": (88000, 88999),
+        "BV": (79000, 79999),
+        "BL": (96000, 96999),
+        "BK": (26000, 26999),
+        "BG": (23000, 23999),
+        "BN": (22000, 22999),
+        "BT": (93000, 93999),
+        "BD": (82000, 82999),
+        "BĐ": (59000, 59999),
+        "BP": (83000, 83999),
+        "BTh": (80000, 80999),
+        "CM": (97000, 97999),
+        "CB": (27000, 27999),
+        "CT": (92000, 92999),
+        "ĐNa": (55000, 55999),
+        "ĐL": (63000, 63999),
+        "ĐNo": (64000, 64999),
+        "ĐB": (38000, 38999),
+        "ĐN": (81000, 81999),
+        "ĐT": (87000, 87999),
+        "GL": (60000, 60999),
+        "HG": (31000, 31999),
+        "HNa": (40000, 40999),
+        "HN": (10000, 15999),
+        "HT": (48000, 48999),
+        "HD": (17000, 17999),
+        "HP": (18000, 18999),
+        "HGi": (91000, 91999),
+        "HB": (35000, 35999),
+        "SG": (70000, 76999),
+        "HY": (16000, 16999),
+        "KH": (65000, 65999),
+        "KG": (92000, 92999),
+        "KT": (58000, 58999),
+        "LC": (39000, 39999),
+        "LS": (24000, 24999),
+        "LCa": (33000, 33999),
+        "LĐ": (67000, 67999),
+        "LA": (85000, 85999),
+        "NĐ": (42000, 42999),
+        "NA": (46000, 47999),
+        "NB": (43000, 43999),
+        "NT": (66000, 66999),
+        "PT": (29000, 29999),
+        "PY": (62000, 62999),
+        "QB": (51000, 51999),
+        "QNa": (56000, 56999),
+        "QNg": (57000, 57999),
+        "QN": (20000, 20999),
+        "QT": (52000, 52999),
+        "ST": (95000, 95999),
+        "SL": (36000, 36999),
+        "TN": (84000, 84999),
+        "TB": (41000, 41999),
+        "TNg": (25000, 25999),
+        "TH": (44000, 45999),
+        "TTH": (53000, 53999),
+        "TG": (86000, 86999),
+        "TV": (94000, 94999),
+        "TQ": (30000, 30999),
+        "VL": (89000, 89999),
+        "VP": (28000, 28999),
+        "YB": (32000, 32999),
+    }
+
+    address_formats = OrderedDict(
+        (
+            ("{{street_address}}\n{{city}}, {{postcode}}", 25.0),
+            ("{{city}}\n{{street_address}}, {{postcode}}", 1.0),
+        )
+    )
+
+    city_formats = (
+        "{{city_prefix}} {{first_name}}{{city_suffix}}",
+        "{{first_name}}{{city_suffix}}",
+    )
+
+    street_name_formats = (
+        "{{first_name}} {{street_suffix}}",
+        "{{last_name}} {{street_suffix}}",
+    )
+
+    street_address_formats = ("{{building_number}} {{street_name}}",)
+
+    def city_prefix(self) -> str:
+        """Returns a random city prefix."""
+        return self.random_element(self.city_prefixes)
+
+    def administrative_unit(self) -> str:
+        """Returns a random administrative unit (province)."""
+        return self.random_element(self.provinces)
+
+    state = administrative_unit
+
+    def state_abbr(self) -> str:
+        """
+        Returns a random two-letter abbreviation for Vietnamese provinces.
+
+        """
+        abbreviations: Tuple[str, ...] = self.provinces_abbr
+        return self.random_element(abbreviations)
+
+    def postcode(self) -> str:
+        """Returns a random postcode."""
+        return f"{self.generator.random.randint(100000, 999999):06d}"
+
+    def postcode_in_state(self, state_abbr: Optional[str] = None) -> str:
+        """
+        Returns a random postcode within the provided province abbreviation.
+
+        :param state_abbr: A province abbreviation.
+        :returns: A random postcode within the provided province abbreviation.
+        """
+        if state_abbr is None:
+            state_abbr = self.random_element(self.provinces_abbr)
+
+        if state_abbr in self.provinces_abbr:
+            postcode = str(
+                self.generator.random.randint(
+                    self.provinces_postcode[state_abbr][0], self.provinces_postcode[state_abbr][1]
+                )
+            )
+
+            # zero left pad up until desired length (length is 6)
+            target_postcode_len = 6
+            current_postcode_len = len(postcode)
+            if current_postcode_len < target_postcode_len:
+                pad = target_postcode_len - current_postcode_len
+                postcode = f"{'0' * pad}{postcode}"
+
+            return postcode
+
+        raise ValueError("Province Abbreviation not found in list")
diff --git a/faker/providers/automotive/uk_UA/__init__.py b/faker/providers/automotive/uk_UA/__init__.py
index 2e933f38..933153b3 100644
--- a/faker/providers/automotive/uk_UA/__init__.py
+++ b/faker/providers/automotive/uk_UA/__init__.py
@@ -18,20 +18,20 @@ class Provider(AutomotiveProvider):
         "Kyiv_reg": (("AI", "KI", "TI", "ME"), "10"),
         "Zhytomyr": (("AM", "KM", "TM", "MV"), "06"),
         "Zakarpattia": (("AO", "KO", "MT", "MO"), "07"),
-        "Zaporizhia": (("AR", "KR", "TR", "MR"), "08"),
+        "Zaporizhzhia": (("AR", "KR", "TR", "MR"), "08"),
         "IvanoFrankivsk": (("AT", "KT", "TO", "XS"), "09"),
         "Kirovohrad": (("BA", "NA", "XA", "EA"), "12"),
         "Luhansk": (("BB", "NV", "EE", "EV"), "13"),
         "Lviv": (("BS", "NS", "SS", "ES"), "14"),
         "Mykolaiv": (("BE", "NE", "XE", "XN"), "15"),
-        "Odessa": (("BN", "NN", "OO", "EN"), "16"),
+        "Odesa": (("BN", "NN", "OO", "EN"), "16"),
         "Poltava": (("BI", "NI", "XI", "EI"), "17"),
         "Rivne": (("BK", "NK", "XK", "EK"), "18"),
         "Sumy": (("BM", "NM", "XM", "EM"), "19"),
         "Ternopil": (("BO", "NO", "XO", "EO"), "20"),
         "Kharkiv": (("AX", "KX", "XX", "EX"), "21"),
         "Kherson": (("BT", "NT", "XT", "ET"), "22"),
-        "Khmelnytsky": (("BX", "NX", "OX", "RX"), "23"),
+        "Khmelnytskyi": (("BX", "NX", "OX", "RX"), "23"),
         "Cherkasy": (("SA", "IA", "OA", "RA"), "24"),
         "Chernihiv": (("SV", "IV", "OV", "RV"), "25"),
         "Chernivtsi": (("SE", "IE", "OE", "RE"), "26"),
diff --git a/faker/providers/color/color.py b/faker/providers/color/color.py
index 47b64e0c..756942bf 100644
--- a/faker/providers/color/color.py
+++ b/faker/providers/color/color.py
@@ -145,7 +145,7 @@ class RandomColor:
             self.random = generator.random
         else:
             self.seed = seed if seed else random.randint(0, sys.maxsize)
-            self.random = random.Random(self.seed)
+            self.random = random.Random(int(self.seed))
 
     def generate(
         self,
diff --git a/faker/providers/color/vi_VN/__init__.py b/faker/providers/color/vi_VN/__init__.py
new file mode 100644
index 00000000..1d06fd0b
--- /dev/null
+++ b/faker/providers/color/vi_VN/__init__.py
@@ -0,0 +1,90 @@
+from collections import OrderedDict
+
+from .. import Provider as ColorProvider
+
+localized = True
+
+
+class Provider(ColorProvider):
+    """
+    Implement color provider for ``vi_VN`` locale.
+
+    #Sources: https://vi.wikipedia.org/wiki/Danh_s%C3%A1ch_m%C3%A0u
+    """
+
+    all_colors = OrderedDict(
+        (
+            ("Trắng Antique", "#FAEBD7"),
+            ("Aquamarine", "#7FFFD4"),
+            ("Azure", "#F0FFFF"),
+            ("Beige", "#F5F5DC"),
+            ("Đen", "#000000"),
+            ("Xanh dương", "#0000FF"),
+            ("Xanh tím", "#8A2BE2"),
+            ("Nâu", "#A52A2A"),
+            ("Sô cô la", "#D2691E"),
+            ("San hô", "#FF7F50"),
+            ("Xanh hải quân", "#6495ED"),
+            ("Hồng đào", "#DC143C"),
+            ("Xanh đậm", "#00008B"),
+            ("Xanh biển đậm", "#008B8B"),
+            ("Xám đậm", "#A9A9A9"),
+            ("Xanh lá đậm", "#006400"),
+            ("Rêu đậm", "#BDB76B"),
+            ("Cam đậm", "#FF8C00"),
+            ("Đỏ đậm", "#8B0000"),
+            ("Xanh ngọc đậm", "#00CED1"),
+            ("Tím đậm", "#9400D3"),
+            ("Hồng đậm", "#FF1493"),
+            ("Xám xỉn", "#696969"),
+            ("Hồng fuchsia", "#FF00FF"),
+            ("Vàng", "#FFD700"),
+            ("Xám", "#808080"),
+            ("Xanh lá cây", "#008000"),
+            ("Xanh lá cây nhạt", "#ADFF2F"),
+            ("Hồng sáng", "#FF69B4"),
+            ("Indigo", "#4B0082"),
+            ("Ngà voi", "#FFFFF0"),
+            ("Rêu", "#F0E68C"),
+            ("Hồng lavender", "#FFF0F5"),
+            ("Xanh dương nhạt", "#ADD8E6"),
+            ("Xanh biển nhạt", "#E0FFFF"),
+            ("Xám sáng", "#D3D3D3"),
+            ("Xanh lá cây sáng", "#90EE90"),
+            ("Hồng sáng", "#FFB6C1"),
+            ("Xanh biển sáng", "#87CEFA"),
+            ("Vàng sáng", "#FFFFE0"),
+            ("Hạt Dẻ", "#800000"),
+            ("Cam", "#FFA500"),
+            ("Cam đỏ", "#FF4500"),
+            ("Xanh lá cây nhạt", "#98FB98"),
+            ("Xanh biển nhạt", "#AFEEEE"),
+            ("Hồng", "#FFC0CB"),
+            ("Tím", "#DDA0DD"),
+            ("Tím đậm", "#800080"),
+            ("Đỏ", "#FF0000"),
+            ("Xanh biển xanh", "#2E8B57"),
+            ("Bạc", "#C0C0C0"),
+            ("Xanh lục bảo", "#40E0D0"),
+            ("Tím violet", "#EE82EE"),
+            ("Trắng", "#FFFFFF"),
+            ("Vàng", "#FFFF00"),
+            ("Xanh lá cây vàng", "#9ACD32"),
+        )
+    )
+
+    safe_colors = (
+        "đen",
+        "đỏ rượu",
+        "xanh lá cây",
+        "rêu",
+        "tím",
+        "xanh biển",
+        "xanh chanh",
+        "xanh dương",
+        "bạc",
+        "xám",
+        "vàng",
+        "hồng fuchsia",
+        "trắng",
+    )
diff --git a/faker/providers/company/vi_VN/__init__.py b/faker/providers/company/vi_VN/__init__.py
new file mode 100644
index 00000000..480b74d2
--- /dev/null
+++ b/faker/providers/company/vi_VN/__init__.py
@@ -0,0 +1,24 @@
+from .. import Provider as CompanyProvider
+
+
+class Provider(CompanyProvider):
+    # Source: https://vi.wikipedia.org/wiki/Danh_s%C3%A1ch_c%C3%B4ng_ty_Vi%E1%BB%87t_Nam
+    formats = (
+        "{{last_name}} {{company_suffix}}",
+        "{{last_name}} {{last_name}} {{company_suffix}}",
+        "{{last_name}} và {{last_name}} {{company_suffix}}",
+        "{{last_name}} và đối tác {{company_suffix}}",
+    )
+
+    company_suffixes = (
+        "Công ty TNHH",
+        "Công ty Cổ phần",
+        "Doanh nghiệp tư nhân",
+        "Công ty TNHH MTV",
+        "Công ty Hợp danh",
+        "Công ty Trách nhiệm hữu hạn",
+        "Tập Đoàn",
+    )
+
+    def company_suffix(self) -> str:
+        return self.random_element(self.company_suffixes)
diff --git a/faker/providers/currency/vi_VN/__init__.py b/faker/providers/currency/vi_VN/__init__.py
new file mode 100644
index 00000000..4ad15819
--- /dev/null
+++ b/faker/providers/currency/vi_VN/__init__.py
@@ -0,0 +1,9 @@
+from .. import Provider as CurrencyProvider
+
+
+class Provider(CurrencyProvider):
+    # Source: https://vi.wikipedia.org/wiki/%C4%90%E1%BB%93ng_(%C4%91%C6%A1n_v%E1%BB%8B_ti%E1%BB%81n_t%E1%BB%87)#Ti%E1%BB%81n_gi%E1%BA%A5y_-_Ti%E1%BB%81n_polymer  # NOQA
+    price_formats = ["#.##", "%#.##", "%##.##", "%,###.##", "%#,###.##"]
+
+    def pricetag(self) -> str:
+        return "₫" + self.numerify(self.random_element(self.price_formats))
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index 788d761a..0c67fb13 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -1426,7 +1426,7 @@ class Provider(BaseProvider):
         ),
         Country(
             timezones=[
-                "Europe/Kiev",
+                "Europe/Kyiv",
                 "Europe/Uzhgorod",
                 "Europe/Zaporozhye",
                 "Europe/Simferopol",
@@ -1435,7 +1435,7 @@ class Provider(BaseProvider):
             alpha_3_code="UKR",
             continent="Europe",
             name="Ukraine",
-            capital="Kiev",
+            capital="Kyiv",
         ),
         Country(
             timezones=["Africa/Kampala"],
diff --git a/faker/providers/date_time/vi_VN/__init__.py b/faker/providers/date_time/vi_VN/__init__.py
new file mode 100644
index 00000000..c90fa160
--- /dev/null
+++ b/faker/providers/date_time/vi_VN/__init__.py
@@ -0,0 +1,37 @@
+from .. import Provider as DateTimeProvider
+
+
+class Provider(DateTimeProvider):
+    # Source: https://vi.wikipedia.org/wiki/%C4%90%E1%BB%8Bnh_d%E1%BA%A1ng_ng%C3%A0y_v%C3%A0_gi%E1%BB%9D_%E1%BB%9F_Vi%E1%BB%87t_Nam  # NOQA
+    DAY_NAMES = {
+        "0": "Chủ Nhật",
+        "1": "Thứ Hai",
+        "2": "Thứ Ba",
+        "3": "Thứ Tư",
+        "4": "Thứ Năm",
+        "5": "Thứ Sáu",
+        "6": "Thứ Bảy",
+    }
+
+    MONTH_NAMES = {
+        "01": "Tháng Một",
+        "02": "Tháng Hai",
+        "03": "Tháng Ba",
+        "04": "Tháng Tư",
+        "05": "Tháng Năm",
+        "06": "Tháng Sáu",
+        "07": "Tháng Bảy",
+        "08": "Tháng Tám",
+        "09": "Tháng Chín",
+        "10": "Tháng Mười",
+        "11": "Tháng Mười Một",
+        "12": "Tháng Mười Hai",
+    }
+
+    def day_of_week(self):
+        day = self.date("%w")
+        return self.DAY_NAMES[day]
+
+    def month_name(self):
+        month = self.month()
+        return self.MONTH_NAMES[month]
diff --git a/faker/providers/isbn/isbn.py b/faker/providers/isbn/isbn.py
index b712a83c..e567864d 100644
--- a/faker/providers/isbn/isbn.py
+++ b/faker/providers/isbn/isbn.py
@@ -2,6 +2,7 @@
 This module is responsible for generating the check digit and formatting
 ISBN numbers.
 """
+
 from typing import Any, Optional
 
 
diff --git a/faker/providers/job/vi_VN/__init__.py b/faker/providers/job/vi_VN/__init__.py
new file mode 100644
index 00000000..0b4a749b
--- /dev/null
+++ b/faker/providers/job/vi_VN/__init__.py
@@ -0,0 +1,75 @@
+from .. import Provider as JobProvider
+
+
+class Provider(JobProvider):
+    """Translated from Super class"""
+
+    jobs = (
+        # Information technology field
+        "Lập trình viên",
+        "Kỹ sư phần mềm",
+        "Kiến trúc sư phần mềm",
+        "Nhà phân tích dữ liệu",
+        "Chuyên viên bảo mật",
+        "Tester",
+        "DevOps Engineer",
+        "Project Manager",
+        "UX/UI Designer",
+        "Digital Marketer",
+        "Thực Tập",
+        # Finance - banking sector
+        "Nhân viên ngân hàng",
+        "Chuyên viên tín dụng",
+        "Kế toán",
+        "Kiểm toán",
+        "Nhà tư vấn tài chính",
+        "Chuyên viên phân tích thị trường",
+        # Business areas
+        "Giám đốc kinh doanh",
+        "Trưởng phòng kinh doanh",
+        "Nhân viên kinh doanh",
+        "Marketing Manager",
+        "Sales Representative",
+        "Chuyên viên bán hàng trực tuyến",
+        # Education Department
+        "Giáo viên",
+        "Giảng viên",
+        "Chuyên viên tư vấn tuyển sinh",
+        "Thực tập sinh giáo dục",
+        # Medical
+        "Bác sĩ",
+        "Y tá",
+        "Dược sĩ",
+        "Điều Dưỡng",
+        # Building sector
+        "Kỹ sư xây dựng",
+        "Kiến trúc sư",
+        "Thợ xây",
+        "Kỹ sư giám sát",
+        # Service sector
+        "Nhân viên khách sạn",
+        "Nhân viên nhà hàng",
+        "Tư vấn khách hàng",
+        "Nhân viên lễ tân",
+        # Manufacturing sector
+        "Công nhân sản xuất",
+        "Kỹ sư sản xuất",
+        "Quản lý sản xuất",
+        # Agriculture sector
+        "Nông dân",
+        "Kỹ sư nông nghiệp",
+        # Law field
+        "Luật sư",
+        "Thư ký pháp lý",
+        # Other areas
+        "Nhà báo",
+        "Biên dịch viên",
+        "Nghệ sĩ",
+        "Nhà thiết kế đồ họa",
+        "Nhân viên hành chính",
+        "Chuyên viên nhân sự",
+        "Nhân Viên Bán Hàng",
+    )
+
+    def job(self) -> str:
+        return self.random_element(self.jobs)
diff --git a/faker/providers/lorem/__init__.py b/faker/providers/lorem/__init__.py
index 0899f58d..b8ccbcde 100644
--- a/faker/providers/lorem/__init__.py
+++ b/faker/providers/lorem/__init__.py
@@ -66,6 +66,7 @@ class Provider(BaseProvider):
         self,
         nb: int = 3,
         ext_word_list: Optional[List[str]] = None,
+        part_of_speech: Optional[str] = None,
         unique: bool = False,
     ) -> List[str]:
         """Generate a tuple of words.
@@ -89,10 +90,7 @@ class Provider(BaseProvider):
         :sample: nb=4, ext_word_list=['abc', 'def', 'ghi', 'jkl'], unique=True
         """
 
-        if ext_word_list is None:
-            word_list = self.get_words_list()
-        else:
-            word_list = ext_word_list
+        word_list = self.get_words_list(part_of_speech=part_of_speech, ext_word_list=ext_word_list)
 
         if unique:
             unique_samples = cast(List[str], self.random_sample(word_list, length=nb))
diff --git a/faker/providers/lorem/vi_VN/__init__.py b/faker/providers/lorem/vi_VN/__init__.py
new file mode 100644
index 00000000..a4aff13c
--- /dev/null
+++ b/faker/providers/lorem/vi_VN/__init__.py
@@ -0,0 +1,193 @@
+from typing import Dict
+
+from .. import Provider as LoremProvider
+
+
+class Provider(LoremProvider):
+    """Implement lorem provider for ``vi_VN`` locale.
+
+    Word list is based on common Vietnamese words and phrases.
+    # Source : https://vi.wikipedia.org/wiki/Ng%E1%BB%AF_ph%C3%A1p_ti%E1%BA%BFng_Vi%E1%BB%87t
+    """
+
+    word_list = (
+        "cái",
+        "đó",
+        "là",
+        "và",
+        "có",
+        "như",
+        "một",
+        "để",
+        "cũng",
+        "với",
+        "cho",
+        "trong",
+        "tôi",
+        "của",
+        "người",
+        "không",
+        "sẽ",
+        "đã",
+        "này",
+        "theo",
+        "làm",
+        "nơi",
+        "đang",
+        "nếu",
+        "bạn",
+        "được",
+        "khi",
+        "thì",
+        "về",
+        "mà",
+        "cũng",
+        "nào",
+        "của",
+        "nhưng",
+        "vì",
+        "rất",
+        "tại",
+        "tại",
+        "thế",
+        "để",
+        "giữa",
+        "với",
+        "cách",
+        "từ",
+        "lớn",
+        "có",
+        "vài",
+        "hơn",
+        "vẫn",
+        "dưới",
+        "đi",
+        "đến",
+        "vậy",
+        "điều",
+        "hoặc",
+        "chỉ",
+        "hơn",
+        "khiến",
+        "giống",
+        "sau",
+        "trong",
+        "đúng",
+        "của",
+        "mỗi",
+        "như",
+        "bên",
+        "để",
+        "chưa",
+        "như",
+        "thay",
+        "như",
+        "các",
+        "tự",
+        "số",
+        "từng",
+        "nhiều",
+        "gần",
+        "từ",
+    )
+
+    parts_of_speech: Dict[str, tuple] = {
+        "verb": (
+            "là",
+            "có",
+            "làm",
+            "đi",
+            "nói",
+            "thấy",
+            "nghe",
+            "đọc",
+            "viết",
+            "muốn",
+            "đi",
+            "ngồi",
+            "uống",
+            "ăn",
+            "học",
+            "chơi",
+            "nhìn",
+            "được",
+            "tìm",
+            "đặt",
+            "giúp",
+            "hỏi",
+            "giải",
+            "mua",
+            "bán",
+            "nói",
+        ),
+        "noun": (
+            "người",
+            "sách",
+            "máy",
+            "bàn",
+            "ghế",
+            "cửa",
+            "nhà",
+            "bút",
+            "xe",
+            "điện thoại",
+            "bánh",
+            "cà phê",
+            "nước",
+            "trường",
+            "chúng tôi",
+            "học sinh",
+            "giáo viên",
+            "bố",
+            "mẹ",
+            "em",
+            "anh",
+            "chị",
+        ),
+        "adverb": (
+            "thực sự",
+            "rất",
+            "nhanh",
+            "chậm",
+            "tốt",
+            "xấu",
+            "đúng",
+            "sai",
+            "vui",
+            "buồn",
+            "mới",
+            "cũ",
+            "dễ",
+            "khó",
+            "gần",
+            "xa",
+            "hơn",
+            "vẫn",
+            "đã",
+            "mới",
+        ),
+        "adjective": (
+            "đẹp",
+            "xấu",
+            "tốt",
+            "xấu",
+            "to",
+            "nhỏ",
+            "ngọt",
+            "chua",
+            "mặn",
+            "nhanh",
+            "chậm",
+            "đầu",
+            "cuối",
+            "mới",
+            "cũ",
+            "dễ",
+            "khó",
+            "hơi",
+            "vui",
+            "buồn",
+            "mạnh",
+            "yếu",
+        ),
+    }
diff --git a/faker/providers/person/en_IE/__init__.py b/faker/providers/person/en_IE/__init__.py
index a2aeb7f4..a5bf713c 100644
--- a/faker/providers/person/en_IE/__init__.py
+++ b/faker/providers/person/en_IE/__init__.py
@@ -6,6 +6,7 @@ first names from Northern Ireland Statistics and Research Agency
  https://www.nisra.gov.uk/publications/baby-names-2016
 1996 series
 """
+
 from .. import Provider as PersonProvider
 
 
diff --git a/faker/providers/person/en_IN/__init__.py b/faker/providers/person/en_IN/__init__.py
index 727da51b..771405b0 100644
--- a/faker/providers/person/en_IN/__init__.py
+++ b/faker/providers/person/en_IN/__init__.py
@@ -2,225 +2,554 @@ from .. import Provider as PersonProvider
 
 
 class Provider(PersonProvider):
-    formats = ("{{first_name}} {{last_name}}",)
 
-    # First names are from
-    #   https://www.babycenter.in/a25010193/modern-indian-baby-names
-    #   https://en.wikipedia.org/wiki/Category:Male_actors_in_Malayalam_cinema (not used exhaustively)
-    #   https://en.wikipedia.org/wiki/List_of_Tamil_film_actors (not used exhaustively)
-    # Last names are from https://www.familyeducation.com/baby-names/browse-origin/surname/indian
+    formats_male = ("{{first_name_male}} {{last_name}}",)
+    formats_female = ("{{first_name_female}} {{last_name}}",)
+    formats = ("{{first_name}} {{last_name}}",)
 
-    first_names = (
+    # https://www.in.pampers.com/pregnancy/baby-names/article/indian-baby-boys-names
+    first_names_male = (
+        "Aadi",
         "Aarav",
+        "Aarnav",
         "Aarush",
         "Aayush",
-        "Abram",
+        "Abdul",
+        "Abeer",
+        "Abhimanyu",
+        "Abhiram",
+        "Aditya",
+        "Advaith",
+        "Advay",
         "Advik",
-        "Akarsh",
+        "Agastya",
+        "Akshay",
+        "Alexander",
+        "Amol",
         "Anay",
-        "Aniruddh",
-        "Arhaan",
-        "Armaan",
-        "Arnav",
+        "Andrew",
+        "Anirudh",
+        "Anmol",
+        "Ansh",
+        "Anthony",
+        "Arin",
+        "Arjun",
+        "Aryan",
+        "Atharv",
+        "Avi",
+        "Ayaan",
+        "Ayush",
+        "Ayushman",
+        "Azaan",
         "Azad",
-        "Badal",
-        "Baiju",
-        "Bhavin",
-        "Biju",
-        "Chirag",
-        "Darshit",
+        "Bachittar",
+        "Bahadurjit",
+        "Bakhshi",
+        "Balendra",
+        "Balhaar",
+        "Baljiwan",
+        "Balvan",
+        "Balveer",
+        "Banjeet",
+        "Benjamin",
+        "Brijesh",
+        "Caleb",
+        "Chaitanya",
+        "Chakradev",
+        "Chakradhar",
+        "Champak",
+        "Chanakya",
+        "Chandran",
+        "Chandresh",
+        "Charan",
+        "Charles",
+        "Chatresh",
+        "Chatura",
+        "Christopher",
+        "Daksh",
+        "Dakshesh",
+        "Dalbir",
+        "Daniel",
+        "Darpan",
+        "Darsh",
+        "David",
+        "Dev",
         "Devansh",
-        "Dhanuk",
-        "Dhanush",
-        "Dharmajan",
         "Dhruv",
-        "Divij",
-        "Divit",
-        "Divyansh",
-        "Ehsaan",
-        "Emir",
-        "Faiyaz",
+        "Dominic",
+        "Ekalinga",
+        "Ekansh",
+        "Ekapad",
+        "Ekaraj",
+        "Ekavir",
+        "Ekbal",
+        "Elijah",
+        "Ethan",
+        "Falan",
+        "Faqid",
+        "Faraj",
+        "Faras",
         "Farhan",
-        "Fateh",
-        "Gatik",
-        "Gokul",
-        "Hansh",
-        "Himmat",
-        "Hiran",
-        "Hridaan",
-        "Hunar",
+        "Fariq",
+        "Faris",
+        "Finn",
+        "Fitan",
+        "Fiyaz",
+        "Frado",
+        "Frederick",
+        "Gabriel",
+        "Gagan",
+        "Gaurang",
+        "Gaurav",
+        "Gautam",
+        "Gavin",
+        "George",
+        "Girik",
+        "Girindra",
+        "Girish",
+        "Gopal",
+        "Gunbir",
+        "Guneet",
+        "Hardik",
+        "Harish",
+        "Harrison",
+        "Harsh",
+        "Harshil",
+        "Hemang",
+        "Henry",
+        "Hitesh",
+        "Hredhaan",
+        "Hritik",
+        "Ikbal",
+        "Imaran",
         "Indrajit",
-        "Indrans",
-        "Indranil",
+        "Isaac",
+        "Isaiah",
         "Ishaan",
-        "Ivan",
-        "Jayan",
-        "Jayant",
-        "Jayesh",
-        "Jivin",
+        "Ishwar",
+        "Jack",
+        "Jackson",
+        "Jacob",
+        "Jagat",
+        "Jagdish",
+        "Jai",
+        "Jairaj",
+        "Jason",
+        "Jatin",
+        "Jeet",
+        "Jeremiah",
+        "Jonathan",
+        "Joshua",
         "Kabir",
-        "Kanav",
-        "Kartik",
+        "Kai",
+        "Kalpit",
+        "Karan",
+        "Kevin",
         "Kiaan",
         "Krish",
-        "Lagan",
-        "Lakshay",
+        "Krishna",
+        "Laban",
+        "Laksh",
         "Lakshit",
+        "Liam",
+        "Logan",
+        "Lohit",
+        "Lucky",
+        "Luke",
+        "Maanas",
+        "Maanav",
         "Madhav",
-        "Madhup",
-        "Mamooty",
-        "Manikya",
-        "Mehul",
-        "Miraan",
+        "Manan",
+        "Manbir",
+        "Manthan",
+        "Mason",
+        "Matthew",
+        "Max",
+        "Michael",
+        "Mitesh",
+        "Mohammed",
+        "Nachiket",
+        "Naksh",
         "Nakul",
-        "Nirvaan",
-        "Nishith",
+        "Nathan",
+        "Nathaniel",
+        "Naveen",
+        "Neel",
+        "Nicholas",
+        "Nihal",
+        "Nitesh",
+        "Noah",
         "Ojas",
+        "Oliver",
+        "Om",
+        "Omkaar",
         "Onkar",
-        "Pranay",
-        "Prerak",
-        "Priyansh",
-        "Purab",
+        "Onveer",
+        "Orinder",
+        "Oscar",
+        "Owen",
+        "Parth",
+        "Patrick",
+        "Peter",
+        "Pranav",
+        "Praneel",
+        "Pranit",
+        "Pratyush",
+        "Qabil",
+        "Qadim",
+        "Qarin",
+        "Qasim",
+        "Quincy",
+        "Rachit",
         "Raghav",
         "Ranbir",
-        "Raunak",
+        "Ranveer",
+        "Rayaan",
+        "Rehaan",
         "Reyansh",
-        "Riaan",
-        "Ritvik",
+        "Rishi",
+        "Robert",
         "Rohan",
-        "Romil",
+        "Ronith",
+        "Rudra",
+        "Rushil",
         "Ryan",
-        "Sahil",
+        "Sai",
         "Saksham",
+        "Samaksh",
         "Samar",
         "Samarth",
-        "Shaan",
-        "Shalv",
-        "Shamik",
-        "Shayak",
-        "Shlok",
-        "Shray",
-        "Stuvan",
-        "Sumer",
-        "Taimur",
-        "Taran",
+        "Samesh",
+        "Samuel",
+        "Sarthak",
+        "Sathvik",
+        "Shaurya",
+        "Shivansh",
+        "Siddharth",
+        "Simon",
+        "Tanay",
+        "Tanish",
+        "Tanveer",
+        "Tarak",
+        "Teerth",
         "Tejas",
-        "Tushar",
+        "Theodore",
+        "Thomas",
+        "Timothy",
+        "Tristan",
+        "Udant",
+        "Udarsh",
         "Umang",
-        "Uthkarsh",
-        "Vaibhav",
+        "Upkaar",
+        "Utkarsh",
+        "Vedant",
         "Veer",
-        "Vidur",
+        "Victor",
         "Vihaan",
+        "Vincent",
+        "Viraj",
         "Vivaan",
-        "Yakshit",
-        "Yuvaan",
-        "Yuvraj ",
-        "Zain",
-        "Zeeshan",
-        "Aaina",
+        "Wahab",
+        "Warinder",
+        "Warjas",
+        "Wazir",
+        "William",
+        "Wriddhish",
+        "Wridesh",
+        "Wyatt",
+        "Xavier",
+        "Yagnesh",
+        "Yash",
+        "Yatan",
+        "Yatin",
+        "Yug",
+        "Yuvraj",
+        "Zaid",
+        "Zashil",
+        "Zayan",
+        "Zayyan",
+        "Zehaan",
+    )
+
+    # https://www.pampers.com/en-us/pregnancy/baby-names/article/indian-girl-names
+    first_names_female = (
+        "Aachal",
+        "Aadhya",
+        "Aahana",
+        "Aarini",
         "Aarna",
-        "Aaryahi",
-        "Adah",
-        "Adira",
+        "Aashi",
+        "Abha",
         "Advika",
-        "Ahana ",
-        "Alia",
-        "Alisha",
-        "Amani",
-        "Amira",
-        "Anahi",
-        "Anahita",
-        "Anaya",
+        "Adweta",
+        "Adya",
+        "Aishani",
+        "Alka",
+        "Amaira",
+        "Amara",
+        "Amrita",
+        "Amruta",
+        "Anamika",
         "Anika",
+        "Anita",
+        "Anjali",
+        "Anusha",
         "Anvi",
         "Anya",
-        "Aradhya",
-        "Ayesha",
-        "Bhamini",
+        "Aradhana",
+        "Arunima",
+        "Arya",
+        "Ati",
+        "Avni",
+        "Baghyawati",
+        "Barkha",
+        "Bhanumati",
+        "Bhavani",
+        "Bhavika",
+        "Bhavini",
+        "Bhavna",
+        "Bhavya",
+        "Bimala",
+        "Bina",
+        "Bishakha",
+        "Brinda",
+        "Chaaya",
+        "Chaitaly",
+        "Chakrika",
+        "Chaman",
+        "Chameli",
+        "Chanchal",
+        "Chandani",
+        "Charita",
         "Charvi",
+        "Chasmum",
+        "Chavvi",
+        "Daksha",
+        "Dalaja",
         "Damini",
-        "Dishani",
+        "Damyanti",
+        "Darika",
+        "Dayamai",
+        "Dayita",
+        "Deepa",
+        "Devika",
+        "Dhriti",
+        "Dipta",
+        "Divya",
         "Diya",
-        "Drishya",
-        "Ela",
-        "Elakshi",
-        "Eshani",
-        "Eva",
-        "Hazel",
-        "Heer",
-        "Hrishita",
-        "Inaaya ",
+        "Edhitha",
+        "Eesha",
+        "Eiravati",
+        "Ekaja",
+        "Ekani",
+        "Ekanta",
+        "Ekantika",
+        "Ekiya",
+        "Ekta",
+        "Eshana",
+        "Eta",
+        "Falak",
+        "Falguni",
+        "Forum",
+        "Ganga",
+        "Garima",
+        "Gaurangi",
+        "Gauri",
+        "Gaurika",
+        "Gautami",
+        "Gayathri",
+        "Geetika",
+        "Hamsini",
+        "Harinakshi",
+        "Harini",
+        "Harita",
+        "Hema",
+        "Hemal",
+        "Hemangini",
+        "Hemani",
+        "Hiral",
+        "Idika",
+        "Ijaya",
+        "Ikshita",
+        "Inaya",
+        "Indali",
+        "Indira",
         "Ira",
+        "Irya",
+        "Isha",
+        "Ishani",
+        "Ishanvi",
         "Ishita",
-        "Ivana",
-        "Jhanvi",
-        "Jivika",
-        "Jiya",
-        "Kaira",
+        "Jagrati",
+        "Jagvi",
+        "Jalsa",
+        "Janaki",
+        "Janani",
+        "Januja",
+        "Janya",
+        "Jasmit",
+        "Jeevika",
+        "Jhalak",
+        "Jyoti",
+        "Kala",
+        "Kamala",
+        "Kamya",
+        "Kashish",
         "Kashvi",
         "Kavya",
         "Keya",
-        "Khushi",
-        "Kiara",
-        "Kimaya",
-        "Kismat",
+        "Krisha",
+        "Krishna",
+        "Kritika",
+        "Ladli",
+        "Lajita",
+        "Lakshmi",
         "Lavanya",
+        "Leela",
+        "Leena",
+        "Lekha",
+        "Libni",
+        "Lila",
+        "Lipika",
+        "Lopa",
+        "Madhavi",
         "Mahika",
-        "Manjari",
-        "Mannat",
-        "Miraya",
-        "Misha",
-        "Mishti",
-        "Mohanlal",
-        "Myra",
-        "Navya",
-        "Nayantara",
-        "Neelofar",
-        "Nehmat",
-        "Neysa",
-        "Nirvi",
+        "Manya",
+        "Maya",
+        "Meera",
+        "Megha",
+        "Meghana",
+        "Mekhala",
+        "Mitali",
+        "Mohini",
+        "Mugdha",
+        "Nandini",
+        "Neelima",
+        "Neha",
+        "Netra",
+        "Nidhi",
+        "Nidra",
+        "Niharika",
+        "Nikita",
+        "Nilima",
+        "Nimrat",
+        "Nirja",
+        "Nisha",
         "Nitara",
-        "Nitya",
-        "Oorja",
-        "Pari",
-        "Parinaaz",
-        "Pihu",
-        "Piya",
+        "Odika",
+        "Oeshi",
+        "Ojasvi",
+        "Omaja",
+        "Omisha",
+        "Omya",
+        "Oni",
+        "Osha",
+        "Oviya",
+        "Pahal",
+        "Pallavi",
+        "Panini",
+        "Pavani",
+        "Pooja",
         "Prisha",
-        "Rania",
-        "Rasha",
-        "Rati",
-        "Renee",
-        "Rhea",
+        "Priya",
+        "Pushti",
+        "Qushi",
+        "Raagini",
+        "Rachana",
+        "Rachita",
+        "Radha",
+        "Radhika",
+        "Rajata",
+        "Rajeshri",
+        "Raksha",
+        "Reva",
+        "Ria",
+        "Ridhi",
         "Riya",
         "Saanvi",
-        "Saira",
-        "Samaira",
-        "Samiha",
-        "Sana",
+        "Sachi",
+        "Sai",
+        "Sanaya",
+        "Sanya",
         "Sara",
-        "Seher",
-        "Shanaya",
+        "Saumya",
+        "Shivani",
+        "Shravya",
         "Siya",
-        "Suhana",
-        "Tanya",
+        "Sneha",
+        "Sudiksha",
+        "Suhani",
+        "Tamanna",
+        "Tanmayi",
+        "Tanvi",
         "Tara",
-        "Tarini",
-        "Tiya",
-        "Trisha",
+        "Tripti",
+        "Triveni",
+        "Triya",
+        "Turvi",
+        "Ubika",
+        "Ucchal",
+        "Udyati",
+        "Unnati",
+        "Unni",
+        "Upadhriti",
+        "Upasna",
+        "Upma",
+        "Urishilla",
+        "Urmi",
+        "Urvashi",
         "Urvi",
+        "Vaishnavi",
+        "Vamakshi",
+        "Vansha",
         "Vanya",
-        "Vardaniya",
+        "Varenya",
+        "Varsha",
+        "Vasana",
+        "Vasatika",
+        "Vasudha",
+        "Veda",
+        "Vedhika",
         "Vedika",
-        "Vritika",
+        "Vidhi",
+        "Vinaya",
+        "Vrinda",
+        "Vrishti",
+        "Vritti",
+        "Vyanjana",
+        "Waida",
+        "Wakeeta",
+        "Warda",
+        "Warhi",
+        "Watika",
+        "Widisha",
+        "Wishi",
+        "Xalak",
+        "Xiti",
+        "Yachana",
+        "Yadavi",
+        "Yahvi",
+        "Yamini",
+        "Yashasvi",
+        "Yashawini",
+        "Yashica",
+        "Yashoda",
+        "Yashodhara",
         "Yashvi",
-        "Yasmin",
-        "Zaina",
-        "Zara",
-        "Zoya",
+        "Yasti",
+        "Yauvani",
+        "Yochana",
+        "Yoshita",
+        "Yutika",
+        "Zaitra",
+        "Zansi",
+        "Zarna",
+        "Zilmil",
+        "Zinal",
     )
 
+    first_names = first_names_male + first_names_female
+
     last_names = (
         "Acharya",
         "Agarwal",
@@ -522,6 +851,96 @@ class Provider(PersonProvider):
         "Mannan",
         "Manne",
         "Master",
+        "Memon",
+        "Menon",
+        "Merchant",
+        "Minhas",
+        "Mishra",
+        "Misra",
+        "Mistry",
+        "Mital",
+        "Mitra",
+        "Mittal",
+        "Mitter",
+        "Modi",
+        "Mody",
+        "Mohan",
+        "Mohanty",
+        "Morar",
+        "More",
+        "Mukherjee",
+        "Mukhopadhyay",
+        "Muni",
+        "Munshi",
+        "Murthy",
+        "Murty",
+        "Mutti",
+        "Nadig",
+        "Nadkarni",
+        "Nagar",
+        "Nagarajan",
+        "Nagi",
+        "Nagy",
+        "Naidu",
+        "Naik",
+        "Nair",
+        "Nanda",
+        "Narain",
+        "Narang",
+        "Narasimhan",
+        "Narayan",
+        "Narayanan",
+        "Narula",
+        "Natarajan",
+        "Nath",
+        "Natt",
+        "Nayak",
+        "Nayar",
+        "Nazareth",
+        "Nigam",
+        "Nori",
+        "Oak",
+        "Om",
+        "Oommen",
+        "Oza",
+        "Padmanabhan",
+        "Pai",
+        "Pal",
+        "Palan",
+        "Pall",
+        "Palla",
+        "Palla",
+        "Panchal",
+        "Pandey",
+        "Pandit",
+        "Pandya",
+        "Pant",
+        "Parekh",
+        "Parikh",
+        "Parmar",
+        "Parmer",
+        "Parsa",
+        "Patel",
+        "Pathak",
+        "Patil",
+        "Patla",
+        "Patla",
+        "Pau",
+        "Peri",
+        "Pillai",
+        "Pillay",
+        "Pingle",
+        "Prabhakar",
+        "Prabhu",
+        "Pradhan",
+        "Prakash",
+        "Prasad",
+        "Prashad",
+        "Puri",
+        "Purohit",
+        "Radhakrishnan",
+        "Raghavan",
+        "Rai",
         "Raj",
         "Raja",
         "Rajagopal",
diff --git a/faker/providers/person/en_PK/__init__.py b/faker/providers/person/en_PK/__init__.py
new file mode 100644
index 00000000..38ee0a08
--- /dev/null
+++ b/faker/providers/person/en_PK/__init__.py
@@ -0,0 +1,1024 @@
+from .. import Provider as PersonProvider
+
+
+class Provider(PersonProvider):
+    formats = ("{{first_name}} {{last_name}}",)
+
+    # First names are from
+    #   https://mummyname.net/pakistani-boy-names/
+    # Last names are from https://mummyname.net/pakistani-boy-names/
+
+    first_names = (
+        "Ali",
+        "Arham",
+        "Aryan",
+        "Ayaan",
+        "Faizan",
+        "Hamza",
+        "Huzaifa",
+        "Rayan",
+        "Rohaan",
+        "Atfat",
+        "Atheel",
+        "Attaf",
+        "Auraq",
+        "Awadil",
+        "Awamil",
+        "Awamiri",
+        "Awan",
+        "Awani",
+        "Awj",
+        "Awlya",
+        "Awmar",
+        "Awrad",
+        "Ayamin",
+        "Aysar",
+        "Ayyubi",
+        "Azban",
+        "Azeeb",
+        "Baashir",
+        "Badawi",
+        "Bairbel",
+        "Bambad",
+        "Berezat",
+        "Birousk",
+        "Bizhan",
+        "Buraid",
+        "Chamali",
+        "Changaz",
+        "Charlesh",
+        "Chashida",
+        "Chawish",
+        "Cheragh",
+        "Darain",
+        "Dastageer",
+        "Dayyaan",
+        "Durab",
+        "Ejlaal",
+        "Elaf",
+        "Esfandyar",
+        "Etizaaz",
+        "Fahmi",
+        "Fazli",
+        "Fidvi",
+        "Ghazanfer",
+        "Gulfaam",
+        "Guney",
+        "Harnail",
+        "Hazeem",
+        "Kachela",
+        "Khaan",
+        "Mizhir",
+        "Mourib",
+        "Muhallil",
+        "Muhazzim",
+        "Muzdahir",
+        "Muzhir",
+        "Rusul",
+        "Ruwaihim",
+        "Samama",
+        "Souma",
+        "Tadeen",
+        "Tafazal",
+        "Tahmaseb",
+        "Tahoor",
+        "Taial",
+        "Taisir",
+        "Tarfaan",
+        "Tawkeel",
+        "Tirdad",
+        "Tishk",
+        "Urrab",
+        "Vahar",
+        "Xobeen",
+        "Yadid",
+        "Yafir",
+        "Yamar",
+        "Yashem",
+        "Yazan",
+        "Yazeed",
+        "Yeraz",
+        "Yergha",
+        "Yesoob",
+        "Yureed",
+        "Zabir",
+        "Zahaar",
+        "Zahri",
+        "Zahrun",
+        "Zahur",
+        "Zarar",
+        "Zauqi",
+        "Zaweel",
+        "Zayan",
+        "Zayyir",
+        "Zerdad",
+        "Zewad",
+        "Zimran",
+        "Zuwayhir",
+        "Name",
+        "Adil",
+        "Aaaqil",
+        "Aaban",
+        "Aabid",
+        "Aabid",
+        "Aadam",
+        "Aadil",
+        "Aadil",
+        "Aadil",
+        "Aafiya",
+        "Aahil",
+        "Aalam",
+        "Aalam",
+        "Aalee",
+        "Aalim",
+        "Aamil",
+        "Aamir",
+        "Aamir",
+        "Aamir",
+        "Aamirah",
+        "Aaqil",
+        "Aarif",
+        "Aarif",
+        "Aarif",
+        "Aariz",
+        "Aaryan",
+        "Aashif",
+        "Aashir",
+        "Aasif",
+        "Aasif",
+        "Aasim",
+        "Aasim",
+        "Aasim",
+        "Aatif",
+        "Aatiq",
+        "Aaus",
+        "Aayan",
+        "Aazim",
+        "Abaan",
+        "Name",
+        "Baahir",
+        "Baaizeed",
+        "Baaqee",
+        "Baaqir",
+        "Baaree",
+        "Baasim",
+        "Baasit",
+        "Babar",
+        "Baber",
+        "Badr",
+        "Badr Udeen",
+        "Baha",
+        "Baha Udeen",
+        "Bahaa",
+        "Bahiy Udeen",
+        "Baleegh",
+        "Baqar",
+        "Baqir",
+        "Barr",
+        "Barraq",
+        "Basaam",
+        "Baseer",
+        "Basel",
+        "Basem",
+        "Bashaar",
+        "Bashaarat",
+        "Bashar",
+        "Basharat",
+        "Basheer",
+        "Basheerah",
+        "Basil",
+        "Basim",
+        "Basir",
+        "Bassam",
+        "Batal",
+        "Batool",
+        "Bazam",
+        "Bilaal",
+        "Bilal",
+        "Name",
+        "Dawud",
+        "Daamin",
+        "Daanish",
+        "Daanyaal",
+        "Daawood",
+        "Dabbah",
+        "Dabir",
+        "Daghfal",
+        "Daiyaan",
+        "Dakhil",
+        "Dameer",
+        "Damurah",
+        "Daniel",
+        "Danish",
+        "Name",
+        "Eesaa",
+        "Ehan",
+        "Ehsaas",
+        "Ehsan",
+        "Eijaz",
+        "Ejaz",
+        "El-Amin",
+        "Emran",
+        "Eshan",
+        "Name",
+        "Ghaalib",
+        "Ghaazi",
+        "Ghaffaar",
+        "Ghafoor",
+        "Ghaith",
+        "Ghalib",
+        "Ghanee",
+        "Ghanem",
+        "Ghannam",
+        "Ghasaan",
+        "Ghauth",
+        "Ghauth",
+        "Ghawth",
+        "Ghayoor",
+        "Ghazalan",
+        "Ghazanfar",
+        "Ghazawan",
+        "Ghazi",
+        "Ghazzal",
+        "Ghiyaath",
+        "Ghiyath",
+        "Ghufran",
+        "Ghulaam",
+        "Ghulam",
+        "Ghunayn",
+        "Ghusharib",
+        "Ghusun",
+        "Ghutayf",
+        "Gohar",
+        "Gulab",
+        "Gulfam",
+        "Gulshan",
+        "Gulzar",
+        "Name",
+        "Izaaz",
+        "Ibaad",
+        "Ibn",
+        "Ibraaheem",
+        "Ibraheem",
+        "Ibrahim",
+        "Idrees",
+        "Idrees",
+        "Idris",
+        "Iesa",
+        "Iftikhaar",
+        "Iftikhar",
+        "Ihab",
+        "Ihsaan",
+        "Ihsaan",
+        "Ihsan",
+        "Ihtesham",
+        "Ihtiram",
+        "Ihtishaam",
+        "Ihtsham",
+        "Ijli",
+        "Ikhlaas",
+        "Ikraam",
+        "Ikramah",
+        "Ikrimah",
+        "Ikrimah",
+        "Ilan",
+        "Name",
+        "Jafar",
+        "Jaabir",
+        "Jaabir",
+        "Jaafar",
+        "Jaan",
+        "Jabbaar",
+        "Jabir",
+        "Jabr",
+        "Jad",
+        "Jafar",
+        "Jaffer",
+        "Jahangir",
+        "Jahanzeb",
+        "Jahdami",
+        "Jahdari",
+        "Jahiz",
+        "Jahm",
+        "Jalaal",
+        "Jalaal",
+        "Jalal",
+        "Jalees",
+        "Jalil",
+        "Jamaal",
+        "Jamaal",
+        "Jamaal Udeen",
+        "Jamal",
+        "Jameel",
+        "Jameel",
+        "Name",
+        "Kaamil",
+        "Kaamil",
+        "Kaamil",
+        "Kaashif",
+        "Kaazim",
+        "Kabeer",
+        "Kabeer",
+        "Kafeel",
+        "Kaiser",
+        "Kajji",
+        "Kalbi",
+        "Kaleem",
+        "Kaleem",
+        "Kaleema",
+        "Kamal",
+        "Kamal",
+        "Kamil",
+        "Kamran",
+        "Karaamat",
+        "Karam",
+        "Kareem",
+        "Kareem",
+        "Karim",
+        "Kasam",
+        "Kashan",
+        "Kashif",
+        "Kasim",
+        "Kauthar",
+        "Kawkab",
+        "Kawthar",
+        "Kaysan",
+        "Kazi",
+        "Kazim",
+        "Keyaan",
+        "Khaalid",
+        "Name",
+        "Laeeq",
+        "Labeeb",
+        "Labeeb",
+        "Labib",
+        "Lahiah",
+        "Laiq",
+        "Laith",
+        "Lajlaj",
+        "Laqeet",
+        "Lateef",
+        "Lateef",
+        "Latif",
+        "Layth",
+        "Liban",
+        "Limazah",
+        "Liyaaqat",
+        "Liyaqat",
+        "Loot",
+        "Luay",
+        "Luqmaan",
+        "Luqmaan",
+        "Luqman",
+        "Lut",
+        "Lutf",
+        "Lutf",
+        "Lutfi",
+        "Lutfi",
+        "Name",
+        "Maawiya",
+        "Mad",
+        "Mamun",
+        "Man",
+        "Man",
+        "Maroof",
+        "Maahir",
+        "Maajid",
+        "Maalik",
+        "Maaz",
+        "Maazin",
+        "Mabad",
+        "Madani",
+        "Madiyan",
+        "Madyan",
+        "Mahad",
+        "Mahaz",
+        "Mahbeer",
+        "Mahboob",
+        "Mahbub",
+        "Mahdee",
+        "Mahdi",
+        "Mahdy",
+        "Maheen",
+        "Maher",
+        "Mahfooz",
+        "Mahfuj",
+        "Mahfuz",
+        "Mahja",
+        "Mahmood",
+        "Mahmoud",
+        "Mahmud",
+        "Majd",
+        "Majd",
+        "Majd Udeen",
+        "Majdi",
+        "Majdy",
+        "Majeed",
+        "Makeen",
+        "Name",
+        "Nail",
+        "Naail",
+        "Naadir",
+        "Naadir",
+        "Naajy",
+        "Naasih",
+        "Naasir",
+        "Naathim",
+        "Naazhim",
+        "Nabeeh",
+        "Nabeel",
+        "Nabeel",
+        "Nabeel",
+        "Nabhan",
+        "Nabhan",
+        "Nabigh",
+        "Nabih",
+        "Nabil",
+        "Nadeem",
+        "Nadeem",
+        "Nadhir",
+        "Nadim",
+        "Nadir",
+        "Nadr",
+        "Naeem",
+        "Naeem",
+        "Nafasat",
+        "Nafees",
+        "Nafees",
+        "Nafesa",
+        "Nafis",
+        "Naib",
+        "Naim",
+        "Najair",
+        "Najam",
+        "Najam",
+        "Najeeb",
+        "Najeeb",
+        "Najeeb",
+        "Name",
+        "Obaid",
+        "Omair",
+        "Omar",
+        "Omar",
+        "Omeir",
+        "Omran",
+        "Osama",
+        "Ossama",
+        "Owais",
+        "Name",
+        "Parsa",
+        "Parvez",
+        "Pervaiz",
+        "Name",
+        "Qaadir",
+        "Qaadir",
+        "Qaasim",
+        "Qabeel",
+        "Qadar",
+        "Qadeer",
+        "Qadeer",
+        "Qadi",
+        "Qadim",
+        "Qahtan",
+        "Qaim",
+        "Qais",
+        "Qamar",
+        "Qani",
+        "Qanit",
+        "Qareeb",
+        "Qaseem",
+        "Qasid",
+        "Qasif",
+        "Qasim",
+        "Qatadah",
+        "Qatadah",
+        "Qawee",
+        "Qawee",
+        "Qay-yoom",
+        "Qays",
+        "Quadir",
+        "Qudamah",
+        "Qudamah",
+        "Quddoos",
+        "Qudoos",
+        "Qurban",
+        "Qusay",
+        "Qutaybah",
+        "Qutaybah",
+        "Qutb",
+        "Qutub",
+        "Name",
+        "Raed",
+        "Raid",
+        "Raaghib",
+        "Raahil",
+        "Raakin",
+        "Raamis",
+        "Raamiz",
+        "Raamiz",
+        "Raashid",
+        "Raashid",
+        "Raatib",
+        "Rabah",
+        "Rabah",
+        "Rabar",
+        "Rabb",
+        "Rabbaanee",
+        "Rabbani",
+        "Rabee",
+        "Rabee",
+        "Rabiah",
+        "Rabit",
+        "Radhee",
+        "Radi",
+        "Raees",
+        "Rafan",
+        "Rafay",
+        "Rafee",
+        "Rafee",
+        "Rafeek",
+        "Rafeeq",
+        "Rafi",
+        "Rafiq",
+        "Ragheb",
+        "Raghib",
+        "Rahat",
+        "Raheel",
+        "Raheem",
+        "Name",
+        "Sad",
+        "Sadan",
+        "Said",
+        "Saim",
+        "Sair",
+        "Sairah",
+        "Saood",
+        "Saabir",
+        "Saabir",
+        "Saad",
+        "Saad",
+        "Saadat",
+        "Saadiq",
+        "Saafir",
+        "Saahir",
+        "Saahir",
+        "Saaiq",
+        "Saajid",
+        "Saajid",
+        "Saal",
+        "Saalih",
+        "Saalim",
+        "Saaqib",
+        "Saariyah",
+        "Sabah",
+        "Sabahat",
+        "Sabbir",
+        "Sabeeh",
+        "Sabeeh",
+        "Sabeeh",
+        "Sabil",
+        "Sabiq",
+        "Sabir",
+        "Saboor",
+        "Sabur",
+        "Saburah",
+        "Sadan",
+        "Sadaqat",
+        "Sadeed",
+        "Name",
+        "Taahaa",
+        "Taahir",
+        "Taahir",
+        "Taaj",
+        "Taalib",
+        "Taamir",
+        "Taanish",
+        "Taariq",
+        "Taban",
+        "Tabassum",
+        "Tabassum",
+        "Tabish",
+        "Taha",
+        "Tahaw-wur",
+        "Tahawwur",
+        "Taheem",
+        "Tahir",
+        "Tahmeed",
+        "Tahmid",
+        "Tahseen",
+        "Taimur",
+        "Taj",
+        "Tajammal",
+        "Tajammul",
+        "Tajammul",
+        "Tajudinn",
+        "Talal",
+        "Talal",
+        "Talat",
+        "Talha",
+        "Talha",
+        "Talhah",
+        "Talhah",
+        "Tali",
+        "Talib",
+        "Tamam",
+        "Tamanna",
+        "Name",
+        "Ubaadah",
+        "Ubaadah",
+        "Ubaadah",
+        "Ubaadah",
+        "Ubadah",
+        "Ubadah",
+        "Ubaid",
+        "Ubaid",
+        "Ubaidah",
+        "Ubaidah",
+        "Ubay",
+        "Ubay",
+        "Ubayd",
+        "Ubayd",
+        "Ubaydullah",
+        "Ubaydullah",
+        "Uhban",
+        "Uhban",
+        "Ulfat",
+        "Ulfat",
+        "Ulfat",
+        "Umaarah",
+        "Umaarah",
+        "Umair",
+        "Umair",
+        "Umair",
+        "Umair",
+        "Umar",
+        "Umar",
+        "Umar",
+        "Umar",
+        "Umar",
+        "Name",
+        "Waail",
+        "Waail",
+        "Waahid",
+        "Waahid",
+        "Waajid",
+        "Wadee",
+        "Wadi",
+        "Wadood",
+        "Wafa",
+        "Wafeeq",
+        "Wafi",
+        "Wafiq",
+        "Wahab",
+        "Wahb",
+        "Wahban",
+        "Waheed",
+        "Waheed",
+        "Wahhaab",
+        "Wahhaaj",
+        "Name",
+        "Yaaseen",
+        "Yafi",
+        "Yaghnam",
+        "Yahya",
+        "Yahyaa",
+        "Yaman",
+        "Yaman",
+        "Yameen",
+        "Yaqeen",
+        "Yaqoot",
+        "Yaqub",
+        "Yar",
+        "Yasaar",
+        "Yaseen",
+        "Yasin",
+        "Yasir",
+        "Yasir",
+        "Yathrib",
+        "Yawar",
+        "Yawer",
+        "Name",
+        "Zaafir",
+        "Zaahid",
+        "Zaahid",
+        "Zaahir",
+        "Zaahir",
+        "Zaahir",
+        "Zaakir",
+        "Zackariya",
+        "Zaeem",
+        "Zafar",
+        "Zafar",
+        "Zafeer",
+        "Zafir",
+        "Zafrul",
+        "Zaheer",
+        "Zaheer",
+        "Zaheer",
+        "Zahi",
+        "Zahir",
+        "Zaib",
+    )
+
+    last_names = (
+        "Lajlaj"
+        "Aarif"
+        "Urrab"
+        "Tabassum"
+        "Ubadah"
+        "Daniel"
+        "Umaarah"
+        "Omair"
+        "Jalil"
+        "Aatiq"
+        "Karaamat"
+        "Lut"
+        "Karam"
+        "Aasif"
+        "Aadam"
+        "Mahbeer"
+        "Saalim"
+        "Ubayd"
+        "Naail"
+        "Mahfuz"
+        "Ghazzal"
+        "Aamir"
+        "Ubaydullah"
+        "Umaarah"
+        "Rabiah"
+        "Maawiya"
+        "Yasir"
+        "Raaghib"
+        "Daamin"
+        "Rabb"
+        "Bashaar"
+        "Taanish"
+        "Yafir"
+        "Baaree"
+        "Talib"
+        "Rafi"
+        "Luqman"
+        "Qaasim"
+        "Ubaidah"
+        "Saajid"
+        "Yaman"
+        "Ubaadah"
+        "Baaqir"
+        "Sadan"
+        "Zarar"
+        "Saafir"
+        "Zafar"
+        "Mahmoud"
+        "Zayyir"
+        "Ubay"
+        "Fidvi"
+        "Mahfuj"
+        "Awmar"
+        "Yawer"
+        "Ayaan"
+        "Taimur"
+        "Rabbani"
+        "Ayyubi"
+        "Waahid"
+        "Ijli"
+        "Baleegh"
+        "Bilaal"
+        "Radi"
+        "Ali"
+        "Tadeen"
+        "Souma"
+        "Layth"
+        "Kashif"
+        "Labeeb"
+        "Talhah"
+        "Sabir"
+        "Dabir"
+        "Yaghnam"
+        "Zackariya"
+        "Ibrahim"
+        "Rafeek"
+        "Qadeer"
+        "Luqmaan"
+        "Jahdari"
+        "Qabeel"
+        "Kaamil"
+        "Ilan"
+        "Omeir"
+        "Ubaid"
+        "Majd"
+        "Aadil"
+        "Ghafoor"
+        "Zahrun"
+        "Tabassum"
+        "Lutf"
+        "Aamir"
+        "Iftikhaar"
+        "Naeem"
+        "Ghauth"
+        "Eshan"
+        "Raid"
+        "Qasif"
+        "Ihsaan"
+        "Bambad"
+        "Aaaqil"
+        "Nabeel"
+        "Jamaal"
+        "Awj"
+        "Wahhaaj"
+        "Nabih"
+        "Jalaal"
+        "Yahyaa"
+        "Aalam"
+        "Ghayoor"
+        "Aarif"
+        "Tahir"
+        "Batal"
+        "Talha"
+        "Uhban"
+        "Aryan"
+        "Najam"
+        "Darain"
+        "Qusay"
+        "Vahar"
+        "Aabid"
+        "Ihtiram"
+        "Umar"
+        "Mahbub"
+        "Qaim"
+        "Name"
+        "Saajid"
+        "Owais"
+        "Maheen"
+        "Raashid"
+        "Limazah"
+        "Zaafir"
+        "Wadood"
+        "Aariz"
+        "Aalam"
+        "Ihab"
+        "Umair"
+        "Zahri"
+        "Aazim"
+        "Jad"
+        "Omar"
+        "Majeed"
+        "Qaseem"
+        "Rafay"
+        "Ghanee"
+        "Gulshan"
+        "Babar"
+        "Baasim"
+        "Ghunayn"
+        "Jaabir"
+        "Nadeem"
+        "Lahiah"
+        "Sair"
+        "Saaqib"
+        "Esfandyar"
+        "Zaheer"
+        "Sabil"
+        "Qutaybah"
+        "Azban"
+        "Zafrul"
+        "Awani"
+        "Tajammul"
+        "Auraq"
+        "Man"
+        "Name"
+        "Tafazal"
+        "Raed"
+        "Baseer"
+        "Quadir"
+        "Dawud"
+        "Talal"
+        "Sabah"
+        "Baashir"
+        "Damurah"
+        "Ibraaheem"
+        "Faizan"
+        "Zaakir"
+        "Ghutayf"
+        "Ehsaas"
+        "Sadeed"
+        "Mad"
+        "Jabir"
+        "Mourib"
+        "Aamil"
+        "Sabeeh"
+        "Bizhan"
+        "Barr"
+        "Basaam"
+        "Ghasaan"
+        "Nail"
+        "Kasim"
+        "Taaj"
+        "Omran"
+        "Madiyan"
+        "Taheem"
+        "Saad"
+        "Kamal"
+        "Raatib"
+        "Taj"
+        "Yadid"
+        "Basheerah"
+        "Aasim"
+        "Zahur"
+        "Saabir"
+        "Kasam"
+        "Naeem"
+        "Tawkeel"
+        "Ghannam"
+        "Tahmaseb"
+        "Awadil"
+        "Liyaaqat"
+        "Tahaw-wur"
+        "Tamanna"
+        "Zafir"
+        "Ghauth"
+        "Ubay"
+        "Zaahid"
+        "Awamil"
+        "Talat"
+        "Maalik"
+        "Name"
+        "Qadar"
+        "Waajid"
+        "Aamirah"
+        "Ayamin"
+        "Kamran"
+        "Kaleem"
+        "Wadi"
+        "Zaahid"
+        "Umar"
+        "Bashaarat"
+        "Saal"
+        "Najeeb"
+        "Kachela"
+        "Sabur"
+        "Buraid"
+        "Rabee"
+        "Najeeb"
+        "Yar"
+        "Umar"
+        "Ossama"
+        "Tahawwur"
+        "Zaahir"
+        "Raashid"
+        "Name"
+        "Tali"
+        "Batool"
+        "Umair"
+        "Ihsaan"
+        "Name"
+        "Majd Udeen"
+        "Kaamil"
+        "Raheel"
+        "Abaan"
+        "Rabah"
+        "Jameel"
+        "Gohar"
+        "Aabid"
+        "Zuwayhir"
+        "Name"
+        "Sadan"
+        "Idris"
+        "Qais"
+        "Sadaqat"
+        "Barraq"
+        "Ejlaal"
+        "Luay"
+        "Jahdami"
+        "Wafeeq"
+        "Wafa"
+        "Rabar"
+        "Aasif"
+        "Dakhil"
+        "Jalaal"
+        "Gulfam"
+        "Saahir"
+        "Name"
+        "Maroof"
+        "Baasit"
+        "Kabeer"
+        "Jameel"
+        "Latif"
+        "Badr Udeen"
+        "Qahtan"
+        "Liyaqat"
+        "Jabr"
+        "Kaleema"
+        "Fazli"
+        "Name"
+        "Huzaifa"
+        "Man"
+        "Rohaan"
+        "Ubadah"
+        "Saburah"
+        "Saariyah"
+        "Kaysan"
+        "Raakin"
+        "Sabiq"
+        "Saboor"
+        "Zahaar"
+        "Jaabir"
+    )
diff --git a/faker/providers/person/fr_BE/__init__.py b/faker/providers/person/fr_BE/__init__.py
index 19385cb6..553c79c3 100644
--- a/faker/providers/person/fr_BE/__init__.py
+++ b/faker/providers/person/fr_BE/__init__.py
@@ -3,6 +3,7 @@
 Last names and male and female first names for locale 'fr_BE' (French-speaking Belgium).
 Source: Statbel (Directorate-general Statistics - Statistics Belgium), https://statbel.fgov.be/en/about-statbel, 2022.
 """
+
 from collections import Counter, OrderedDict
 
 from .. import Provider as PersonProvider
diff --git a/faker/providers/person/ga_IE/__init__.py b/faker/providers/person/ga_IE/__init__.py
index ff71bba0..2aaad62d 100644
--- a/faker/providers/person/ga_IE/__init__.py
+++ b/faker/providers/person/ga_IE/__init__.py
@@ -5,6 +5,7 @@ The name list was sourced from UCD and DCU project
 First names from Central Statistic Office, 1970 data
 https://www.cso.ie/en/interactivezone/visualisationtools/babynamesofireland/
 """
+
 from .. import Provider as PersonProvider
 
 
diff --git a/faker/providers/person/nl_BE/__init__.py b/faker/providers/person/nl_BE/__init__.py
index f70718cb..bac5eace 100644
--- a/faker/providers/person/nl_BE/__init__.py
+++ b/faker/providers/person/nl_BE/__init__.py
@@ -3,6 +3,7 @@
 Last names and male and female first names for locale 'nl_BE' (Dutch-speaking Belgium).
 Source: Statbel (Directorate-general Statistics - Statistics Belgium), https://statbel.fgov.be/en/about-statbel, 2022.
 """
+
 from collections import Counter, OrderedDict
 
 from .. import Provider as PersonProvider
diff --git a/faker/providers/person/vi_VN/__init__.py b/faker/providers/person/vi_VN/__init__.py
new file mode 100644
index 00000000..563c5df3
--- /dev/null
+++ b/faker/providers/person/vi_VN/__init__.py
@@ -0,0 +1,110 @@
+from .. import Provider as PersonProvider
+
+
+class Provider(PersonProvider):
+    formats_female = (
+        "{{first_name_female}} {{last_name}}",
+        "{{first_name_unisex}} {{last_name}}",
+        "{{prefix_female}} {{first_name_unisex}} {{last_name}}",
+        "{{prefix_female}} {{first_name_female}} {{last_name}}",
+    )
+    formats_male = (
+        "{{first_name_male}} {{last_name}}",
+        "{{first_name_male}} {{middle_name}} {{last_name}}",
+        "{{first_name_unisex}} {{middle_name}} {{last_name}}",
+        "{{prefix_male}} {{first_name_male}} {{last_name}}",
+    )
+    formats = formats_female + formats_male
+
+    # Name from : https://en.wikipedia.org/wiki/Vietnamese_name
+    # and https://vinpearl.com/en/vietnamese-names-top-200-popular-names-for-boys-and-girls
+
+    first_names_female = (
+        "Ngọc",
+        "Hương",
+        "Lan",
+        "Mai",
+        "Thảo",
+        "Linh",
+        "Hồng",
+        "Chi",
+        "Vân",
+        "Duyên",
+        "Dương",
+        "Yến",
+        "Vi",
+        "Ánh",
+        "Xuân",
+    )
+
+    first_names_unisex = (
+        "An",
+        "Hà",
+        "Bảo",
+        "Lâm",
+        "Hạnh",
+        "Thành",
+        "Kim",
+        "Nhật",
+        "Phương",
+        "Khoa",
+        "Hải",
+        "Nhật",
+    )
+
+    first_names_male = (
+        "Nam",
+        "Hưng",
+        "Vũ",
+        "Tú",
+        "Hoàng",
+        "Phúc",
+        "Trung",
+        "Quang",
+        "Anh",
+        "Khoa",
+        "Dũng",
+        "Quang",
+        "Thành",
+        "Huy",
+        "Bảo",
+        "Châu",
+        "Minh",
+        "Tùng",
+        "Nhiên",
+        "Trọng",
+    )
+
+    middle_names = (
+        "Văn",
+        "Thị",
+        "Quang",
+        "Đức",
+        "Trí",
+        "Xuân",
+        "Hoàng",
+        "Hải",
+        "Đức",
+        "Thế",
+        "Tấn",
+        "Phú",
+        "Hữu",
+        "Bảo",
+        "Mai",
+        "Mai Bảo",
+    )
+
+    last_names = ("Nguyễn", "Trần", "Lê", "Phạm", "Vũ", "Đặng", "Bùi", "Dương", "Mai", "Hoàng")
+
+    # Typically, Vietnamese will be addressed with their given name and a prefix
+    # https://en.wikipedia.org/wiki/Vietnamese_name#Given_name
+
+    prefixes_female = ("Cô", "Chị", "Bà", "Quý cô")
+
+    prefixes_male = ("Ông", "Anh", "Bác", "Quý ông")
+
+    def first_name_unisex(self) -> str:
+        return self.random_element(self.first_names_unisex)
+
+    def middle_name(self) -> str:
+        return self.random_element(self.middle_names)
diff --git a/faker/providers/phone_number/vi_VN/__init__.py b/faker/providers/phone_number/vi_VN/__init__.py
new file mode 100644
index 00000000..e89c2129
--- /dev/null
+++ b/faker/providers/phone_number/vi_VN/__init__.py
@@ -0,0 +1,17 @@
+from .. import Provider as PhoneNumberProvider
+
+
+class Provider(PhoneNumberProvider):
+    """Implement phone_number provider for ``vi_VN`` locale.
+    # Source : https://vi.wikipedia.org/wiki/M%C3%A3_%C4%91i%E1%BB%87n_tho%E1%BA%A1i_Vi%E1%BB%87t_Nam
+    """
+
+    formats = (
+        "+84 ## #######",
+        "(0#) #### ####",
+        "0# #### ####",
+        "0# #######",
+        "+84-##-######",
+        "+84-##-### ####",
+        "(0#)###-####",
+    )
diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py
index 669efdad..d601c8d4 100644
--- a/faker/providers/python/__init__.py
+++ b/faker/providers/python/__init__.py
@@ -285,7 +285,7 @@ class Provider(BaseProvider):
         self,
         left_digits: Optional[int] = None,
         right_digits: Optional[int] = None,
-        positive: bool = False,
+        positive: Optional[bool] = None,
         min_value: Optional[BasicNumber] = None,
         max_value: Optional[BasicNumber] = None,
     ) -> Decimal:
@@ -320,7 +320,10 @@ class Provider(BaseProvider):
         elif max_value is not None and max_value <= 0:
             sign = "-"
         else:
-            sign = "+" if positive else self.random_element(("+", "-"))
+            if positive is None:
+                sign = self.random_element(("+", "-"))
+            else:
+                sign = "+" if positive else "-"
 
         if sign == "+":
             if max_value is not None:
diff --git a/faker/providers/sbn/sbn.py b/faker/providers/sbn/sbn.py
index 070f799b..d7ab921a 100644
--- a/faker/providers/sbn/sbn.py
+++ b/faker/providers/sbn/sbn.py
@@ -2,6 +2,7 @@
 This module is responsible for generating the check digit and formatting
 SBN numbers.
 """
+
 from typing import Any, Optional
 
 
diff --git a/faker/proxy.pyi b/faker/proxy.pyi
index e8931ca9..54347af4 100644
--- a/faker/proxy.pyi
+++ b/faker/proxy.pyi
@@ -34,6 +34,7 @@ class Faker:
         :example: '791 Crist Parks, Sashabury, IL 86039-9874'
         """
         ...
+
     def administrative_unit(self) -> str: ...
     def bothify(self, text: str = ..., letters: str = ...) -> str:
         """
@@ -53,22 +54,26 @@ class Faker:
         :sample: text='Product Number: ????-########', letters='ABCDE'
         """
         ...
+
     def building_number(self) -> str:
         """
         :example: '791'
         """
         ...
+
     def city(self) -> str:
         """
         :example: 'Sashabury'
         """
         ...
+
     def city_prefix(self) -> str: ...
     def city_suffix(self) -> str:
         """
         :example: 'town'
         """
         ...
+
     def country(self) -> str: ...
     def country_code(self, representation: str = ...) -> str: ...
     def current_country(self) -> str: ...
@@ -85,11 +90,13 @@ class Faker:
         :sample: text='MAC Address: ^^:^^:^^:^^:^^:^^', upper=True
         """
         ...
+
     def language_code(self) -> str:
         """
         Generate a random i18n language code (e.g. en).
         """
         ...
+
     def lexify(self, text: str = ..., letters: str = ...) -> str:
         """
         Generate a string with each question mark ('?') in ``text``
@@ -101,31 +108,37 @@ class Faker:
         :sample: text='Random Identifier: ??????????', letters='ABCDE'
         """
         ...
+
     def locale(self) -> str:
         """
         Generate a random underscored i18n locale code (e.g. en_US).
         """
         ...
+
     def military_apo(self) -> str:
         """
         :example: 'PSC 5394 Box 3492
         """
         ...
+
     def military_dpo(self) -> str:
         """
         :example: 'Unit 3333 Box 9342'
         """
         ...
+
     def military_ship(self) -> str:
         """
         :example: 'USS'
         """
         ...
+
     def military_state(self) -> str:
         """
         :example: 'APO'
         """
         ...
+
     def numerify(self, text: str = ...) -> str:
         """
         Generate a string with each placeholder in ``text`` replaced according
@@ -147,6 +160,7 @@ class Faker:
         :sample: text='!!! !!@ !@! !@@ @!! @!@ @@! @@@'
         """
         ...
+
     def postalcode(self) -> str: ...
     def postalcode_in_state(self, state_abbr: Optional[str] = ...) -> str: ...
     def postalcode_plus4(self) -> str: ...
@@ -155,6 +169,7 @@ class Faker:
         :example: 86039-9874
         """
         ...
+
     def postcode_in_state(self, state_abbr: Optional[str] = ...) -> str:
         """
         :returns: A random postcode within the provided state abbreviation
@@ -162,6 +177,7 @@ class Faker:
         :param state_abbr: A state abbreviation
         """
         ...
+
     def random_choices(
         self, elements: Union[Collection[str], Collection[T], OrderedDict[T, float]] = ..., length: Optional[int] = ...
     ) -> Sequence[T]:
@@ -188,21 +204,25 @@ class Faker:
                  ]), length=20
         """
         ...
+
     def random_digit(self) -> int:
         """
         Generate a random digit (0 to 9).
         """
         ...
+
     def random_digit_above_two(self) -> int:
         """
         Generate a random digit above value two (2 to 9).
         """
         ...
+
     def random_digit_not_null(self) -> int:
         """
         Generate a random non-zero digit (1 to 9).
         """
         ...
+
     def random_digit_not_null_or_empty(self) -> Union[int, str]:
         """
         Generate a random non-zero digit (1 to 9) or an empty string.
@@ -211,6 +231,7 @@ class Faker:
         and each digit has a 1/18 chance of being generated.
         """
         ...
+
     def random_digit_or_empty(self) -> Union[int, str]:
         """
         Generate a random digit (0 to 9) or an empty string.
@@ -219,6 +240,7 @@ class Faker:
         and each digit has a 1/20 chance of being generated.
         """
         ...
+
     def random_element(self, elements: Union[Collection[str], Collection[T], OrderedDict[T, float]] = ...) -> T:
         """
         Generate a randomly sampled object from ``elements``.
@@ -237,6 +259,7 @@ class Faker:
                  ])
         """
         ...
+
     def random_elements(
         self,
         elements: Union[Collection[str], Collection[T], OrderedDict[T, float]] = ...,
@@ -301,6 +324,7 @@ class Faker:
                    ]), unique=True
         """
         ...
+
     def random_int(self, min: int = ..., max: int = ..., step: int = ...) -> int:
         """
         Generate a random integer between two integers ``min`` and ``max`` inclusive
@@ -313,11 +337,13 @@ class Faker:
         :sample: min=0, max=15, step=3
         """
         ...
+
     def random_letter(self) -> str:
         """
         Generate a random ASCII letter (a-z and A-Z).
         """
         ...
+
     def random_letters(self, length: int = ...) -> Sequence[str]:
         """
         Generate a list of random ASCII letters (a-z and A-Z) of the specified ``length``.
@@ -325,11 +351,13 @@ class Faker:
         :sample: length=10
         """
         ...
+
     def random_lowercase_letter(self) -> str:
         """
         Generate a random lowercase ASCII letter (a-z).
         """
         ...
+
     def random_number(self, digits: Optional[int] = ..., fix_len: bool = ...) -> int:
         """
         Generate a random integer according to the following rules:
@@ -348,6 +376,7 @@ class Faker:
         :sample: digits=3, fix_len=True
         """
         ...
+
     def random_sample(
         self, elements: Union[Collection[str], Collection[T], OrderedDict[T, float]] = ..., length: Optional[int] = ...
     ) -> Sequence[T]:
@@ -362,11 +391,13 @@ class Faker:
         :sample: elements=('a', 'b', 'c', 'd', 'e', 'f'), length=3
         """
         ...
+
     def random_uppercase_letter(self) -> str:
         """
         Generate a random uppercase ASCII letter (A-Z).
         """
         ...
+
     def randomize_nb_elements(
         self, number: int = ..., le: bool = ..., ge: bool = ..., min: Optional[int] = ..., max: Optional[int] = ...
     ) -> int:
@@ -392,6 +423,7 @@ class Faker:
         :sample: number=79, le=True, ge=True, min=80
         """
         ...
+
     def secondary_address(self) -> str: ...
     def state(self) -> str: ...
     def state_abbr(self, include_territories: bool = ..., include_freely_associated_states: bool = ...) -> str:
@@ -407,21 +439,25 @@ class Faker:
             If False, sovereign states in free association with the US will be excluded.
         """
         ...
+
     def street_address(self) -> str:
         """
         :example: '791 Crist Parks'
         """
         ...
+
     def street_name(self) -> str:
         """
         :example: 'Crist Parks'
         """
         ...
+
     def street_suffix(self) -> str:
         """
         :example: 'Avenue'
         """
         ...
+
     def zipcode(self) -> str: ...
     def zipcode_in_state(self, state_abbr: Optional[str] = ...) -> str: ...
     def zipcode_plus4(self) -> str: ...
@@ -430,31 +466,37 @@ class Faker:
         Generate a license plate.
         """
         ...
+
     def vin(self) -> str:
         """
         Generate vin number.
         """
         ...
+
     def aba(self) -> str:
         """
         Generate an ABA routing transit number.
         """
         ...
+
     def bank_country(self) -> str:
         """
         Generate the bank provider's ISO 3166-1 alpha-2 country code.
         """
         ...
+
     def bban(self) -> str:
         """
         Generate a Basic Bank Account Number (BBAN).
         """
         ...
+
     def iban(self) -> str:
         """
         Generate an International Bank Account Number (IBAN).
         """
         ...
+
     def swift(self, length: Optional[int] = ..., primary: bool = ..., use_dataset: bool = ...) -> str:
         """
         Generate a SWIFT code.
@@ -490,6 +532,7 @@ class Faker:
         :sample: length=11, primary=True, use_dataset=True
         """
         ...
+
     def swift11(self, primary: bool = ..., use_dataset: bool = ...) -> str:
         """
         Generate an 11-digit SWIFT code.
@@ -503,6 +546,7 @@ class Faker:
         :sample: use_dataset=True
         """
         ...
+
     def swift8(self, use_dataset: bool = ...) -> str:
         """
         Generate an 8-digit SWIFT code.
@@ -515,6 +559,7 @@ class Faker:
         :sample: use_dataset=True
         """
         ...
+
     def ean(self, length: int = ..., prefixes: Tuple[Union[int, str, Tuple[Union[int, str], ...]], ...] = ...) -> str:
         """
         Generate an EAN barcode of the specified ``length``.
@@ -531,6 +576,7 @@ class Faker:
         :sample: prefixes=('45', '49')
         """
         ...
+
     def ean13(
         self,
         prefixes: Tuple[Union[int, str, Tuple[Union[int, str], ...]], ...] = ...,
@@ -568,6 +614,7 @@ class Faker:
         :sample: prefixes=('45', '49')
         """
         ...
+
     def ean8(self, prefixes: Tuple[Union[int, str, Tuple[Union[int, str], ...]], ...] = ...) -> str:
         """
         Generate an EAN-8 barcode.
@@ -583,6 +630,7 @@ class Faker:
         :sample: prefixes=('45', '49')
         """
         ...
+
     def localized_ean(self, length: int = ...) -> str:
         """
         Generate a localized EAN barcode of the specified ``length``.
@@ -599,6 +647,7 @@ class Faker:
         :sample: length=8
         """
         ...
+
     def localized_ean13(self) -> str:
         """
         Generate a localized EAN-13 barcode.
@@ -607,6 +656,7 @@ class Faker:
         argument explicitly set to ``13``.
         """
         ...
+
     def localized_ean8(self) -> str:
         """
         Generate a localized EAN-8 barcode.
@@ -615,6 +665,7 @@ class Faker:
         argument explicitly set to ``8``.
         """
         ...
+
     def upc_a(
         self, upc_ae_mode: bool = ..., base: Optional[str] = ..., number_system_digit: Optional[int] = ...
     ) -> str:
@@ -653,6 +704,7 @@ class Faker:
         :sample: upc_ae_mode=True, base='120004', number_system_digit=0
         """
         ...
+
     def upc_e(self, base: Optional[str] = ..., number_system_digit: Optional[int] = ..., safe_mode: bool = ...) -> str:
         """
         Generate an 8-digit UPC-E barcode.
@@ -700,6 +752,7 @@ class Faker:
         :sample: base='120004', number_system_digit=0, safe_mode=False
         """
         ...
+
     def color(
         self,
         hue: Union[str, float, int, Sequence[int], None] = ...,
@@ -742,6 +795,7 @@ class Faker:
         :sample: hue=(300, 20), luminosity='random', color_format='hsl'
         """
         ...
+
     def color_hsl(
         self, hue: Union[str, float, int, Sequence[int], None] = ..., luminosity: Optional[str] = ...
     ) -> Tuple[int, int, int]:
@@ -749,6 +803,7 @@ class Faker:
         Generate a HSL color tuple in a human-friendly way.
         """
         ...
+
     def color_hsv(
         self, hue: Union[str, float, int, Sequence[int], None] = ..., luminosity: Optional[str] = ...
     ) -> Tuple[int, int, int]:
@@ -756,11 +811,13 @@ class Faker:
         Generate a HSV color tuple in a human-friendly way.
         """
         ...
+
     def color_name(self) -> str:
         """
         Generate a color name.
         """
         ...
+
     def color_rgb(
         self, hue: Union[str, float, int, Sequence[int], None] = ..., luminosity: Optional[str] = ...
     ) -> Tuple[int, int, int]:
@@ -768,6 +825,7 @@ class Faker:
         Generate a RGB color tuple of integers in a human-friendly way.
         """
         ...
+
     def color_rgb_float(
         self, hue: Union[str, float, int, Sequence[int], None] = ..., luminosity: Optional[str] = ...
     ) -> Tuple[float, float, float]:
@@ -775,51 +833,61 @@ class Faker:
         Generate a RGB color tuple of floats in a human-friendly way.
         """
         ...
+
     def hex_color(self) -> str:
         """
         Generate a color formatted as a hex triplet.
         """
         ...
+
     def rgb_color(self) -> str:
         """
         Generate a color formatted as a comma-separated RGB value.
         """
         ...
+
     def rgb_css_color(self) -> str:
         """
         Generate a color formatted as a CSS rgb() function.
         """
         ...
+
     def safe_color_name(self) -> str:
         """
         Generate a web-safe color name.
         """
         ...
+
     def safe_hex_color(self) -> str:
         """
         Generate a web-safe color formatted as a hex triplet.
         """
         ...
+
     def bs(self) -> str:
         """
         :example: 'integrate extensible convergence'
         """
         ...
+
     def catch_phrase(self) -> str:
         """
         :example: 'Robust full-range hub'
         """
         ...
+
     def company(self) -> str:
         """
         :example: 'Acme Ltd'
         """
         ...
+
     def company_suffix(self) -> str:
         """
         :example: 'Ltd'
         """
         ...
+
     def credit_card_expire(
         self,
         start: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -836,26 +904,31 @@ class Faker:
         to that method.
         """
         ...
+
     def credit_card_full(self, card_type: Optional[CardType] = ...) -> str:
         """
         Generate a set of credit card details.
         """
         ...
+
     def credit_card_number(self, card_type: Optional[CardType] = ...) -> str:
         """
         Generate a valid credit card number.
         """
         ...
+
     def credit_card_provider(self, card_type: Optional[CardType] = ...) -> str:
         """
         Generate a credit card provider name.
         """
         ...
+
     def credit_card_security_code(self, card_type: Optional[CardType] = ...) -> str:
         """
         Generate a credit card security code.
         """
         ...
+
     def cryptocurrency(self) -> Tuple[str, str]: ...
     def cryptocurrency_code(self) -> str: ...
     def cryptocurrency_name(self) -> str: ...
@@ -867,6 +940,7 @@ class Faker:
         :example: $
         """
         ...
+
     def pricetag(self) -> str: ...
     def am_pm(self) -> str: ...
     def century(self) -> str:
@@ -874,6 +948,7 @@ class Faker:
         :example: 'XVII'
         """
         ...
+
     def date(
         self,
         pattern: str = ...,
@@ -887,6 +962,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_between(
         self,
         start_date: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -902,6 +978,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_between_dates(
         self,
         date_start: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int, None] = ...,
@@ -916,6 +993,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_object(self, end_datetime: Optional[datetime.datetime] = ...) -> datetime.date:
         """
         Get a date object between January 1, 1970 and now
@@ -923,6 +1001,7 @@ class Faker:
         :example: datetime.date(2016, 9, 20)
         """
         ...
+
     def date_of_birth(
         self, tzinfo: Optional[datetime.tzinfo] = ..., minimum_age: int = ..., maximum_age: int = ...
     ) -> datetime.date:
@@ -939,6 +1018,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_this_century(self, before_today: bool = ..., after_today: bool = ...) -> datetime.date:
         """
         Gets a Date object for the current century.
@@ -949,6 +1029,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_this_decade(self, before_today: bool = ..., after_today: bool = ...) -> datetime.date:
         """
         Gets a Date object for the decade year.
@@ -959,6 +1040,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_this_month(self, before_today: bool = ..., after_today: bool = ...) -> datetime.date:
         """
         Gets a Date object for the current month.
@@ -969,6 +1051,7 @@ class Faker:
         :return: dtdate
         """
         ...
+
     def date_this_year(self, before_today: bool = ..., after_today: bool = ...) -> datetime.date:
         """
         Gets a Date object for the current year.
@@ -979,6 +1062,7 @@ class Faker:
         :return: Date
         """
         ...
+
     def date_time(
         self,
         tzinfo: Optional[datetime.tzinfo] = ...,
@@ -992,6 +1076,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_ad(
         self,
         tzinfo: Optional[datetime.tzinfo] = ...,
@@ -1006,6 +1091,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_between(
         self,
         start_date: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -1023,6 +1109,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_between_dates(
         self,
         datetime_start: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int, None] = ...,
@@ -1041,6 +1128,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_this_century(
         self, before_now: bool = ..., after_now: bool = ..., tzinfo: Optional[datetime.tzinfo] = ...
     ) -> datetime.datetime:
@@ -1054,6 +1142,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_this_decade(
         self, before_now: bool = ..., after_now: bool = ..., tzinfo: Optional[datetime.tzinfo] = ...
     ) -> datetime.datetime:
@@ -1067,6 +1156,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_this_month(
         self, before_now: bool = ..., after_now: bool = ..., tzinfo: Optional[datetime.tzinfo] = ...
     ) -> datetime.datetime:
@@ -1080,6 +1170,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def date_time_this_year(
         self, before_now: bool = ..., after_now: bool = ..., tzinfo: Optional[datetime.tzinfo] = ...
     ) -> datetime.datetime:
@@ -1093,6 +1184,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def day_of_month(self) -> str: ...
     def day_of_week(self) -> str: ...
     def future_date(
@@ -1111,6 +1203,7 @@ class Faker:
         :return: dtdate
         """
         ...
+
     def future_datetime(
         self,
         end_date: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -1127,6 +1220,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def iso8601(
         self,
         tzinfo: Optional[datetime.tzinfo] = ...,
@@ -1143,6 +1237,7 @@ class Faker:
         :example: '2003-10-21T16:05:52+0000'
         """
         ...
+
     def month(self) -> str: ...
     def month_name(self) -> str: ...
     def past_date(
@@ -1161,6 +1256,7 @@ class Faker:
         :return: dtdate
         """
         ...
+
     def past_datetime(
         self,
         start_date: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -1177,6 +1273,7 @@ class Faker:
         :return: datetime
         """
         ...
+
     def pytimezone(self, *args: Any, **kwargs: Any) -> Optional[datetime.tzinfo]:
         """
         Generate a random timezone (see `faker.timezone` for any args)
@@ -1187,6 +1284,7 @@ class Faker:
         :return: dateutil.tz.tz.tzfile
         """
         ...
+
     def time(
         self,
         pattern: str = ...,
@@ -1199,6 +1297,7 @@ class Faker:
         :example: '15:02:34'
         """
         ...
+
     def time_delta(
         self, end_datetime: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int, None] = ...
     ) -> datetime.timedelta:
@@ -1206,6 +1305,7 @@ class Faker:
         Get a timedelta object
         """
         ...
+
     def time_object(
         self, end_datetime: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int, None] = ...
     ) -> datetime.time:
@@ -1215,6 +1315,7 @@ class Faker:
         :example: datetime.time(15, 56, 56, 772876)
         """
         ...
+
     def time_series(
         self,
         start_date: Union[datetime.date, datetime.datetime, datetime.timedelta, str, int] = ...,
@@ -1231,6 +1332,7 @@ class Faker:
         ``distrib`` is a callable that accepts ``<datetime>`` and returns ``<value>``
         """
         ...
+
     def timezone(self) -> str: ...
     def unix_time(
         self,
@@ -1246,12 +1348,14 @@ class Faker:
         :example: 1061306726.6
         """
         ...
+
     def year(self) -> str: ...
     def emoji(self) -> str:
         """
         :example: '😉'
         """
         ...
+
     def file_extension(self, category: Optional[str] = ...) -> str:
         """
         Generate a file extension under the specified ``category``.
@@ -1264,6 +1368,7 @@ class Faker:
         :sample: category='image'
         """
         ...
+
     def file_name(self, category: Optional[str] = ..., extension: Optional[str] = ...) -> str:
         """
         Generate a random file name with extension.
@@ -1283,6 +1388,7 @@ class Faker:
         :sample: extension=''
         """
         ...
+
     def file_path(
         self,
         depth: int = ...,
@@ -1322,6 +1428,7 @@ class Faker:
         :sample: depth=5, category='video', extension='abcdef', file_system='windows'
         """
         ...
+
     def mime_type(self, category: Optional[str] = ...) -> str:
         """
         Generate a mime type under the specified ``category``.
@@ -1335,6 +1442,7 @@ class Faker:
         :sample: category='application'
         """
         ...
+
     def unix_device(self, prefix: Optional[str] = ...) -> str:
         """
         Generate a Unix device file name.
@@ -1346,6 +1454,7 @@ class Faker:
         :sample: prefix='mmcblk'
         """
         ...
+
     def unix_partition(self, prefix: Optional[str] = ...) -> str:
         """
         Generate a Unix partition name.
@@ -1357,11 +1466,13 @@ class Faker:
         :sample: prefix='mmcblk'
         """
         ...
+
     def coordinate(self, center: Optional[float] = ..., radius: Union[float, int] = ...) -> Decimal:
         """
         Optionally center the coord and pick a point within radius.
         """
         ...
+
     def latitude(self) -> Decimal: ...
     def latlng(self) -> Tuple[Decimal, Decimal]: ...
     def local_latlng(self, country_code: str = ..., coords_only: bool = ...) -> Optional[Tuple[str, ...]]:
@@ -1370,6 +1481,7 @@ class Faker:
         Defaults to 'en_US'. See the `land_coords` list for available locations/countries.
         """
         ...
+
     def location_on_land(self, coords_only: bool = ...) -> Tuple[str, ...]:
         """
         Returns a random tuple specifying a coordinate set guaranteed to exist on land.
@@ -1377,6 +1489,7 @@ class Faker:
         Pass `coords_only` to return coordinates without metadata.
         """
         ...
+
     def longitude(self) -> Decimal: ...
     def ascii_company_email(self) -> str: ...
     def ascii_email(self) -> str: ...
@@ -1403,6 +1516,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def domain_name(self, levels: int = ...) -> str:
         """
         Produce an Internet domain name with the specified number of
@@ -1414,6 +1528,7 @@ class Faker:
         williamson-hopkins.jackson.com
         """
         ...
+
     def domain_word(self) -> str: ...
     def email(self, safe: bool = ..., domain: Optional[str] = ...) -> str: ...
     def free_email(self) -> str: ...
@@ -1430,6 +1545,7 @@ class Faker:
         web-12.williamson-hopkins.jackson.com
         """
         ...
+
     def http_method(self) -> str:
         """
         Returns random HTTP method
@@ -1438,6 +1554,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def http_status_code(self, include_unassigned: bool = ...) -> int:
         """
         Returns random HTTP status code
@@ -1451,6 +1568,7 @@ class Faker:
         :example: 404
         """
         ...
+
     def iana_id(self) -> str:
         """
         Returns IANA Registrar ID
@@ -1459,6 +1577,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def image_url(
         self, width: Optional[int] = ..., height: Optional[int] = ..., placeholder_url: Optional[str] = ...
     ) -> str:
@@ -1474,6 +1593,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def ipv4(self, network: bool = ..., address_class: Optional[str] = ..., private: Optional[str] = ...) -> str:
         """
         Returns a random IPv4 address or network with a valid CIDR.
@@ -1484,6 +1604,7 @@ class Faker:
         :returns: IPv4
         """
         ...
+
     def ipv4_network_class(self) -> str:
         """
         Returns a IPv4 network class 'a', 'b' or 'c'.
@@ -1491,6 +1612,7 @@ class Faker:
         :returns: IPv4 network class
         """
         ...
+
     def ipv4_private(self, network: bool = ..., address_class: Optional[str] = ...) -> str:
         """
         Returns a private IPv4.
@@ -1500,6 +1622,7 @@ class Faker:
         :returns: Private IPv4
         """
         ...
+
     def ipv4_public(self, network: bool = ..., address_class: Optional[str] = ...) -> str:
         """
         Returns a public IPv4 excluding private blocks.
@@ -1509,11 +1632,13 @@ class Faker:
         :returns: Public IPv4
         """
         ...
+
     def ipv6(self, network: bool = ...) -> str:
         """
         Produce a random IPv6 address or network with a valid CIDR
         """
         ...
+
     def mac_address(self, multicast: bool = ...) -> str:
         """
         Returns a random MAC address.
@@ -1522,6 +1647,7 @@ class Faker:
         :returns: MAC Address
         """
         ...
+
     def nic_handle(self, suffix: str = ...) -> str:
         """
         Returns NIC Handle ID
@@ -1530,6 +1656,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def nic_handles(self, count: int = ..., suffix: str = ...) -> List[str]:
         """
         Returns NIC Handle ID list
@@ -1537,6 +1664,7 @@ class Faker:
         :rtype: list[str]
         """
         ...
+
     def port_number(self, is_system: bool = ..., is_user: bool = ..., is_dynamic: bool = ...) -> int:
         """
         Returns a network port number
@@ -1548,6 +1676,7 @@ class Faker:
         :rtype: int
         """
         ...
+
     def ripe_id(self) -> str:
         """
         Returns RIPE Organization ID
@@ -1556,6 +1685,7 @@ class Faker:
         :rtype: str
         """
         ...
+
     def safe_domain_name(self) -> str: ...
     def safe_email(self) -> str: ...
     def slug(self, value: Optional[str] = ...) -> str:
@@ -1563,6 +1693,7 @@ class Faker:
         Django algorithm
         """
         ...
+
     def tld(self) -> str: ...
     def uri(self, schemes: Optional[List[str]] = ..., deep: Optional[int] = ...) -> str:
         """
@@ -1573,6 +1704,7 @@ class Faker:
         :return: a random url string.
         """
         ...
+
     def uri_extension(self) -> str: ...
     def uri_page(self) -> str: ...
     def uri_path(self, deep: Optional[int] = ...) -> str: ...
@@ -1584,6 +1716,7 @@ class Faker:
         :return: a random url string.
         """
         ...
+
     def user_name(self) -> str: ...
     def isbn10(self, separator: str = ...) -> str: ...
     def isbn13(self, separator: str = ...) -> str: ...
@@ -1614,6 +1747,7 @@ class Faker:
             exhaust said lists if ``unique`` is ``True``, raising an exception.
         """
         ...
+
     def paragraph(
         self, nb_sentences: int = ..., variable_nb_sentences: bool = ..., ext_word_list: Optional[Sequence[str]] = ...
     ) -> str:
@@ -1637,6 +1771,7 @@ class Faker:
                  ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def paragraphs(self, nb: int = ..., ext_word_list: Optional[Sequence[str]] = ...) -> List[str]:
         """
         Generate a list of paragraphs.
@@ -1650,6 +1785,7 @@ class Faker:
         :sample: nb=5, ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def sentence(
         self, nb_words: int = ..., variable_nb_words: bool = ..., ext_word_list: Optional[Sequence[str]] = ...
     ) -> str:
@@ -1671,6 +1807,7 @@ class Faker:
                  ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def sentences(self, nb: int = ..., ext_word_list: Optional[Sequence[str]] = ...) -> List[str]:
         """
         Generate a list of sentences.
@@ -1685,6 +1822,7 @@ class Faker:
         :sample: nb=5, ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def text(self, max_nb_chars: int = ..., ext_word_list: Optional[Sequence[str]] = ...) -> str:
         """
         Generate a text string.
@@ -1701,6 +1839,7 @@ class Faker:
         :sample: ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def texts(
         self, nb_texts: int = ..., max_nb_chars: int = ..., ext_word_list: Optional[Sequence[str]] = ...
     ) -> List[str]:
@@ -1718,6 +1857,7 @@ class Faker:
                  ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
+
     def word(self, part_of_speech: Optional[str] = ..., ext_word_list: Optional[Sequence[str]] = ...) -> str:
         """
         Generate a word.
@@ -1729,7 +1869,14 @@ class Faker:
         :sample: ext_word_list=['abc', 'def', 'ghi', 'jkl']
         """
         ...
-    def words(self, nb: int = ..., ext_word_list: Optional[List[str]] = ..., unique: bool = ...) -> List[str]:
+
+    def words(
+        self,
+        nb: int = ...,
+        ext_word_list: Optional[List[str]] = ...,
+        part_of_speech: Optional[str] = ...,
+        unique: bool = ...,
+    ) -> List[str]:
         """
         Generate a tuple of words.
 
@@ -1752,6 +1899,7 @@ class Faker:
         :sample: nb=4, ext_word_list=['abc', 'def', 'ghi', 'jkl'], unique=True
         """
         ...
+
     def binary(self, length: int = ...) -> bytes:
         """
         Generate a random binary blob of ``length`` bytes.
@@ -1762,6 +1910,7 @@ class Faker:
         :sample: length=64
         """
         ...
+
     def boolean(self, chance_of_getting_true: int = ...) -> bool:
         """
         Generate a random boolean value based on ``chance_of_getting_true``.
@@ -1771,6 +1920,7 @@ class Faker:
         :sample: chance_of_getting_true=75
         """
         ...
+
     def csv(
         self,
         header: Optional[Sequence[str]] = ...,
@@ -1790,6 +1940,7 @@ class Faker:
                 num_rows=10, include_row_ids=True
         """
         ...
+
     def dsv(
         self,
         dialect: str = ...,
@@ -1828,6 +1979,7 @@ class Faker:
         :sample: data_columns=('{{name}}', '{{address}}'), num_rows=5, delimiter='$'
         """
         ...
+
     def fixed_width(self, data_columns: Optional[list] = ..., num_rows: int = ..., align: str = ...) -> str:
         """
         Generate random fixed width values.
@@ -1865,6 +2017,7 @@ class Faker:
                 'max_value': 100})], align='right', num_rows=2
         """
         ...
+
     def image(
         self,
         size: Tuple[int, int] = ...,
@@ -1891,6 +2044,7 @@ class Faker:
         :sample: size=(16, 16), hue=[90,270], image_format='ico'
         """
         ...
+
     def json(
         self,
         data_columns: Optional[List] = ...,
@@ -1943,6 +2097,7 @@ class Faker:
                 {'min_value': 50, 'max_value': 100})], num_rows=1
         """
         ...
+
     def json_bytes(
         self,
         data_columns: Optional[List] = ...,
@@ -1957,6 +2112,7 @@ class Faker:
         :meth:`json() <faker.providers.misc.Provider.json>` which is used under the hood.
         """
         ...
+
     def md5(self, raw_output: bool = ...) -> Union[bytes, str]:
         """
         Generate a random MD5 hash.
@@ -1968,11 +2124,13 @@ class Faker:
         :sample: raw_output=True
         """
         ...
+
     def null_boolean(self) -> Optional[bool]:
         """
         Generate ``None``, ``True``, or ``False``, each with equal probability.
         """
         ...
+
     def password(
         self,
         length: int = ...,
@@ -1995,6 +2153,7 @@ class Faker:
         :sample: length=40, special_chars=False, upper_case=False
         """
         ...
+
     def psv(
         self,
         header: Optional[Sequence[str]] = ...,
@@ -2014,6 +2173,7 @@ class Faker:
                 num_rows=10, include_row_ids=True
         """
         ...
+
     def sha1(self, raw_output: bool = ...) -> Union[bytes, str]:
         """
         Generate a random SHA-1 hash.
@@ -2025,6 +2185,7 @@ class Faker:
         :sample: raw_output=True
         """
         ...
+
     def sha256(self, raw_output: bool = ...) -> Union[bytes, str]:
         """
         Generate a random SHA-256 hash.
@@ -2036,6 +2197,7 @@ class Faker:
         :sample: raw_output=True
         """
         ...
+
     def tar(
         self,
         uncompressed_size: int = ...,
@@ -2064,6 +2226,7 @@ class Faker:
         :sample: uncompressed_size=256, num_files=32, min_file_size=4, compression='bz2'
         """
         ...
+
     def tsv(
         self,
         header: Optional[Sequence[str]] = ...,
@@ -2083,6 +2246,7 @@ class Faker:
                 num_rows=10, include_row_ids=True
         """
         ...
+
     def uuid4(
         self, cast_to: Union[Callable[[UUID], str], Callable[[UUID], bytes], None] = ...
     ) -> Union[bytes, str, UUID]:
@@ -2097,6 +2261,7 @@ class Faker:
         :sample: cast_to=None
         """
         ...
+
     def xml(
         self,
         nb_elements: int = ...,
@@ -2114,6 +2279,7 @@ class Faker:
         Note: this provider required xmltodict library installed
         """
         ...
+
     def zip(
         self,
         uncompressed_size: int = ...,
@@ -2142,6 +2308,7 @@ class Faker:
         :sample: uncompressed_size=256, num_files=32, min_file_size=4, compression='bz2'
         """
         ...
+
     def passport_dates(self, birthday: datetime.date = ...) -> Tuple[str, str, str]:
         """
         Generates a formatted date of birth, issue, and expiration dates.
@@ -2155,16 +2322,19 @@ class Faker:
         -https://travel.state.gov/content/travel/en/passports/passport-help/faqs.html
         """
         ...
+
     def passport_dob(self) -> datetime.date:
         """
         Generate a datetime date of birth.
         """
         ...
+
     def passport_full(self) -> str:
         """
         Generates a formatted sting with US Passport information
         """
         ...
+
     def passport_gender(self, seed: int = ...) -> str:
         """
         Generates a string representing the gender displayed on a passport
@@ -2174,11 +2344,13 @@ class Faker:
         - https://williamsinstitute.law.ucla.edu/publications/x-gender-markers-passports/
         """
         ...
+
     def passport_number(self) -> str:
         """
         Generate a passport number by replacing tokens to be alphanumeric
         """
         ...
+
     def passport_owner(self, gender: str = ...) -> Tuple[str, str]:
         """
         Generate a given_name and surname for a passport owner
@@ -2186,6 +2358,7 @@ class Faker:
         that is either male, female, or non-binary.
         """
         ...
+
     def first_name(self) -> str: ...
     def first_name_female(self) -> str: ...
     def first_name_male(self) -> str: ...
@@ -2195,6 +2368,7 @@ class Faker:
         Generate a random i18n language name (e.g. English).
         """
         ...
+
     def last_name(self) -> str: ...
     def last_name_female(self) -> str: ...
     def last_name_male(self) -> str: ...
@@ -2204,6 +2378,7 @@ class Faker:
         :example: 'John Doe'
         """
         ...
+
     def name_female(self) -> str: ...
     def name_male(self) -> str: ...
     def name_nonbinary(self) -> str: ...
@@ -2222,6 +2397,7 @@ class Faker:
         https://en.wikipedia.org/wiki/MSISDN
         """
         ...
+
     def phone_number(self) -> str: ...
     def profile(
         self, fields: Optional[List[str]] = ..., sex: Optional[Literal["M", "F"]] = ...
@@ -2231,6 +2407,7 @@ class Faker:
         If "fields" is not empty, only the fields in the list will be returned
         """
         ...
+
     def simple_profile(
         self, sex: Optional[Literal["M", "F"]] = ...
     ) -> Dict[str, Union[str, datetime.date, Literal["M", "F"]]]:
@@ -2238,6 +2415,7 @@ class Faker:
         Generates a basic profile with personal informations
         """
         ...
+
     def enum(self, enum_cls: Type[TEnum]) -> TEnum:
         """
         Returns a random enum of the provided input `Enum` type.
@@ -2246,6 +2424,7 @@ class Faker:
         :returns: A randomly selected enum value.
         """
         ...
+
     def pybool(self, truth_probability: int = ...) -> bool:
         """
         Generates a random boolean, optionally biased towards `True` or `False`.
@@ -2255,11 +2434,12 @@ class Faker:
         :raises ValueError: If invalid `truth_probability` is provided.
         """
         ...
+
     def pydecimal(
         self,
         left_digits: Optional[int] = ...,
         right_digits: Optional[int] = ...,
-        positive: bool = ...,
+        positive: Optional[bool] = ...,
         min_value: Union[float, int, None] = ...,
         max_value: Union[float, int, None] = ...,
     ) -> Decimal: ...
@@ -2278,6 +2458,7 @@ class Faker:
         :value_types: type of dictionary values
         """
         ...
+
     def pyfloat(
         self,
         left_digits: Optional[int] = ...,
@@ -2312,6 +2493,7 @@ class Faker:
         :raises ValueError: if the object type passed is not supported
         """
         ...
+
     def pyset(
         self,
         nb_elements: int = ...,
@@ -2330,6 +2512,7 @@ class Faker:
         :return: Random of random length between min and max characters.
         """
         ...
+
     def pystr_format(self, string_format: str = ..., letters: str = ...) -> str: ...
     def pystruct(
         self,
@@ -2358,6 +2541,7 @@ class Faker:
         https://www.irs.gov/businesses/small-businesses-self-employed/employer-id-numbers
         """
         ...
+
     def invalid_ssn(self) -> str:
         """
         Generate a random invalid United States Social Security Identification Number (SSN).
@@ -2374,6 +2558,7 @@ class Faker:
         Additionally, return an invalid SSN that is NOT a valid ITIN by excluding certain ITIN related "group" values
         """
         ...
+
     def itin(self) -> str:
         """
         Generate a random United States Individual Taxpayer Identification Number (ITIN).
@@ -2388,6 +2573,7 @@ class Faker:
         https://www.irs.gov/individuals/international-taxpayers/general-itin-information
         """
         ...
+
     def ssn(self, taxpayer_identification_number_type: str = ...) -> str:
         """
         Generate a random United States Taxpayer Identification Number of the specified type.
@@ -2395,71 +2581,85 @@ class Faker:
         If no type is specified, a US SSN is returned.
         """
         ...
+
     def android_platform_token(self) -> str:
         """
         Generate an Android platform token used in user agent strings.
         """
         ...
+
     def chrome(self, version_from: int = ..., version_to: int = ..., build_from: int = ..., build_to: int = ...) -> str:
         """
         Generate a Chrome web browser user agent string.
         """
         ...
+
     def firefox(self) -> str:
         """
         Generate a Mozilla Firefox web browser user agent string.
         """
         ...
+
     def internet_explorer(self) -> str:
         """
         Generate an IE web browser user agent string.
         """
         ...
+
     def ios_platform_token(self) -> str:
         """
         Generate an iOS platform token used in user agent strings.
         """
         ...
+
     def linux_platform_token(self) -> str:
         """
         Generate a Linux platform token used in user agent strings.
         """
         ...
+
     def linux_processor(self) -> str:
         """
         Generate a Linux processor token used in user agent strings.
         """
         ...
+
     def mac_platform_token(self) -> str:
         """
         Generate a MacOS platform token used in user agent strings.
         """
         ...
+
     def mac_processor(self) -> str:
         """
         Generate a MacOS processor token used in user agent strings.
         """
         ...
+
     def opera(self) -> str:
         """
         Generate an Opera web browser user agent string.
         """
         ...
+
     def safari(self) -> str:
         """
         Generate a Safari web browser user agent string.
         """
         ...
+
     def user_agent(self) -> str:
         """
         Generate a random web browser user agent string.
         """
         ...
+
     def windows_platform_token(self) -> str:
         """
         Generate a Windows platform token used in user agent strings.
         """
         ...
+
     def area_code(self) -> str: ...
     def cellphone_number(self) -> str: ...
     def cellphone_provider_code(self) -> str: ...
@@ -2472,12 +2672,14 @@ class Faker:
         Generate an initial number for license plates.
         """
         ...
+
     def operator_id(self) -> str: ...
     def district(self) -> str:
         """
         Generate a district code for license plates.
         """
         ...
+
     def provider_code(self) -> str: ...
     def license_plate_ar(self) -> str:
         """
@@ -2489,56 +2691,67 @@ class Faker:
         value.
         """
         ...
+
     def license_plate_en(self) -> str:
         """
         Generate a license plate in Latin/Western characters.
         """
         ...
+
     def district_suffix(self) -> str:
         """
         :example: 'r.'
         """
         ...
+
     def house_number(self) -> str:
         """
         :example: 'm. 49'
         """
         ...
+
     def settlement(self) -> str:
         """
         :example: 'Horadiz'
         """
         ...
+
     def settlement_suffix(self) -> str:
         """
         :example: 'qəs.'
         """
         ...
+
     def street(self) -> str:
         """
         :example: 'A.AĞAYEV'
         """
         ...
+
     def village(self) -> str:
         """
         :example: 'Didivar'
         """
         ...
+
     def village_suffix(self) -> str:
         """
         :example: 'k.'
         """
         ...
+
     def bank(self) -> str:
         """
         Generate a bank name.
         """
         ...
+
     def large_company(self) -> str:
         """
         :example: 'SOCAR'
         """
         ...
+
     def last_name_unique_to_female(self) -> str: ...
     def last_name_unique_to_male(self) -> str: ...
     def last_name_unisex(self) -> str: ...
@@ -2550,102 +2763,120 @@ class Faker:
         :return: A random Bulgarian VAT ID
         """
         ...
+
     def area_name(self) -> str:
         """
         :example: 'উজির'
         """
         ...
+
     def building_name(self) -> str:
         """
         :example: 'বাড়ী নং'
         """
         ...
+
     def town(self) -> str:
         """
         :example: 'নবাব'
         """
         ...
+
     def city_name(self) -> str:
         """
         :example: 'ঢাকা মেট্রো'
         """
         ...
+
     def vehicle_category_letter(self) -> str:
         """
         :example: 'ব'
         """
         ...
+
     def vehicle_category_number(self) -> str:
         """
         :example: '১১'
         """
         ...
+
     def vehicle_serial_number(self) -> str:
         """
         Generate a 4 digits vehicle serial number.
         :example: '৫৪৩২'
         """
         ...
+
     def first_name_female_common(self) -> str:
         """
         Return religiously unbiased female first name.
         :example: 'অর্পিতা'
         """
         ...
+
     def first_name_female_hinduism(self) -> str:
         """
         Return Hindu religion based female first name.
         :example: 'দূর্গা'
         """
         ...
+
     def first_name_female_islamic(self) -> str:
         """
         Return Islam religion based female first name.
         :example: 'মেহজাবিন'
         """
         ...
+
     def first_name_male_common(self) -> str:
         """
         Return religiously unbiased male first name.
         :example: 'প্রিতম'
         """
         ...
+
     def first_name_male_hinduism(self) -> str:
         """
         Return Hindu religion based male first name.
         :example: 'অশোক'
         """
         ...
+
     def first_name_male_islamic(self) -> str:
         """
         Return Islam religion based male first name.
         :example: 'ইকবাল'
         """
         ...
+
     def last_name_common(self) -> str:
         """
         Return religiously and gender unbiased last name.
         :example: 'চৌধুরী'
         """
         ...
+
     def last_name_female_islamic(self) -> str:
         """
         Return Islam religion based female last name.
         :example: 'খাতুন'
         """
         ...
+
     def last_name_hinduism(self) -> str:
         """
         Return gender unbiased Hindu religion based last name.
         :example: 'দত্ত'
         """
         ...
+
     def last_name_islamic(self) -> str:
         """
         Return gender unbiased Islam religion based last name.
         :example: 'আলি'
         """
         ...
+
     def city_with_postcode(self) -> str: ...
     def street_suffix_long(self) -> str: ...
     def street_suffix_short(self) -> str: ...
@@ -2655,11 +2886,13 @@ class Faker:
         https://en.wikipedia.org/wiki/National_identification_number#Czech_Republic_and_Slovakia
         """
         ...
+
     def dk_street_name(self) -> str:
         """
         This returns the name of a street, without any suffix.
         """
         ...
+
     def local_latitude(self) -> Decimal: ...
     def local_longitude(self) -> Decimal: ...
     def canton(self) -> Tuple[str, str]:
@@ -2668,18 +2901,21 @@ class Faker:
         :example ('ZH', 'Zürich')
         """
         ...
+
     def canton_code(self) -> str:
         """
         Randomly returns a Swiss canton code.
         :example 'ZH'
         """
         ...
+
     def canton_name(self) -> str:
         """
         Randomly returns a Swiss canton name.
         :example 'Zürich'
         """
         ...
+
     def line_address(self) -> str: ...
     def region(self) -> str: ...
     def street_prefix(self) -> str: ...
@@ -2691,24 +2927,28 @@ class Faker:
         :return: a random Greek identity card number
         """
         ...
+
     def tin(self) -> str:
         """
         Generates random Greek personal TINs
         :return: a random Greek personal TIN
         """
         ...
+
     def postal_code_letter(self) -> str:
         """
         Returns a random letter from the list of allowable
         letters in a canadian postal code
         """
         ...
+
     def postalcode_in_province(self, province_abbr: Optional[str] = ...) -> str: ...
     def postcode_in_province(self, province_abbr: Optional[str] = ...) -> str:
         """
         Returns a random postcode within the provided province abbreviation
         """
         ...
+
     def province(self) -> str: ...
     def province_abbr(self) -> str: ...
     def county(self) -> str: ...
@@ -2720,6 +2960,17 @@ class Faker:
         Official Website: https://uidai.gov.in/my-aadhaar/about-your-aadhaar.html
         """
         ...
+
+    def building_prefix(self) -> str: ...
+    def city_prefix_abbr(self) -> str: ...
+    def city_state(self) -> str:
+        """
+        Return the complete city address with matching postcode and state
+
+        Example: 55100 Bukit Bintang, Kuala Lumpur
+        """
+        ...
+
     def rd_number(self) -> str: ...
     def te_reo_ending(self) -> str: ...
     def te_reo_first(self) -> str: ...
@@ -2759,6 +3010,7 @@ class Faker:
            considered automobiles for this purpose.
         """
         ...
+
     def motorcycle_license_plate(self) -> str:
         """
         Generate a motorcycle license plate.
@@ -2768,6 +3020,7 @@ class Faker:
            are issued motorcycle license plates.
         """
         ...
+
     def protocol_license_plate(self) -> str:
         """
         Generate a protocol license plate.
@@ -2777,6 +3030,7 @@ class Faker:
            protocol license plates.
         """
         ...
+
     def company_type(self) -> str: ...
     def random_company_acronym(self) -> str: ...
     def random_company_adjective(self) -> str: ...
@@ -2790,6 +3044,7 @@ class Faker:
         :sample: nb_sentences=5, variable_nb_sentences=False
         """
         ...
+
     def english_paragraphs(self, nb: int = ...) -> List[str]:
         """
         Generate a list of paragraphs in English.
@@ -2797,6 +3052,7 @@ class Faker:
         :sample: nb=5
         """
         ...
+
     def english_sentence(self, nb_words: int = ..., variable_nb_words: bool = ...) -> str:
         """
         Generate a sentence in English.
@@ -2805,6 +3061,7 @@ class Faker:
         :sample: nb_words=10, variable_nb_words=False
         """
         ...
+
     def english_sentences(self, nb: int = ...) -> List[str]:
         """
         Generate a list of sentences in English.
@@ -2812,6 +3069,7 @@ class Faker:
         :sample: nb=5
         """
         ...
+
     def english_text(self, max_nb_chars: int = ...) -> str:
         """
         Generate a text string in English.
@@ -2821,6 +3079,7 @@ class Faker:
         :sample: max_nb_chars=160
         """
         ...
+
     def english_texts(self, nb_texts: int = ..., max_nb_chars: int = ...) -> List[str]:
         """
         Generate a list of text strings in English.
@@ -2829,11 +3088,13 @@ class Faker:
         :sample: nb_texts=5, max_nb_chars=50
         """
         ...
+
     def english_word(self) -> str:
         """
         Generate an English word.
         """
         ...
+
     def english_words(self, nb: int = ..., unique: bool = ...) -> List[str]:
         """
         Generate a list of English words.
@@ -2842,6 +3103,7 @@ class Faker:
         :sample: nb=5, unique=True
         """
         ...
+
     def gemstone_name(self) -> str: ...
     def mountain_name(self) -> str: ...
     def plant_name(self) -> str: ...
@@ -2873,71 +3135,84 @@ class Faker:
         :example: "La Plata"
         """
         ...
+
     def municipality_code(self) -> str:
         """
         :example: "1900"
         """
         ...
+
     def provinces_code(self) -> str:
         """
         :example: "BA"
         """
         ...
+
     def street_municipality(self) -> str:
         """
         :example: "La Plata"
         """
         ...
+
     def street_procer(self) -> str:
         """
         :example: "Belgrano"
         """
         ...
+
     def street_province(self) -> str:
         """
         :example: "San Juan"
         """
         ...
+
     def license_plate_mercosur(self) -> str:
         """
         Generate an new plate with Mercosur format. Since 2016
         """
         ...
+
     def license_plate_old(self) -> str:
         """
         Generate an old format license plate. Since 1995 to 2016
         """
         ...
+
     def cif(self) -> str:
         """
         https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
         :return: a random Spanish CIF
         """
         ...
+
     def doi(self) -> str:
         """
         https://es.wikipedia.org/wiki/Identificador_de_objeto_digital
         :return: a random Spanish CIF or NIE or NIF
         """
         ...
+
     def nie(self) -> str:
         """
         https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero
         :return: a random Spanish NIE
         """
         ...
+
     def nif(self) -> str:
         """
         https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal
         :return: NIF
         """
         ...
+
     def nuss(self, company: bool = ...) -> str:
         """
         :param company: flag to indicate if we should generate a company NUSS
         :return: a random Spanish Social Security Number (Número de la Seguridad Social)
         """
         ...
+
     def common_street_name(self) -> str: ...
     def commune(self) -> str: ...
     def commune_and_region(self) -> str: ...
@@ -2957,21 +3232,25 @@ class Faker:
         :example: 'Grupo'
         """
         ...
+
     def given_name(self) -> str:
         """
         Generates a composite given name with two unique names
         """
         ...
+
     def given_name_female(self) -> str:
         """
         Generates a composite female given name with two unique names
         """
         ...
+
     def given_name_male(self) -> str:
         """
         Generates a composite male given name with two unique names
         """
         ...
+
     def cellphone_block(self) -> str: ...
     def landline_code(self) -> str: ...
     def special_code(self) -> str: ...
@@ -2980,11 +3259,13 @@ class Faker:
         :return: a random Chilean RUT between 60.000.000 and 99.999.999
         """
         ...
+
     def person_rut(self) -> str:
         """
         :return: a random Chilean RUT between a 10 and 31.999.999 range
         """
         ...
+
     def rut(self, min: int = ..., max: int = ...) -> str:
         """
         Generates a RUT within the specified ranges, inclusive.
@@ -2994,44 +3275,52 @@ class Faker:
         :return: a random Chilean RUT between 35.000.000 and 99.999.999
         """
         ...
+
     def department(self) -> str:
         """
         :example: "Bogotá, D.C."
         """
         ...
+
     def department_code(self) -> str:
         """
         :example: "11"
         """
         ...
+
     def legal_person_nit(self) -> str:
         """
         https://es.wikipedia.org/wiki/N%C3%BAmero_de_Identificaci%C3%B3n_Tributaria
         :example: '967807269'
         """
         ...
+
     def legal_person_nit_with_check_digit(self) -> str:
         """
         :example: '967807269-7'
         """
         ...
+
     def natural_person_nit(self) -> str:
         """
         https://es.wikipedia.org/wiki/C%C3%A9dula_de_Ciudadan%C3%ADa_(Colombia)
         :example: '1095312769'
         """
         ...
+
     def natural_person_nit_with_check_digit(self) -> str:
         """
         :example: '1095312769-0'
         """
         ...
+
     def nuip(self) -> str:
         """
         https://es.wikipedia.org/wiki/C%C3%A9dula_de_Ciudadan%C3%ADa_(Colombia)
         :example: '1095312769'
         """
         ...
+
     def autonomous_community(self) -> str: ...
     def state_name(self) -> str: ...
     def license_plate_by_province(self, province_prefix: Optional[str] = ...) -> str:
@@ -3043,11 +3332,13 @@ class Faker:
         will be selected at random.
         """
         ...
+
     def license_plate_unified(self) -> str:
         """
         Generate a unified license plate.
         """
         ...
+
     def random_name_complements(self) -> str: ...
     def city_adjective(self) -> str: ...
     def clabe(self, bank_code: Optional[int] = ...) -> str:
@@ -3064,6 +3355,7 @@ class Faker:
         :sample: bank_code=2
         """
         ...
+
     def curp(self) -> str:
         """
         See https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Registro_de_Poblaci%C3%B3n.
@@ -3071,6 +3363,7 @@ class Faker:
         :return: a random Mexican CURP (Unique Population Registry Code)
         """
         ...
+
     def elector_code(self, gender: Optional[Literal["H", "M"]] = ...) -> str:
         """
         Unique elector code issued by INE (Instituto Nacional Electoral) in Mexico.
@@ -3084,6 +3377,7 @@ class Faker:
         :sample: gender='M'
         """
         ...
+
     def rfc(self, natural: bool = ...) -> str:
         """
         See https://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes
@@ -3094,6 +3388,7 @@ class Faker:
         :return: a random Mexican RFC
         """
         ...
+
     def first_name_est(self) -> str: ...
     def first_name_female_est(self) -> str: ...
     def first_name_female_rus(self) -> str: ...
@@ -3111,6 +3406,7 @@ class Faker:
         non-zero.
         """
         ...
+
     def company_vat(self) -> str:
         """
         Returns Finnish VAT identification number (Arvonlisaveronumero).
@@ -3118,6 +3414,7 @@ class Faker:
         adding prefix "FI" and removing dash before checksum.
         """
         ...
+
     def english_catch_phrase(self) -> str: ...
     def random_good_service_adjective(self) -> str: ...
     def random_good_service_adjective_chain(self) -> str: ...
@@ -3128,33 +3425,39 @@ class Faker:
         Returns a random catch phrase attribute.
         """
         ...
+
     def catch_phrase_noun(self) -> str:
         """
         Returns a random catch phrase noun.
         """
         ...
+
     def catch_phrase_verb(self) -> str:
         """
         Returns a random catch phrase verb.
         """
         ...
+
     def ide(self) -> str:
         """
         Generates a IDE number (9 digits).
         http://www.bfs.admin.ch/bfs/portal/fr/index/themen/00/05/blank/03/02.html
         """
         ...
+
     def idi(self) -> str:
         """
         Generates a IDE number (9 digits).
         http://www.bfs.admin.ch/bfs/portal/fr/index/themen/00/05/blank/03/02.html
         """
         ...
+
     def siren(self) -> str:
         """
         Generates a siren number (9 digits). Formatted as '### ### ###'.
         """
         ...
+
     def siret(self, max_sequential_digits: int = ...) -> str:
         """
         Generates a siret number (14 digits).
@@ -3166,18 +3469,21 @@ class Faker:
         :param max_sequential_digits The maximum number of digits for the sequential number (> 0 && <= 4).
         """
         ...
+
     def uid(self) -> str:
         """
         Generates a IDE number (9 digits).
         http://www.bfs.admin.ch/bfs/portal/fr/index/themen/00/05/blank/03/02.html
         """
         ...
+
     def department_name(self) -> str:
         """
         Randomly returns a french department name.
         :example: 'Ardèche'
         """
         ...
+
     def department_number(self) -> str:
         """
         Randomly returns a french department number.
@@ -3185,6 +3491,7 @@ class Faker:
         :example: '59'
         """
         ...
+
     def area_code_with_separator(self) -> str: ...
     def area_code_without_separator(self) -> str: ...
     def street_title(self) -> str: ...
@@ -3199,6 +3506,7 @@ class Faker:
         :example: 'գ.'
         """
         ...
+
     def postcode_city_province(self) -> str: ...
     @staticmethod
     def is_leap_year(year: int) -> bool:
@@ -3206,26 +3514,31 @@ class Faker:
         Checks if the one given is a leap year
         """
         ...
+
     def ban(self) -> str:
         """
         :example: '3番'
         """
         ...
+
     def chome(self) -> str:
         """
         :example: '1丁目'
         """
         ...
+
     def gou(self) -> str:
         """
         :example: '10号'
         """
         ...
+
     def prefecture(self) -> str:
         """
         :example: '東京都'
         """
         ...
+
     def jan(self, length: int = ...) -> str:
         """
         Generate a JAN barcode of the specified ``length``.
@@ -3237,6 +3550,7 @@ class Faker:
         :sample: length=13
         """
         ...
+
     def jan13(self) -> str:
         """
         Generate a 13 digit JAN barcode.
@@ -3244,6 +3558,7 @@ class Faker:
         This method is an alias for |JaJpProvider.localized_ean13|.
         """
         ...
+
     def jan8(self) -> str:
         """
         Generate a 8 digit JAN barcode.
@@ -3251,6 +3566,7 @@ class Faker:
         This method is an alias for |JaJpProvider.localized_ean8|.
         """
         ...
+
     def company_category(self) -> str: ...
     def traditional_month_name(self) -> str: ...
     def first_kana_name(self) -> str:
@@ -3258,176 +3574,205 @@ class Faker:
         :example: 'アケミ'
         """
         ...
+
     def first_kana_name_female(self) -> str:
         """
         :example: 'アケミ'
         """
         ...
+
     def first_kana_name_male(self) -> str:
         """
         :example: 'アキラ'
         """
         ...
+
     def first_name_female_pair(self) -> Tuple[str, str, str]:
         """
         :example: ('明美', 'アケミ', 'Akemi')
         """
         ...
+
     def first_name_male_pair(self) -> Tuple[str, str, str]:
         """
         :example: ('晃', 'アキラ', 'Akira')
         """
         ...
+
     def first_name_pair(self) -> Tuple[str, str, str]:
         """
         :example: ('明美', 'アケミ', 'Akemi')
         """
         ...
+
     def first_romanized_name(self) -> str:
         """
         :example: 'Akemi'
         """
         ...
+
     def first_romanized_name_female(self) -> str:
         """
         :example: 'Akemi'
         """
         ...
+
     def first_romanized_name_male(self) -> str:
         """
         :example: 'Akira'
         """
         ...
+
     def kana_name(self) -> str:
         """
         :example: 'サトウ アケミ'
         """
         ...
+
     def kana_name_female(self) -> str:
         """
         :example: 'サトウ アケミ'
         """
         ...
+
     def kana_name_male(self) -> str:
         """
         :example: 'サトウ アキラ'
         """
         ...
+
     def last_kana_name(self) -> str:
         """
         :example: 'サトウ'
         """
         ...
+
     def last_name_pair(self) -> Tuple[str, str, str]:
         """
         :example: ('佐藤', 'サトウ', 'Sato')
         """
         ...
+
     def last_romanized_name(self) -> str:
         """
         :example: 'Sato'
         """
         ...
+
     def romanized_name(self) -> str:
         """
         :example: 'Akemi Sato'
         """
         ...
+
     def romanized_name_female(self) -> str:
         """
         :example: 'Akemi Sato'
         """
         ...
+
     def romanized_name_male(self) -> str:
         """
         :example: 'Akira Sato'
         """
         ...
+
     def address_detail(self) -> str:
         """
         :example: 가나아파트 가동 102호
         """
         ...
+
     def borough(self) -> str:
         """
         :example: 중구
         """
         ...
+
     def building_dong(self) -> str:
         """
         :example: 가
         """
         ...
+
     def building_suffix(self) -> str:
         """
         :example: 아파트
         """
         ...
+
     def land_address(self) -> str:
         """
         :example: 세종특별자치시 어진동 507
         """
         ...
+
     def land_number(self) -> str:
         """
         :example: 507
         """
         ...
+
     def metropolitan_city(self) -> str:
         """
         :example: 서울특별시
         """
         ...
+
     def old_postal_code(self) -> str:
         """
         :example: 123-456
         """
         ...
+
     def postal_code(self) -> str:
         """
         :example: 12345
         """
         ...
+
     def road(self) -> str:
         """
         :example: 도움5로
         """
         ...
+
     def road_address(self) -> str:
         """
         :example: 세종특별자치시 도움5로 19 (어진동)
         """
         ...
+
     def road_number(self) -> str:
         """
         :example: 24
         """
         ...
+
     def road_suffix(self) -> str:
         """
         :example: 길
         """
         ...
+
     def town_suffix(self) -> str:
         """
         :example: 동
         """
         ...
-    def building_prefix(self) -> str:
-        """
-        :example: वडा
-        """
-        ...
+
     def license_plate_car(self) -> str:
         """
         Generate a license plate for cars.
         """
         ...
+
     def license_plate_motorbike(self) -> str:
         """
         Generate a license plate for motorbikes.
         """
         ...
+
     def first_name_unisex(self) -> str: ...
     def middle_name(self) -> str: ...
     def license_plate_regex_formats(self) -> List[str]:
@@ -3440,6 +3785,7 @@ class Faker:
            this method.
         """
         ...
+
     def local_regon(self) -> str:
         """
         Returns 14 character Polish National Business Registry Number,
@@ -3448,6 +3794,7 @@ class Faker:
         https://pl.wikipedia.org/wiki/REGON
         """
         ...
+
     def regon(self) -> str:
         """
         Returns 9 character Polish National Business Registry Number,
@@ -3456,6 +3803,7 @@ class Faker:
         https://pl.wikipedia.org/wiki/REGON
         """
         ...
+
     def identity_card_number(self) -> str:
         """
         Returns 9 character Polish Identity Card Number,
@@ -3467,6 +3815,7 @@ class Faker:
         https://en.wikipedia.org/wiki/Polish_identity_card
         """
         ...
+
     def nip(self) -> str:
         """
         Returns 10 digit of Number of tax identification.
@@ -3477,6 +3826,7 @@ class Faker:
         http://www.algorytm.org/numery-identyfikacyjne/nip.html
         """
         ...
+
     def pesel(self, date_of_birth: Optional[datetime.datetime] = ..., sex: Optional[str] = ...) -> str:
         """
         Returns 11 characters of Universal Electronic System for Registration of the Population.
@@ -3496,6 +3846,7 @@ class Faker:
         https://en.wikipedia.org/wiki/PESEL
         """
         ...
+
     def pesel_compute_check_digit(self, pesel: str) -> int: ...
     def pwz_doctor(self) -> str:
         """
@@ -3505,6 +3856,7 @@ class Faker:
         https://www.nil.org.pl/rejestry/centralny-rejestr-lekarzy/zasady-weryfikowania-nr-prawa-wykonywania-zawodu
         """
         ...
+
     def pwz_doctor_compute_check_digit(self, x: Sequence[int]) -> int: ...
     def pwz_nurse(self, kind: str = ...) -> str:
         """
@@ -3517,6 +3869,7 @@ class Faker:
         -rady-pielegniarek-i-polo
         """
         ...
+
     def bairro(self) -> str:
         """
         Randomly returns a bairro (neighborhood) name.
@@ -3524,24 +3877,28 @@ class Faker:
         :example: 'Serra'
         """
         ...
+
     def estado(self) -> Tuple[str, str]:
         """
         Randomly returns a Brazilian State  ('sigla' , 'nome').
         :example: ('MG' . 'Minas Gerais')
         """
         ...
+
     def estado_nome(self) -> str:
         """
         Randomly returns a Brazilian State Name
         :example: 'Minas Gerais'
         """
         ...
+
     def estado_sigla(self) -> str:
         """
         Randomly returns the abbreviation of a Brazilian State
         :example: 'MG'
         """
         ...
+
     def neighborhood(self) -> str: ...
     def cnpj(self) -> str: ...
     def company_id(self) -> str: ...
@@ -3552,61 +3909,73 @@ class Faker:
         Check:  https://www.ngmatematica.com/2014/02/como-determinar-o-digito-verificador-do.html
         """
         ...
+
     def concelho(self) -> str:
         """
         :example: 'Tondela'
         """
         ...
+
     def distrito(self) -> str:
         """
         :example: 'Bragança'
         """
         ...
+
     def freguesia(self) -> str:
         """
         :example: 'Miranda do Douro'
         """
         ...
+
     def place_name(self) -> str:
         """
         :example: "do Pombal"
         """
         ...
+
     def nationality(self) -> str:
         """
         :example: 'Portuguesa'
         """
         ...
+
     def plate_letter(self) -> str:
         """
         Generate a letter for license plates.
         """
         ...
+
     def plate_number(self) -> str:
         """
         Generate a number for license plates.
         """
         ...
+
     def plate_number_extra(self) -> str:
         """
         Generate extra numerical code for license plates.
         """
         ...
+
     def plate_number_special(self) -> str:
         """
         Generate a special code for license plates.
         """
         ...
+
     def plate_suffix(self) -> str:
         """
         Generate a suffix code for license plates.
         """
         ...
+
     def vehicle_category(self) -> str:
         """
         Generate a vehicle category code for license plates.
         """
         ...
+
     def bic(self) -> str:
         """
         Generate a bank identification code (BIC).
@@ -3615,6 +3984,7 @@ class Faker:
         See https://ru.wikipedia.org/wiki/Банковский_идентификационный_код.
         """
         ...
+
     def checking_account(self) -> str:
         """
         Generate a checking account number.
@@ -3624,6 +3994,7 @@ class Faker:
         See https://ru.wikipedia.org/wiki/Расчётный_счёт.
         """
         ...
+
     def correspondent_account(self) -> str:
         """
         Generate a correspondent account number.
@@ -3633,33 +4004,39 @@ class Faker:
         See https://ru.wikipedia.org/wiki/Корреспондентский_счёт.
         """
         ...
+
     def businesses_inn(self) -> str:
         """
         Returns tax identification number for businesses (ru. идентификационный номер налогоплательщика, ИНН).
         """
         ...
+
     def businesses_ogrn(self) -> str:
         """
         Returns primary state registration number for businesses
         (ru. основной государственный регистрационный номер, ОГРН).
         """
         ...
+
     def individuals_inn(self) -> str:
         """
         Returns tax identification number for individuals (ru. идентификационный номер налогоплательщика, ИНН).
         """
         ...
+
     def individuals_ogrn(self) -> str:
         """
         Returns primary state registration number for individuals
         (ru. основной государственный регистрационный номер, ОГРН).
         """
         ...
+
     def kpp(self) -> str:
         """
         Returns tax registration reason code (ru. код причины постановки на учет, КПП).
         """
         ...
+
     def middle_name_female(self) -> str: ...
     def middle_name_male(self) -> str: ...
     def org_and_vat_id(self, long: bool = ..., dash: bool = ...) -> Tuple[str, str]:
@@ -3667,6 +4044,7 @@ class Faker:
         Returns matching Org ID and VAT number
         """
         ...
+
     def org_id(self, long: bool = ..., dash: bool = ...) -> str:
         """
         Returns a 10 or 12 digit Organisation ID for a Swedish
@@ -3674,6 +4052,7 @@ class Faker:
         (In Swedish) https://sv.wikipedia.org/wiki/Organisationsnummer
         """
         ...
+
     def amphoe(self) -> str:
         """
         Get a random Amphoe (district) name.
@@ -3681,6 +4060,7 @@ class Faker:
         :example: 'บางสะพานน้อย'
         """
         ...
+
     def tambon(self) -> str:
         """
         Get a random Tambon (subdistrict) name.
@@ -3688,21 +4068,25 @@ class Faker:
         :example: 'ห้วยนาง'
         """
         ...
+
     def company_limited_prefix(self) -> str:
         """
         :example: 'บริษัท'
         """
         ...
+
     def company_limited_suffix(self) -> str:
         """
         :example: 'จำกัด'
         """
         ...
+
     def nonprofit_prefix(self) -> str:
         """
         :example: 'มูลนิธิ'
         """
         ...
+
     def diplomatic_license_plate(self) -> str:
         """
         Example: 'CDP 000'  or 'DP 000 000' or 'S 000 000' format
@@ -3710,6 +4094,7 @@ class Faker:
         :sample:
         """
         ...
+
     def plate_letter_prefix(self, region_name: Optional[str] = ...) -> str:
         """
         Generate a letter for license plates.
@@ -3718,6 +4103,7 @@ class Faker:
         :sample: region_name="Kyiv"
         """
         ...
+
     def plate_letter_suffix(self) -> str:
         """
         Generate a end letter for license plates.
@@ -3725,6 +4111,7 @@ class Faker:
         :sample:
         """
         ...
+
     def plate_region_code(self, region_name: Optional[str] = ...) -> str:
         """
         Generate plate region number
@@ -3733,6 +4120,7 @@ class Faker:
         :sample: region_name="Kyiv"
         """
         ...
+
     def full_name(self, gender: Optional[Literal["M", "F"]] = ..., short: Optional[bool] = ...) -> str:
         """
         Generate Full Name
@@ -3748,6 +4136,7 @@ class Faker:
         :sample: short=True
         """
         ...
+
     def phonenumber_prefix(self) -> int: ...
     def city_name_suffix(self) -> str: ...
     def section_number(self) -> str: ...
@@ -3759,6 +4148,7 @@ class Faker:
         Default dir() implementation.
         """
         ...
+
     def __getattr__(self, attr: "str") -> "Any":
         """
         Handles cache access and proxying behavior
@@ -3767,6 +4157,7 @@ class Faker:
         :return: the appropriate attribute
         """
         ...
+
     def __getattribute__(self, attr: "str") -> "Any":
         """
         Handles the "attribute resolution" behavior for declared members of this proxy class
@@ -3777,6 +4168,7 @@ class Faker:
         :return: the appropriate attribute
         """
         ...
+
     def __getitem__(self, locale: "str") -> "Faker": ...
     def __init__(
         self,
@@ -3791,6 +4183,7 @@ class Faker:
         Initialize self.  See help(type(self)) for accurate signature.
         """
         ...
+
     def __setstate__(self, state: "Any") -> "None": ...
     def items(self) -> "list[tuple[str, Generator | Faker]]": ...
     @staticmethod
@@ -3801,6 +4194,7 @@ class Faker:
         :param seed: seed value
         """
         ...
+
     def seed_instance(self, seed: "SeedType | None" = ...) -> "None":
         """
         Creates and seeds a new `random.Random` object for each factory
@@ -3808,6 +4202,7 @@ class Faker:
         :param seed: seed value
         """
         ...
+
     def seed_locale(self, locale: "str", seed: "SeedType | None" = ...) -> "None":
         """
         Creates and seeds a new `random.Random` object for the factory of the specified locale
diff --git a/tox.ini b/tox.ini
index 7c1284e9..84dc3808 100644
--- a/tox.ini
+++ b/tox.ini
@@ -46,7 +46,7 @@ commands =
     mypy --install-types --non-interactive --config mypy.ini faker
 
 [testenv:black]
-deps = black==23.3.0
+deps = black==24.4.0
 commands =
     {envpython} -m black --check --line-length 120 .
 


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
index 45607994..6f5b3e41 100644
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -19,6 +19,7 @@ from faker.providers.address.en_CA import Provider as EnCaAddressProvider
 from faker.providers.address.en_GB import Provider as EnGbAddressProvider
 from faker.providers.address.en_IE import Provider as EnIeAddressProvider
 from faker.providers.address.en_IN import Provider as EnInAddressProvider
+from faker.providers.address.en_MS import Provider as EnMsAddressProvider
 from faker.providers.address.en_NZ import Provider as EnNzAddressProvider
 from faker.providers.address.en_PH import Provider as EnPhAddressProvider
 from faker.providers.address.en_US import Provider as EnUsAddressProvider
@@ -52,6 +53,7 @@ from faker.providers.address.sv_SE import Provider as SvSeAddressProvider
 from faker.providers.address.ta_IN import Provider as TaInAddressProvider
 from faker.providers.address.th_TH import Provider as ThThAddressProvider
 from faker.providers.address.uk_UA import Provider as UkUaAddressProvider
+from faker.providers.address.vi_VN import Provider as ViVNAddressProvider
 from faker.providers.address.zh_CN import Provider as ZhCnAddressProvider
 from faker.providers.address.zh_TW import Provider as ZhTwAddressProvider
 
@@ -2030,6 +2032,85 @@ class TestRoRo:
             assert match.group("city") in RoRoAddressProvider.cities
 
 
+class TestEnMs:
+    """Test en_MS address provider methods"""
+
+    def test_city_prefix_abbr(self, faker, num_samples):
+        for _ in range(num_samples):
+            city_prefix_abbr = faker.city_prefix_abbr()
+            assert isinstance(city_prefix_abbr, str)
+            assert city_prefix_abbr in EnMsAddressProvider.city_prefix_abbrs
+
+    def test_city_prefix(self, faker, num_samples):
+        for _ in range(num_samples):
+            city_prefix = faker.city_prefix()
+            assert isinstance(city_prefix, str)
+            assert city_prefix in EnMsAddressProvider.city_prefixes
+
+    def test_city(self, faker, num_samples):
+        for _ in range(num_samples):
+            city = faker.city()
+            assert isinstance(city, str)
+            assert "%" not in city
+            assert "#" not in city
+            assert "?" not in city
+
+    def test_street_prefix(self, faker, num_samples):
+        for _ in range(num_samples):
+            street_prefix = faker.street_prefix()
+            assert isinstance(street_prefix, str)
+            assert street_prefix in EnMsAddressProvider.street_prefixes
+
+    def test_street_name(self, faker, num_samples):
+        for _ in range(num_samples):
+            street_name = faker.street_name()
+            assert isinstance(street_name, str)
+
+    def test_building_prefix(self, faker, num_samples):
+        for _ in range(num_samples):
+            building_prefix = faker.building_prefix()
+            assert isinstance(building_prefix, str)
+
+    def test_building_number(self, faker, num_samples):
+        for _ in range(num_samples):
+            building_number = faker.building_number()
+            assert isinstance(building_number, str)
+
+    def test_city_state(self, faker, num_samples):
+        for _ in range(num_samples):
+            city_state = faker.city_state()
+            assert isinstance(city_state, str)
+
+    @pytest.mark.parametrize(
+        "fn_name",
+        [
+            ("administrative_unit"),
+            ("state"),
+        ],
+    )
+    def test_state_administrative_unit(self, faker, num_samples, fn_name):
+        for _ in range(num_samples):
+            state = getattr(faker, fn_name)()
+            assert isinstance(state, str)
+            assert state in [x for v in EnMsAddressProvider.states.values() for x in v]
+
+    def test_postcode_in_state(self, faker, num_samples):
+        for _ in range(num_samples):
+            for state_abbr in EnMsAddressProvider.states.keys():
+                code = faker.postcode_in_state(state_abbr)
+                assert re.fullmatch(r"\d{5}", code)
+                assert int(code) >= EnMsAddressProvider.states_postcode[state_abbr][0][0]
+                assert int(code) <= EnMsAddressProvider.states_postcode[state_abbr][-1][1]
+
+        with pytest.raises(KeyError):
+            faker.postcode_in_state("XX")
+
+    def test_postcode(self, faker, num_samples):
+        for _ in range(num_samples):
+            code = faker.postcode()
+            assert re.fullmatch(r"\d{5}", code)
+
+
 class TestEnNz:
     """Test en_NZ address provider methods"""
 
@@ -2332,6 +2413,51 @@ class TestUkUa:
             assert region in UkUaAddressProvider.region_names
 
 
+class TestViVn:
+    """Test vi_VN address provider methods"""
+
+    def test_city_prefix(self, faker, num_samples):
+        for _ in range(num_samples):
+            city_prefix = faker.city_prefix()
+            assert isinstance(city_prefix, str)
+            assert city_prefix in ViVNAddressProvider.city_prefixes
+
+    def test_state(self, faker, num_samples):
+        for _ in range(num_samples):
+            state = faker.state()
+            assert isinstance(state, str)
+            assert state in ViVNAddressProvider.provinces
+
+    def test_state_abbr(self, faker, num_samples):
+        for _ in range(num_samples):
+            state_abbr = faker.state_abbr()
+            assert isinstance(state_abbr, str)
+            assert state_abbr in ViVNAddressProvider.provinces_abbr
+
+    def test_postcode(self, faker, num_samples):
+        for _ in range(num_samples):
+            postcode = faker.postcode()
+            assert isinstance(postcode, str) and len(postcode) == 6
+            assert 100000 <= int(postcode) <= 999999
+
+    def test_postcode_in_state(self, faker, num_samples):
+        for _ in range(num_samples):
+            for state_abbr in ViVNAddressProvider.provinces_abbr:
+                postcode = faker.postcode_in_state(state_abbr)
+                assert re.fullmatch(r"\d{6}", postcode)
+                assert int(postcode) >= ViVNAddressProvider.provinces_postcode[state_abbr][0]
+                assert int(postcode) <= ViVNAddressProvider.provinces_postcode[state_abbr][1]
+
+        with pytest.raises(ValueError):
+            faker.postcode_in_state("XX")
+
+    def test_state_abbr_determinism(self, faker):
+        faker.seed_instance(0)
+        first = faker.state_abbr()
+        faker.seed_instance(0)
+        assert faker.state_abbr() == first
+
+
 class TestFrCa:
     """Test fr_CA address provider methods"""
 
diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py
index 40691674..1d26596e 100644
--- a/tests/providers/test_automotive.py
+++ b/tests/providers/test_automotive.py
@@ -336,7 +336,9 @@ class TestNlBe(_SimpleAutomotiveTestMixin):
 class TestZhCn(_SimpleAutomotiveTestMixin):
     """Test zh_CN automotive provider methods"""
 
-    license_plate_pattern: Pattern = re.compile(r"^[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]{1}[A-Z]{1}-[A-Z0-9]{5}")
+    license_plate_pattern: Pattern = re.compile(
+        r"^[京津冀晋蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云渝藏陕甘青宁新]{1}[A-Z]{1}-[A-Z0-9]{5}"
+    )
 
 
 class TestZhTw(_SimpleAutomotiveTestMixin):
diff --git a/tests/providers/test_color.py b/tests/providers/test_color.py
index 359041f3..609c4cf7 100644
--- a/tests/providers/test_color.py
+++ b/tests/providers/test_color.py
@@ -17,6 +17,7 @@ from faker.providers.color.he_IL import Provider as HeILColorProvider
 from faker.providers.color.hy_AM import Provider as HyAmColorProvider
 from faker.providers.color.id_ID import Provider as IdIdColorProvider
 from faker.providers.color.sk_SK import Provider as SkSkColorProvider
+from faker.providers.color.vi_VN import Provider as ViVNColorProvider
 
 
 class TestColorProvider:
@@ -443,3 +444,19 @@ class TestIdId:
             safe_color_name = faker.safe_color_name()
             assert isinstance(safe_color_name, str)
             assert safe_color_name in IdIdColorProvider.safe_colors
+
+
+class TestViVn:
+    """Test vi_VN color provider methods"""
+
+    def test_color_name(self, faker, num_samples):
+        for _ in range(num_samples):
+            color_name = faker.color_name()
+            assert isinstance(color_name, str)
+            assert color_name in ViVNColorProvider.all_colors.keys()
+
+    def test_safe_color_name(self, faker, num_samples):
+        for _ in range(num_samples):
+            safe_color_name = faker.safe_color_name()
+            assert isinstance(safe_color_name, str)
+            assert safe_color_name in ViVNColorProvider.safe_colors
diff --git a/tests/providers/test_company.py b/tests/providers/test_company.py
index 33a007b3..2face87f 100644
--- a/tests/providers/test_company.py
+++ b/tests/providers/test_company.py
@@ -25,6 +25,7 @@ from faker.providers.company.ru_RU import Provider as RuRuCompanyProvider
 from faker.providers.company.ru_RU import calculate_checksum
 from faker.providers.company.th_TH import Provider as ThThCompanyProvider
 from faker.providers.company.tr_TR import Provider as TrTrCompanyProvider
+from faker.providers.company.vi_VN import Provider as ViVnCompanyProvider
 from faker.utils.checksums import luhn_checksum
 
 
@@ -492,3 +493,18 @@ class TestEsEs:
         for _ in range(num_samples):
             company = faker.company()
             assert isinstance(company, str)
+
+
+class TestViVn:
+    """Test vi_VN company provider methods"""
+
+    def test_company_suffix(self, faker, num_samples):
+        for _ in range(num_samples):
+            suffix = faker.company_suffix()
+            assert isinstance(suffix, str)
+            assert suffix in ViVnCompanyProvider.company_suffixes
+
+    def test_company(self, faker, num_samples):
+        for _ in range(num_samples):
+            company = faker.company()
+            assert isinstance(company, str)
diff --git a/tests/providers/test_currency.py b/tests/providers/test_currency.py
index 5161749d..30699c1f 100644
--- a/tests/providers/test_currency.py
+++ b/tests/providers/test_currency.py
@@ -485,3 +485,26 @@ class TestTrTr:
         for _ in range(num_samples):
             pricetag = faker.pricetag()
             assert isinstance(pricetag, str)
+
+
+class TestViVn:
+    """Test vi_VN currency provider"""
+
+    num_samples = 100
+
+    @classmethod
+    def setup_class(cls):
+        from faker.providers.currency.vi_VN import Provider as ViVNCurrencyProvider
+
+        cls.provider = ViVNCurrencyProvider
+        cls.currencies = cls.provider.currencies
+
+    def test_currency(self, faker, num_samples):
+        for _ in range(num_samples):
+            cur = faker.currency()
+            assert isinstance(cur, tuple) and cur in self.currencies
+
+    def test_pricetag(self, faker, num_samples):
+        for _ in range(num_samples):
+            pricetag = faker.pricetag()
+            assert isinstance(pricetag, str)
diff --git a/tests/providers/test_date_time.py b/tests/providers/test_date_time.py
index f6fba540..d708bf84 100644
--- a/tests/providers/test_date_time.py
+++ b/tests/providers/test_date_time.py
@@ -40,6 +40,7 @@ from faker.providers.date_time.sk_SK import Provider as SkSkProvider
 from faker.providers.date_time.sl_SI import Provider as SlSiProvider
 from faker.providers.date_time.ta_IN import Provider as TaInProvider
 from faker.providers.date_time.tr_TR import Provider as TrTrProvider
+from faker.providers.date_time.vi_VN import Provider as ViVNProvider
 from faker.providers.date_time.zh_CN import Provider as ZhCnProvider
 from faker.providers.date_time.zh_TW import Provider as ZhTwProvider
 
@@ -1317,3 +1318,21 @@ class TestJaJp(unittest.TestCase):
     def test_traditional_month(self):
         month = self.fake.traditional_month_name()
         assert month in JaJpProvider.TRADITIONAL_MONTH_NAMES.values()
+
+
+class TestViVn(unittest.TestCase):
+    """Tests date_time in the vi_VN locale"""
+
+    def setUp(self):
+        self.fake = Faker("vi_VN")
+        Faker.seed(0)
+
+    def test_day(self):
+        day = self.fake.day_of_week()
+        assert isinstance(day, str)
+        assert day in ViVNProvider.DAY_NAMES.values()
+
+    def test_month(self):
+        month = self.fake.month_name()
+        assert isinstance(month, str)
+        assert month in ViVNProvider.MONTH_NAMES.values()
diff --git a/tests/providers/test_job.py b/tests/providers/test_job.py
index eeb32704..607fbe3c 100644
--- a/tests/providers/test_job.py
+++ b/tests/providers/test_job.py
@@ -15,6 +15,7 @@ from faker.providers.job.ro_RO import Provider as RoRoJobProvider
 from faker.providers.job.sk_SK import Provider as SkSkJobProvider
 from faker.providers.job.th_TH import Provider as ThThJobProvider
 from faker.providers.job.tr_TR import Provider as TrTrJobProvider
+from faker.providers.job.vi_VN import Provider as ViVNJobProvider
 
 
 class TestJobProvider:
@@ -152,3 +153,13 @@ class TestRoRo:
 
     def test_job(self, faker, num_samples):
         assert faker.job() in RoRoJobProvider.jobs
+
+
+class TestViVn:
+    """Test vi_VN job provider"""
+
+    def test_job(self, faker, num_samples):
+        for _ in range(num_samples):
+            job = faker.job()
+            assert isinstance(job, str)
+            assert job in ViVNJobProvider.jobs
diff --git a/tests/providers/test_lorem.py b/tests/providers/test_lorem.py
index e3e0e0ff..eae23911 100644
--- a/tests/providers/test_lorem.py
+++ b/tests/providers/test_lorem.py
@@ -11,6 +11,7 @@ from faker.providers.lorem.en_US import Provider as EnUsLoremProvider
 from faker.providers.lorem.fa_IR import Provider as FaIrLoremProvider
 from faker.providers.lorem.nl_BE import Provider as NlBeLoremProvider
 from faker.providers.lorem.uk_UA import Provider as UkUaLoremProvider
+from faker.providers.lorem.vi_VN import Provider as ViVNLoremProvider
 
 
 class TestLoremProvider:
@@ -712,3 +713,72 @@ class TestUkUa:
         for _ in range(num_samples):
             words = faker.words(num_words)
             assert all(isinstance(word, str) and word in UkUaLoremProvider.word_list for word in words)
+
+
+class TestViVn:
+    """Test vi_VN lorem provider"""
+
+    word_list = [word.lower() for word in ViVNLoremProvider.word_list]
+
+    def test_paragraph(self, faker, num_samples):
+        num_sentences = 10
+        for _ in range(num_samples):
+            paragraph = faker.paragraph(nb_sentences=num_sentences)
+            assert isinstance(paragraph, str)
+            words = paragraph.replace(".", "").split()
+            assert all(word.lower() in self.word_list for word in words)
+
+    def test_paragraphs(self, faker, num_samples):
+        num_paragraphs = 5
+        for _ in range(num_samples):
+            paragraphs = faker.paragraphs(nb=num_paragraphs)
+            for paragraph in paragraphs:
+                assert isinstance(paragraph, str)
+                words = paragraph.replace(".", "").split()
+                assert all(word.lower() in self.word_list for word in words)
+
+    def test_sentence(self, faker, num_samples):
+        num_words = 10
+        for _ in range(num_samples):
+            sentence = faker.sentence(nb_words=num_words)
+            assert isinstance(sentence, str)
+            words = sentence.replace(".", "").split()
+            assert all(word.lower() in self.word_list for word in words)
+
+    def test_sentences(self, faker, num_samples):
+        num_sentences = 5
+        for _ in range(num_samples):
+            sentences = faker.sentences(nb=num_sentences)
+            for sentence in sentences:
+                assert isinstance(sentence, str)
+                words = sentence.replace(".", "").split()
+                assert all(word.lower() in self.word_list for word in words)
+
+    def test_text(self, faker, num_samples):
+        num_chars = 25
+        for _ in range(num_samples):
+            text = faker.text(max_nb_chars=num_chars)
+            assert isinstance(text, str)
+            words = re.sub(r"[.\n]+", " ", text).split()
+            assert all(word.lower() in self.word_list for word in words)
+
+    def test_texts(self, faker, num_samples):
+        num_texts = 5
+        num_chars = 25
+        for _ in range(num_samples):
+            texts = faker.texts(max_nb_chars=num_chars, nb_texts=num_texts)
+            for text in texts:
+                assert isinstance(text, str)
+                words = re.sub(r"[.\n]+", " ", text).split()
+                assert all(word.lower() in self.word_list for word in words)
+
+    def test_word(self, faker, num_samples):
+        for _ in range(num_samples):
+            word = faker.word()
+            assert isinstance(word, str) and word in ViVNLoremProvider.word_list
+
+    def test_words(self, faker, num_samples):
+        num_words = 5
+        for _ in range(num_samples):
+            words = faker.words(num_words)
+            assert all(isinstance(word, str) and word in ViVNLoremProvider.word_list for word in words)
diff --git a/tests/providers/test_person.py b/tests/providers/test_person.py
index 5cece79e..6cb915a4 100644
--- a/tests/providers/test_person.py
+++ b/tests/providers/test_person.py
@@ -12,6 +12,7 @@ from faker.providers.person.en import Provider as EnProvider
 from faker.providers.person.en_GB import Provider as EnGBProvider
 from faker.providers.person.en_IE import Provider as EnIEProvider
 from faker.providers.person.en_IN import Provider as EnINProvider
+from faker.providers.person.en_PK import Provider as EnPKprovider
 from faker.providers.person.en_US import Provider as EnUSProvider
 from faker.providers.person.es import Provider as EsProvider
 from faker.providers.person.es_CO import Provider as EsCOProvider
@@ -37,6 +38,7 @@ from faker.providers.person.ta_IN import Provider as TaINProvider
 from faker.providers.person.th_TH import Provider as ThThProvider
 from faker.providers.person.uk_UA import Provider as UkUAProvider
 from faker.providers.person.uk_UA import translit as UkUATranslit
+from faker.providers.person.vi_VN import Provider as ViVNProvider
 from faker.providers.person.yo_NG import Provider as YoNGProvider
 from faker.providers.person.zh_CN import Provider as ZhCNProvider
 from faker.providers.person.zh_TW import Provider as ZhTWProvider
@@ -159,12 +161,102 @@ class TestAzAz(unittest.TestCase):
         assert name in AzAzProvider.last_names_male
 
 
-class TestNlBE(unittest.TestCase):
-    """Tests person in the nl-BE locale"""
+class TestCsCZ(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("cs_CZ")
+        Faker.seed(0)
+
+    def test_name_male(self):
+        male_name = self.fake.name_male()
+        name_parts = male_name.split(" ")
+        first_name, last_name = "", ""
+        if len(name_parts) == 2:
+            first_name = name_parts[0]
+            last_name = name_parts[1]
+        elif len(name_parts) == 4:
+            first_name = name_parts[1]
+            last_name = name_parts[2]
+        elif len(name_parts) == 3:
+            if name_parts[-1] in CsCZProvider.suffixes:
+                first_name = name_parts[0]
+                last_name = name_parts[1]
+            else:
+                first_name = name_parts[1]
+                last_name = name_parts[2]
+        assert first_name in CsCZProvider.first_names_male
+        assert last_name in CsCZProvider.last_names_male
+
+    def test_name_female(self):
+        female_name = self.fake.name_female()
+        name_parts = female_name.split(" ")
+        first_name, last_name = "", ""
+        if len(name_parts) == 2:
+            first_name = name_parts[0]
+            last_name = name_parts[1]
+        elif len(name_parts) == 4:
+            first_name = name_parts[1]
+            last_name = name_parts[2]
+        elif len(name_parts) == 3:
+            if name_parts[-1] in CsCZProvider.suffixes:
+                first_name = name_parts[0]
+                last_name = name_parts[1]
+            else:
+                first_name = name_parts[1]
+                last_name = name_parts[2]
+        assert first_name in CsCZProvider.first_names_female
+        assert last_name in CsCZProvider.last_names_female
+
+
+class TestEn(unittest.TestCase):
+    """Tests person in the en locale"""
 
     def setUp(self):
-        self.fake = Faker("nl-BE")
-        self.provider = NlBEProvider
+        self.fake = Faker("en")
+        Faker.seed(0)
+
+    def test_suffix(self):
+        # Traditional suffix -- provider does not offer a nonbinary suffix at this time
+        suffix = self.fake.suffix()
+        self.assertIsInstance(suffix, str)
+        assert suffix in EnProvider.suffixes_male or suffix in EnProvider.suffixes_female
+
+
+class TestEnGB(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("en_GB")
+        Faker.seed(0)
+
+    def test_first_name_female(self):
+        name = self.fake.first_name_female()
+        assert name in EnGBProvider.first_names_female
+
+    def test_first_name_male(self):
+        name = self.fake.first_name_male()
+        assert name in EnGBProvider.first_names_male
+
+    def test_name_female(self):
+        full_name = self.fake.name_female()
+        first_name = self.get_first_name_from_full_name(full_name)
+        assert first_name in EnGBProvider.first_names_female
+
+    def test_name_male(self):
+        full_name = self.fake.name_male()
+        first_name = self.get_first_name_from_full_name(full_name)
+        assert first_name in EnGBProvider.first_names_male
+
+    def get_first_name_from_full_name(self, full_name):
+        names = full_name.split(" ")
+        if len(names) == 2:
+            return names[0]
+        return names[1]
+
+
+class TestEnIE(unittest.TestCase):
+    """Tests person in the en-IE locale"""
+
+    def setUp(self):
+        self.fake = Faker("en-ie")
+        self.provider = EnIEProvider
         Faker.seed(0)
 
     def test_first_name(self):
@@ -214,215 +306,190 @@ class TestNlBE(unittest.TestCase):
         assert name in self.provider.last_names
 
 
-class TestJaJP(unittest.TestCase):
-    """Tests person in the ja_JP locale"""
+class TestEnIN(unittest.TestCase):
+    """Tests person in the en_IN locale"""
 
     def setUp(self):
-        self.fake = Faker("ja")
+        self.fake = Faker("en_IN")
         Faker.seed(0)
 
-    def test_person(self):
-        name = self.fake.name()
-        assert name
-        assert isinstance(name, str)
-
-        first_name = self.fake.first_name()
-        assert first_name
-        assert isinstance(first_name, str)
-
-        last_name = self.fake.last_name()
-        assert last_name
-        assert isinstance(last_name, str)
-
-        kana_name = self.fake.kana_name()
-        assert kana_name
-        assert isinstance(kana_name, str)
-
-        first_kana_name = self.fake.first_kana_name()
-        assert first_kana_name
-        assert isinstance(first_kana_name, str)
-
-        first_kana_name_male = self.fake.first_kana_name_male()
-        assert first_kana_name_male
-        assert isinstance(first_kana_name_male, str)
+    def test_first_name(self):
+        """Verify that gender specific names are set correctly"""
 
-        first_kana_name_female = self.fake.first_kana_name_female()
-        assert first_kana_name_female
-        assert isinstance(first_kana_name_female, str)
+        name = self.fake.first_name_female()
+        assert name in EnINProvider.first_names_female
 
-        last_kana_name = self.fake.last_kana_name()
-        assert last_kana_name
-        assert isinstance(last_kana_name, str)
+        name = self.fake.first_name_male()
+        assert name in EnINProvider.first_names_male
 
-        romanized_name = self.fake.romanized_name()
-        assert romanized_name
-        assert isinstance(romanized_name, str)
+        first_name = self.fake.first_name()
+        assert first_name in EnINProvider.first_names
 
-        first_romanized_name = self.fake.first_romanized_name()
-        assert first_romanized_name
-        assert isinstance(first_romanized_name, str)
+    def test_last_name(self):
+        last_name = self.fake.last_name()
+        assert last_name in EnINProvider.last_names
 
-        first_romanized_name_male = self.fake.first_romanized_name_male()
-        assert first_romanized_name_male
-        assert isinstance(first_romanized_name_male, str)
 
-        first_romanized_name_female = self.fake.first_romanized_name_female()
-        assert first_romanized_name_female
-        assert isinstance(first_romanized_name_female, str)
+class TestEnPk(unittest.TestCase):
 
-        last_romanized_name = self.fake.last_romanized_name()
-        assert last_romanized_name
-        assert isinstance(last_romanized_name, str)
+    def setUp(self):
+        """Set up the Faker instance with the Pakistani locale."""
+        self.fake = Faker("en_PK")
 
-        first_name_pair = self.fake.first_name_pair()
-        assert first_name_pair
-        assert len(first_name_pair) == 3
-        assert all(s for s in first_name_pair if isinstance(s, str))
+    def test_first_name(self):
+        """Test if the first name is from the predefined list."""
+        first_name = self.fake.first_name()
+        self.assertIn(first_name, EnPKprovider.first_names)
 
-        first_name_male_pair = self.fake.first_name_male_pair()
-        assert first_name_male_pair
-        assert len(first_name_male_pair) == 3
-        assert all(s for s in first_name_male_pair if isinstance(s, str))
+    def test_last_name(self):
+        """Test if the last name is from the predefined list."""
+        last_name = self.fake.last_name()
+        self.assertIn(last_name, EnPKprovider.last_names)
 
-        first_name_female_pair = self.fake.first_name_female_pair()
-        assert first_name_female_pair
-        assert len(first_name_female_pair) == 3
-        assert all(isinstance(s, str) for s in first_name_female_pair)
+    def test_full_name(self):
+        """Test if the generated full name follows the correct format."""
+        full_name = self.fake.name()
+        name_parts = full_name.split()
+        self.assertIn(name_parts[0], EnPKprovider.first_names)
+        self.assertIn(name_parts[-1], EnPKprovider.last_names)
+
+    def test_name_format(self):
+        """Test if the generated name format is as expected."""
+        name = self.fake.name()
+        name_parts = name.split()
+        self.assertGreaterEqual(len(name_parts), 2, "Full name should have at least a first and last name.")
+        self.assertIn(name_parts[0], EnPKprovider.first_names)
+        self.assertIn(name_parts[-1], EnPKprovider.last_names)
 
-        last_name_pair = self.fake.last_name_pair()
-        assert last_name_pair
-        assert len(last_name_pair) == 3
-        assert all(isinstance(s, str) for s in last_name_pair)
 
+class TestEnUS(unittest.TestCase):
+    """Tests person in the en_US locale"""
 
-class TestLvLV(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("lv_LV")
+        self.fake = Faker("en_US")
         Faker.seed(0)
 
-    def test_first_name(self):
+    def test_first_names(self):
         # General first name
         name = self.fake.first_name()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in LvProvider.first_names
+        assert name in EnUSProvider.first_names
 
-        # Females first name
+        # Female first name
         name = self.fake.first_name_female()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in LvProvider.first_names
-        assert name in LvProvider.first_names_female
+        assert name in EnUSProvider.first_names
+        assert name in EnUSProvider.first_names_female
 
         # Male first name
         name = self.fake.first_name_male()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in LvProvider.first_names
-        assert name in LvProvider.first_names_male
+        assert name in EnUSProvider.first_names
+        assert name in EnUSProvider.first_names_male
 
-    def test_last_name(self):
-        # General last name.
-        name = self.fake.last_name()
-        assert name
+        # Nonbinary first name
+        name = self.fake.first_name_nonbinary()
         self.assertIsInstance(name, str)
-        assert name in LvProvider.last_names
+        assert name in EnUSProvider.first_names
+        assert name in EnUSProvider.first_names_nonbinary
 
-        # Females last name.
-        name = self.fake.last_name_female()
-        assert name
+    def test_last_names(self):
+        # General last name
+        name = self.fake.last_name()
         self.assertIsInstance(name, str)
-        assert name in LvProvider.last_names_female + LvProvider.last_names_nonbinary
+        assert name in EnUSProvider.last_names
 
-        # Females only last name.
+        # Female last name
         name = self.fake.last_name_female()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in LvProvider.last_names_female
+        assert name in EnUSProvider.last_names
 
-        # Male last name.
+        # Male last name
         name = self.fake.last_name_male()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in LvProvider.last_names_male + LvProvider.last_names_nonbinary
+        assert name in EnUSProvider.last_names
 
-        # Male only last name.
-        name = self.fake.last_name_male()
-        assert name
+        # Nonbinary last name
+        name = self.fake.last_name_nonbinary()
         self.assertIsInstance(name, str)
-        assert name in LvProvider.last_names_male
+        assert name in EnUSProvider.last_names
+
+    def test_prefix(self):
+        # Nonbinary prefix
+        prefix = self.fake.prefix_nonbinary()
+        self.assertIsInstance(prefix, str)
+        assert prefix in EnUSProvider.prefixes_nonbinary
+
+    def test_suffix(self):
+        # Nonbinary suffix
+        suffix = self.fake.suffix_nonbinary()
+        self.assertIsInstance(suffix, str)
+        assert suffix in EnUSProvider.suffixes_nonbinary
 
 
-class TestNeNP(unittest.TestCase):
+class TestEs(unittest.TestCase):
+    """Tests person in the es locale."""
+
     def setUp(self):
-        self.fake = Faker("ne_NP")
+        self.fake = Faker("es")
         Faker.seed(0)
 
-    def test_names(self):
-        name = self.fake.name().split()
-        assert all(isinstance(n, str) for n in name)
-        # name should always be 2-3 words. If 3, first word
-        # should be a prefix.
-        assert name[-2] in NeProvider.first_names
-        assert name[-1] in NeProvider.last_names
-        prefixes = NeProvider.prefixes_male + NeProvider.prefixes_female
-        if len(name) == 3:
-            assert name[0] in prefixes
+    def test_language_name(self):
+        language_name = self.fake.language_name()
+        assert language_name in EsProvider.language_names
 
 
-class TestFrBE(unittest.TestCase):
-    """Tests person in the fr-BE locale"""
+class TestEsCO(unittest.TestCase):
+    """Tests person in the es_CO locale"""
 
     def setUp(self):
-        self.fake = Faker("fr-BE")
-        self.provider = FrBEProvider
+        self.fake = Faker("es_CO")
         Faker.seed(0)
 
-    def test_first_name(self):
+    def test_first_names(self):
         # General first name
         name = self.fake.first_name()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
+        assert name in EsCOProvider.first_names
 
-        # Females first name
+        # Female first name
         name = self.fake.first_name_female()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
-        assert name in self.provider.first_names_female
+        assert name in EsCOProvider.first_names
+        assert name in EsCOProvider.first_names_female
 
         # Male first name
         name = self.fake.first_name_male()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
-        assert name in self.provider.first_names_male
-
-    def test_last_name(self):
-        assert not hasattr(self.provider, "last_names_male")
-        assert not hasattr(self.provider, "last_names_female")
-        # All last names apply for all genders.
-        assert hasattr(self.provider, "last_names")
+        assert name in EsCOProvider.first_names
+        assert name in EsCOProvider.first_names_male
 
-        # General last name.
+    def test_last_names(self):
+        # General last name
         name = self.fake.last_name()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
+        assert name in EsCOProvider.last_names
 
-        # Females last name.
+        # Female last name
         name = self.fake.last_name_female()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
-        assert name in self.provider.last_names
+        assert name in EsCOProvider.last_names
 
-        # Male last name.
+        # Male last name
         name = self.fake.last_name_male()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
+        assert name in EsCOProvider.last_names
+
+    def test_prefix(self):
+        # Female prefix
+        prefix = self.fake.prefix_female()
+        self.assertIsInstance(prefix, str)
+        assert prefix in EsCOProvider.prefixes_female
+
+        # Male prefix
+        prefix = self.fake.prefix_male()
+        self.assertIsInstance(prefix, str)
+        assert prefix in EsCOProvider.prefixes_male
 
 
 class TestEtEE(unittest.TestCase):
@@ -542,622 +609,495 @@ class TestFiFI(unittest.TestCase):
         assert last_name in FiProvider.last_names
 
 
-class TestSvSE(unittest.TestCase):
+class TestFrBE(unittest.TestCase):
+    """Tests person in the fr-BE locale"""
+
     def setUp(self):
-        self.fake = Faker("sv_SE")
+        self.fake = Faker("fr-BE")
+        self.provider = FrBEProvider
         Faker.seed(0)
 
-    def test_gender_first_names(self):
-        """simple test to verify that we are pulling gender specific names"""
+    def test_first_name(self):
+        # General first name
+        name = self.fake.first_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.first_names
+
+        # Females first name
         name = self.fake.first_name_female()
-        assert name in SvSEProvider.first_names_female
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.first_names
+        assert name in self.provider.first_names_female
+
+        # Male first name
         name = self.fake.first_name_male()
-        assert name in SvSEProvider.first_names_male
-        name = self.fake.first_name()
-        assert name in SvSEProvider.first_names
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.first_names
+        assert name in self.provider.first_names_male
 
+    def test_last_name(self):
+        assert not hasattr(self.provider, "last_names_male")
+        assert not hasattr(self.provider, "last_names_female")
+        # All last names apply for all genders.
+        assert hasattr(self.provider, "last_names")
 
-class TestPlPL(unittest.TestCase):
-    def setUp(self):
-        self.fake = Faker("pl_PL")
-        Faker.seed(0)
+        # General last name.
+        name = self.fake.last_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.last_names
 
-    def test_identity_card_number_checksum(self):
-        assert pl_checksum_identity_card_number(["A", "I", "S", 8, 5, 0, 2, 1, 4]) == 8
-        assert pl_checksum_identity_card_number(["A", "U", "L", 9, 2, 7, 2, 8, 5]) == 9
-        assert pl_checksum_identity_card_number(["A", "E", "I", 2, 5, 1, 8, 2, 4]) == 2
-        assert pl_checksum_identity_card_number(["A", "H", "F", 2, 2, 0, 6, 8, 0]) == 2
-        assert pl_checksum_identity_card_number(["A", "X", "E", 8, 2, 0, 3, 4, 0]) == 8
+        # Females last name.
+        name = self.fake.last_name_female()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.last_names
+        assert name in self.provider.last_names
 
-    def test_identity_card_number(self):
-        for _ in range(100):
-            assert re.search(r"^[A-Z]{3}\d{6}$", self.fake.identity_card_number())
+        # Male last name.
+        name = self.fake.last_name_male()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in self.provider.last_names
 
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pesel_birth_date(self, mock_random_digit):
-        mock_random_digit.side_effect = [
-            3,
-            5,
-            8,
-            8,
-            3,
-            5,
-            8,
-            8,
-            7,
-            9,
-            9,
-            3,
-            7,
-            9,
-            9,
-            3,
-            7,
-            9,
-            9,
-            3,
-        ]
-        assert self.fake.pesel(datetime.date(1899, 12, 31)) == "99923135889"
-        assert self.fake.pesel(datetime.date(1999, 12, 31)) == "99123135885"
-        assert self.fake.pesel(datetime.date(2000, 1, 1)) == "00210179936"
-        assert self.fake.pesel(datetime.date(2100, 1, 1)) == "00410179932"
-        assert self.fake.pesel(datetime.date(2200, 1, 1)) == "00610179938"
 
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pesel_sex_male(self, mock_random_digit):
-        mock_random_digit.side_effect = [1, 3, 4, 5, 6, 1, 7, 0]
-        assert self.fake.pesel(datetime.date(1909, 3, 3), "M") == "09030313454"
-        assert self.fake.pesel(datetime.date(1913, 8, 16), "M") == "13081661718"
+class TestGaIE(TestEnIE):
+    """Tests person in the ga-IE locale"""
 
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pesel_sex_female(self, mock_random_digit):
-        mock_random_digit.side_effect = [4, 9, 1, 6, 6, 1, 7, 3]
-        assert self.fake.pesel(datetime.date(2007, 4, 13), "F") == "07241349161"
-        assert self.fake.pesel(datetime.date(1933, 12, 16), "F") == "33121661744"
+    def setUp(self):
+        self.fake = Faker("ga-ie")
+        self.provider = GaIEProvider
+        Faker.seed(0)
 
-    def test_pesel_value_error(self):
-        self.assertRaises(ValueError, self.fake.pesel, datetime.date(2300, 1, 1))
-        self.assertRaises(ValueError, self.fake.pesel, datetime.date(1799, 12, 31))
 
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pwz_doctor(self, mock_random_digit):
-        mock_random_digit.side_effect = [6, 9, 1, 9, 6, 5, 2, 7, 9, 9, 1, 5]
-        assert self.fake.pwz_doctor() == "2691965"
-        assert self.fake.pwz_doctor() == "4279915"
+class TestHeIL(unittest.TestCase):
+    """Tests person in the he_IL locale."""
 
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pwz_doctor_check_digit_zero(self, mock_random_digit):
-        mock_random_digit.side_effect = [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 9, 9]
-        assert self.fake.pwz_doctor() == "6000012"
-        assert self.fake.pwz_doctor() == "1000090"
+    def setUp(self):
+        self.fake = Faker("he_IL")
+        Faker.seed(0)
 
-    @mock.patch.object(PlPLProvider, "random_int")
-    @mock.patch.object(PlPLProvider, "random_digit")
-    def test_pwz_nurse(self, mock_random_digit, mock_random_int):
-        mock_random_digit.side_effect = [3, 4, 5, 6, 7, 1, 7, 5, 1, 2]
-        mock_random_int.side_effect = [45, 3]
-        assert self.fake.pwz_nurse(kind="nurse") == "4534567P"
-        assert self.fake.pwz_nurse(kind="midwife") == "0317512A"
+    def test_language_name(self):
+        language_name = self.fake.language_name()
+        assert language_name in HeILProvider.language_names
 
-    @staticmethod
-    def validate_nip(nip_str):
-        """
-        Validates NIP using recommended code
-        https://pl.wikibooks.org/wiki/Kody_%C5%BAr%C3%B3d%C5%82owe/Implementacja_NIP
-        """
-        nip_str = nip_str.replace("-", "")
-        if len(nip_str) != 10 or not nip_str.isdigit():
-            return False
-        digits = [int(i) for i in nip_str]
-        weights = (6, 5, 7, 2, 3, 4, 5, 6, 7)
-        check_sum = sum(d * w for d, w in zip(digits, weights)) % 11
-        return check_sum == digits[9]
+    def test_male_first_name(self):
+        first_name_male = self.fake.first_name_male()
+        assert first_name_male in HeILProvider.first_names_male
 
-    def test_nip(self):
-        for _ in range(100):
-            assert self.validate_nip(self.fake.nip())
+    def test_female_first_name(self):
+        first_name_female = self.fake.first_name_female()
+        assert first_name_female in HeILProvider.first_names_female
 
+    def test_last_name(self):
+        last_name = self.fake.last_name()
+        assert last_name in HeILProvider.last_names
+
+
+class TestHyAM(unittest.TestCase):
+    """Tests person in the hy_AM locale"""
 
-class TestCsCZ(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("cs_CZ")
+        self.fake = Faker("hy_AM")
         Faker.seed(0)
 
-    def test_name_male(self):
-        male_name = self.fake.name_male()
-        name_parts = male_name.split(" ")
-        first_name, last_name = "", ""
-        if len(name_parts) == 2:
-            first_name = name_parts[0]
-            last_name = name_parts[1]
-        elif len(name_parts) == 4:
-            first_name = name_parts[1]
-            last_name = name_parts[2]
-        elif len(name_parts) == 3:
-            if name_parts[-1] in CsCZProvider.suffixes:
-                first_name = name_parts[0]
-                last_name = name_parts[1]
-            else:
-                first_name = name_parts[1]
-                last_name = name_parts[2]
-        assert first_name in CsCZProvider.first_names_male
-        assert last_name in CsCZProvider.last_names_male
-
-    def test_name_female(self):
-        female_name = self.fake.name_female()
-        name_parts = female_name.split(" ")
-        first_name, last_name = "", ""
-        if len(name_parts) == 2:
-            first_name = name_parts[0]
-            last_name = name_parts[1]
-        elif len(name_parts) == 4:
-            first_name = name_parts[1]
-            last_name = name_parts[2]
-        elif len(name_parts) == 3:
-            if name_parts[-1] in CsCZProvider.suffixes:
-                first_name = name_parts[0]
-                last_name = name_parts[1]
-            else:
-                first_name = name_parts[1]
-                last_name = name_parts[2]
-        assert first_name in CsCZProvider.first_names_female
-        assert last_name in CsCZProvider.last_names_female
-
-
-class TestSkSK(unittest.TestCase):
-    def setUp(self):
-        self.fake = Faker("sk_SK")
-        Faker.seed(0)
-
-    def test_name_male(self):
-        male_name = self.fake.name_male()
-        name_parts = male_name.split(" ")
-        first_name, last_name = "", ""
-        if len(name_parts) == 2:
-            first_name = name_parts[0]
-            last_name = name_parts[1]
-        elif len(name_parts) == 4:
-            first_name = name_parts[1]
-            last_name = name_parts[2]
-        elif len(name_parts) == 3:
-            if name_parts[-1] in SkSKProvider.suffixes:
-                first_name = name_parts[0]
-                last_name = name_parts[1]
-            else:
-                first_name = name_parts[1]
-                last_name = name_parts[2]
-        assert first_name in SkSKProvider.first_names_male
-        assert last_name in SkSKProvider.last_names_male
-
-    def test_name_female(self):
-        female_name = self.fake.name_female()
-        name_parts = female_name.split(" ")
-        first_name, last_name = "", ""
-        if len(name_parts) == 2:
-            first_name = name_parts[0]
-            last_name = name_parts[1]
-        elif len(name_parts) == 4:
-            first_name = name_parts[1]
-            last_name = name_parts[2]
-        elif len(name_parts) == 3:
-            if name_parts[-1] in SkSKProvider.suffixes:
-                first_name = name_parts[0]
-                last_name = name_parts[1]
-            else:
-                first_name = name_parts[1]
-                last_name = name_parts[2]
-        assert first_name in SkSKProvider.first_names_female
-        assert last_name in SkSKProvider.last_names_female
-
+    def test_name(self):
+        # General name
+        name = self.fake.name()
+        self.assertIsInstance(name, str)
 
-class TestThTh(unittest.TestCase):
-    """Tests person in the th_TH locale"""
+        # Female name
+        name = self.fake.name_female()
+        self.assertIsInstance(name, str)
 
-    def setUp(self):
-        self.fake = Faker("th_TH")
-        Faker.seed(0)
+        # Male name
+        name = self.fake.name_male()
+        self.assertIsInstance(name, str)
 
     def test_first_name(self):
         # General first name
         name = self.fake.first_name()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in ThThProvider.first_names
-
-    def test_last_name(self):
-        # There's no gender-specific last name in Thai.
-        assert not hasattr(ThThProvider, "last_names_male")
-        assert not hasattr(ThThProvider, "last_names_female")
-        # All last names apply for all genders.
-        assert hasattr(ThThProvider, "last_names")
+        assert name in HyAmProvider.first_names
 
-        # General last name.
-        name = self.fake.last_name()
-        assert name
+        # Female first name
+        name = self.fake.first_name_female()
         self.assertIsInstance(name, str)
-        assert name in ThThProvider.last_names
+        assert name in HyAmProvider.first_names
+        assert name in HyAmProvider.first_names_female
 
-    def test_name(self):
-        # Full name
-        name = self.fake.name()
-        assert name
+        # Male first name
+        name = self.fake.first_name_male()
         self.assertIsInstance(name, str)
-
-
-class TestZhCN(unittest.TestCase):
-    def setUp(self):
-        self.fake = Faker("zh_CN")
-        Faker.seed(0)
+        assert name in HyAmProvider.first_names
+        assert name in HyAmProvider.first_names_male
 
     def test_last_name(self):
-        # There's no gender-specific last name in Chinese.
-        assert not hasattr(ZhCNProvider, "last_names_male")
-        assert not hasattr(ZhCNProvider, "last_names_female")
-        assert not hasattr(ZhCNProvider, "last_romanized_names_male")
-        assert not hasattr(ZhCNProvider, "last_romanized_names_female")
+        # There's no gender-specific last name in Armenian.
+        assert not hasattr(HyAmProvider, "last_names_male")
+        assert not hasattr(HyAmProvider, "last_names_female")
         # All last names apply for all genders.
-        assert hasattr(ZhCNProvider, "last_names")
+        assert hasattr(HyAmProvider, "last_names")
 
         # General last name.
         name = self.fake.last_name()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.last_names
+        assert name in HyAmProvider.last_names
 
         # Females last name.
         name = self.fake.last_name_female()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.last_names
+        assert name in HyAmProvider.last_names
 
         # Male last name.
         name = self.fake.last_name_male()
-        assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.last_names
+        assert name in HyAmProvider.last_names
 
-        # General last romanized name
-        name = self.fake.last_romanized_name()
+
+class TestJaJP(unittest.TestCase):
+    """Tests person in the ja_JP locale"""
+
+    def setUp(self):
+        self.fake = Faker("ja")
+        Faker.seed(0)
+
+    def test_person(self):
+        name = self.fake.name()
         assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.last_romanized_names
+        assert isinstance(name, str)
+
+        first_name = self.fake.first_name()
+        assert first_name
+        assert isinstance(first_name, str)
+
+        last_name = self.fake.last_name()
+        assert last_name
+        assert isinstance(last_name, str)
+
+        kana_name = self.fake.kana_name()
+        assert kana_name
+        assert isinstance(kana_name, str)
+
+        first_kana_name = self.fake.first_kana_name()
+        assert first_kana_name
+        assert isinstance(first_kana_name, str)
+
+        first_kana_name_male = self.fake.first_kana_name_male()
+        assert first_kana_name_male
+        assert isinstance(first_kana_name_male, str)
+
+        first_kana_name_female = self.fake.first_kana_name_female()
+        assert first_kana_name_female
+        assert isinstance(first_kana_name_female, str)
+
+        last_kana_name = self.fake.last_kana_name()
+        assert last_kana_name
+        assert isinstance(last_kana_name, str)
+
+        romanized_name = self.fake.romanized_name()
+        assert romanized_name
+        assert isinstance(romanized_name, str)
+
+        first_romanized_name = self.fake.first_romanized_name()
+        assert first_romanized_name
+        assert isinstance(first_romanized_name, str)
+
+        first_romanized_name_male = self.fake.first_romanized_name_male()
+        assert first_romanized_name_male
+        assert isinstance(first_romanized_name_male, str)
+
+        first_romanized_name_female = self.fake.first_romanized_name_female()
+        assert first_romanized_name_female
+        assert isinstance(first_romanized_name_female, str)
+
+        last_romanized_name = self.fake.last_romanized_name()
+        assert last_romanized_name
+        assert isinstance(last_romanized_name, str)
+
+        first_name_pair = self.fake.first_name_pair()
+        assert first_name_pair
+        assert len(first_name_pair) == 3
+        assert all(s for s in first_name_pair if isinstance(s, str))
+
+        first_name_male_pair = self.fake.first_name_male_pair()
+        assert first_name_male_pair
+        assert len(first_name_male_pair) == 3
+        assert all(s for s in first_name_male_pair if isinstance(s, str))
+
+        first_name_female_pair = self.fake.first_name_female_pair()
+        assert first_name_female_pair
+        assert len(first_name_female_pair) == 3
+        assert all(isinstance(s, str) for s in first_name_female_pair)
+
+        last_name_pair = self.fake.last_name_pair()
+        assert last_name_pair
+        assert len(last_name_pair) == 3
+        assert all(isinstance(s, str) for s in last_name_pair)
+
+
+class TestLvLV(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("lv_LV")
+        Faker.seed(0)
 
     def test_first_name(self):
         # General first name
         name = self.fake.first_name()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.first_names
+        assert name in LvProvider.first_names
 
         # Females first name
         name = self.fake.first_name_female()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.first_names
-        assert name in ZhCNProvider.first_names_female
+        assert name in LvProvider.first_names
+        assert name in LvProvider.first_names_female
 
         # Male first name
         name = self.fake.first_name_male()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.first_names
-        assert name in ZhCNProvider.first_names_male
+        assert name in LvProvider.first_names
+        assert name in LvProvider.first_names_male
 
-        # General first romanized name
-        name = self.fake.first_romanized_name()
+    def test_last_name(self):
+        # General last name.
+        name = self.fake.last_name()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhCNProvider.first_romanized_names
+        assert name in LvProvider.last_names
 
-    def test_name(self):
-        # Full name
-        name = self.fake.name()
+        # Females last name.
+        name = self.fake.last_name_female()
         assert name
         self.assertIsInstance(name, str)
-        assert name[0] in ZhCNProvider.last_names or name[:2] in ZhCNProvider.last_names
-        assert name[1:] in ZhCNProvider.first_names or name[2:] in ZhCNProvider.first_names
+        assert name in LvProvider.last_names_female + LvProvider.last_names_nonbinary
 
-        # Full romanized name
-        name = self.fake.romanized_name()
+        # Females only last name.
+        name = self.fake.last_name_female()
         assert name
         self.assertIsInstance(name, str)
-        first_romanized_name, last_romanized_name = name.split(" ")
-        assert first_romanized_name in ZhCNProvider.first_romanized_names
-        assert last_romanized_name in ZhCNProvider.last_romanized_names
-
-
-class TestZhTW(unittest.TestCase):
-    def setUp(self):
-        self.fake = Faker("zh_TW")
-        Faker.seed(0)
-
-    def test_last_name(self):
-        # There's no gender-specific last name in Chinese.
-        assert not hasattr(ZhTWProvider, "last_names_male")
-        assert not hasattr(ZhTWProvider, "last_names_female")
-        assert not hasattr(ZhTWProvider, "last_romanized_names_male")
-        assert not hasattr(ZhTWProvider, "last_romanized_names_female")
-        # All last names apply for all genders.
-        assert hasattr(ZhTWProvider, "last_names")
-
-        # General last name.
-        name = self.fake.last_name()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.last_names
-
-        # Females last name.
-        name = self.fake.last_name_female()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.last_names
+        assert name in LvProvider.last_names_female
 
         # Male last name.
         name = self.fake.last_name_male()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.last_names
-
-        # General last romanized name
-        name = self.fake.last_romanized_name()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.last_romanized_names
-
-    def test_first_name(self):
-        # General first name
-        name = self.fake.first_name()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.first_names
-
-        # Females first name
-        name = self.fake.first_name_female()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.first_names
-        assert name in ZhTWProvider.first_names_female
+        assert name in LvProvider.last_names_male + LvProvider.last_names_nonbinary
 
-        # Male first name
-        name = self.fake.first_name_male()
+        # Male only last name.
+        name = self.fake.last_name_male()
         assert name
         self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.first_names
-        assert name in ZhTWProvider.first_names_male
+        assert name in LvProvider.last_names_male
 
-        # General first romanized name
-        name = self.fake.first_romanized_name()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in ZhTWProvider.first_romanized_names
 
-    def test_name(self):
-        # Full name
-        name = self.fake.name()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name[0] in ZhTWProvider.last_names or name[:2] in ZhTWProvider.last_names
-        assert name[1:] in ZhTWProvider.first_names or name[2:] in ZhTWProvider.first_names
+class TestNeNP(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("ne_NP")
+        Faker.seed(0)
 
-        # Full romanized name
-        name = self.fake.romanized_name()
-        assert name
-        self.assertIsInstance(name, str)
-        first_romanized_name, last_romanized_name = name.split(" ")
-        assert first_romanized_name in ZhTWProvider.first_romanized_names
-        assert last_romanized_name in ZhTWProvider.last_romanized_names
+    def test_names(self):
+        name = self.fake.name().split()
+        assert all(isinstance(n, str) for n in name)
+        # name should always be 2-3 words. If 3, first word
+        # should be a prefix.
+        assert name[-2] in NeProvider.first_names
+        assert name[-1] in NeProvider.last_names
+        prefixes = NeProvider.prefixes_male + NeProvider.prefixes_female
+        if len(name) == 3:
+            assert name[0] in prefixes
 
 
-class TestHyAM(unittest.TestCase):
-    """Tests person in the hy_AM locale"""
+class TestNlBE(unittest.TestCase):
+    """Tests person in the nl-BE locale"""
 
     def setUp(self):
-        self.fake = Faker("hy_AM")
+        self.fake = Faker("nl-BE")
+        self.provider = NlBEProvider
         Faker.seed(0)
 
-    def test_name(self):
-        # General name
-        name = self.fake.name()
-        self.assertIsInstance(name, str)
-
-        # Female name
-        name = self.fake.name_female()
-        self.assertIsInstance(name, str)
-
-        # Male name
-        name = self.fake.name_male()
-        self.assertIsInstance(name, str)
-
     def test_first_name(self):
         # General first name
         name = self.fake.first_name()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.first_names
+        assert name in self.provider.first_names
 
-        # Female first name
+        # Females first name
         name = self.fake.first_name_female()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.first_names
-        assert name in HyAmProvider.first_names_female
+        assert name in self.provider.first_names
+        assert name in self.provider.first_names_female
 
         # Male first name
         name = self.fake.first_name_male()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.first_names
-        assert name in HyAmProvider.first_names_male
+        assert name in self.provider.first_names
+        assert name in self.provider.first_names_male
 
     def test_last_name(self):
-        # There's no gender-specific last name in Armenian.
-        assert not hasattr(HyAmProvider, "last_names_male")
-        assert not hasattr(HyAmProvider, "last_names_female")
+        assert not hasattr(self.provider, "last_names_male")
+        assert not hasattr(self.provider, "last_names_female")
         # All last names apply for all genders.
-        assert hasattr(HyAmProvider, "last_names")
+        assert hasattr(self.provider, "last_names")
 
         # General last name.
         name = self.fake.last_name()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.last_names
+        assert name in self.provider.last_names
 
         # Females last name.
         name = self.fake.last_name_female()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.last_names
+        assert name in self.provider.last_names
+        assert name in self.provider.last_names
 
         # Male last name.
         name = self.fake.last_name_male()
+        assert name
         self.assertIsInstance(name, str)
-        assert name in HyAmProvider.last_names
+        assert name in self.provider.last_names
 
 
-class TestTaIN(unittest.TestCase):
+class TestOrIN(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("ta_IN")
+        self.fake = Faker("or_IN")
         Faker.seed(0)
 
-    def test_gender_first_names(self):
+    def test_first_names(self):
         """simple test to verify that we are pulling gender specific names"""
         name = self.fake.first_name_female()
-        assert name in TaINProvider.first_names_female
+        assert name in OrINProvider.first_names_female
+
         name = self.fake.first_name_male()
-        assert name in TaINProvider.first_names_male
+        assert name in OrINProvider.first_names_male
+
+        name = self.fake.first_name_unisex()
+        assert name in OrINProvider.first_names_unisex
+
         name = self.fake.first_name()
-        assert name in TaINProvider.first_names
+        assert name in OrINProvider.first_names
+
+    def test_middle_names(self):
+        """test the middle name"""
+        name = self.fake.middle_name()
+        assert name in OrINProvider.middle_names
 
+    def test_last_names(self):
+        """test the last name is generating from the provided tuple"""
+        last_name = self.fake.last_name()
+        assert last_name in OrINProvider.last_names
 
-class TestRuRU(unittest.TestCase):
-    """Tests person in the ru_RU locale"""
 
+class TestPlPL(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("ru_RU")
+        self.fake = Faker("pl_PL")
         Faker.seed(0)
 
-    def test_translit(self):
-        assert translit("Александр Сергеевич Пушкин") == "Aleksandr Sergeevich Pushkin"
-        assert translit("Анна Андреевна Ахматова") == "Anna Andreevna Akhmatova"
-        assert translit("Михаил") == "Mikhail"
-        assert translit("Фёдор") == "Fedor"
-        assert translit("Екатерина") == "Yekaterina"
-        assert translit("Анастасия") == "Anastasiya"
-        assert translit("Юрьевич") == "Yurevich"
-        assert translit("Никитична") == "Nikitichna"
-        assert translit("Щербакова") == "Shcherbakova"
-        assert translit("Маяковский") == "Mayakovskiy"
-        assert translit("Петров-Водкин") == "Petrov-Vodkin"
-        assert translit("Воронцова-Дашкова") == "Vorontsova-Dashkova"
-        assert translit("А.С.Пушкин") == "A.S.Pushkin"
-        assert translit("А. С. Пушкин") == "A. S. Pushkin"
-        assert translit("тов. И.И.Сидоров") == "tov. I.I.Sidorov"
-        assert translit("г-н А.Б.Петров") == "g-n A.B.Petrov"
-        assert translit("г-жа Ю.М.Петрова") == "g-zha Yu.M.Petrova"
+    def test_identity_card_number_checksum(self):
+        assert pl_checksum_identity_card_number(["A", "I", "S", 8, 5, 0, 2, 1, 4]) == 8
+        assert pl_checksum_identity_card_number(["A", "U", "L", 9, 2, 7, 2, 8, 5]) == 9
+        assert pl_checksum_identity_card_number(["A", "E", "I", 2, 5, 1, 8, 2, 4]) == 2
+        assert pl_checksum_identity_card_number(["A", "H", "F", 2, 2, 0, 6, 8, 0]) == 2
+        assert pl_checksum_identity_card_number(["A", "X", "E", 8, 2, 0, 3, 4, 0]) == 8
 
-    def test_name_female(self):
-        first_name = self.fake.first_name_female()
-        assert first_name in RuProvider.first_names_female
-        middle_name = self.fake.middle_name_female()
-        assert middle_name in RuProvider.middle_names_female
-        last_name = self.fake.last_name_female()
-        assert last_name in RuProvider.last_names_female
+    def test_identity_card_number(self):
+        for _ in range(100):
+            assert re.search(r"^[A-Z]{3}\d{6}$", self.fake.identity_card_number())
 
-    def test_name_male(self):
-        first_name = self.fake.first_name_male()
-        assert first_name in RuProvider.first_names_male
-        middle_name = self.fake.middle_name_male()
-        assert middle_name in RuProvider.middle_names_male
-        last_name = self.fake.last_name_male()
-        assert last_name in RuProvider.last_names_male
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pesel_birth_date(self, mock_random_digit):
+        mock_random_digit.side_effect = [
+            3,
+            5,
+            8,
+            8,
+            3,
+            5,
+            8,
+            8,
+            7,
+            9,
+            9,
+            3,
+            7,
+            9,
+            9,
+            3,
+            7,
+            9,
+            9,
+            3,
+        ]
+        assert self.fake.pesel(datetime.date(1899, 12, 31)) == "99923135889"
+        assert self.fake.pesel(datetime.date(1999, 12, 31)) == "99123135885"
+        assert self.fake.pesel(datetime.date(2000, 1, 1)) == "00210179936"
+        assert self.fake.pesel(datetime.date(2100, 1, 1)) == "00410179932"
+        assert self.fake.pesel(datetime.date(2200, 1, 1)) == "00610179938"
 
-    def test_language_name(self):
-        language_name = self.fake.language_name()
-        assert language_name in RuProvider.language_names
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pesel_sex_male(self, mock_random_digit):
+        mock_random_digit.side_effect = [1, 3, 4, 5, 6, 1, 7, 0]
+        assert self.fake.pesel(datetime.date(1909, 3, 3), "M") == "09030313454"
+        assert self.fake.pesel(datetime.date(1913, 8, 16), "M") == "13081661718"
 
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pesel_sex_female(self, mock_random_digit):
+        mock_random_digit.side_effect = [4, 9, 1, 6, 6, 1, 7, 3]
+        assert self.fake.pesel(datetime.date(2007, 4, 13), "F") == "07241349161"
+        assert self.fake.pesel(datetime.date(1933, 12, 16), "F") == "33121661744"
 
-class TestEs(unittest.TestCase):
-    """Tests person in the es locale."""
-
-    def setUp(self):
-        self.fake = Faker("es")
-        Faker.seed(0)
-
-    def test_language_name(self):
-        language_name = self.fake.language_name()
-        assert language_name in EsProvider.language_names
-
-
-class TestEsCO(unittest.TestCase):
-    """Tests person in the es_CO locale"""
-
-    def setUp(self):
-        self.fake = Faker("es_CO")
-        Faker.seed(0)
-
-    def test_first_names(self):
-        # General first name
-        name = self.fake.first_name()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.first_names
-
-        # Female first name
-        name = self.fake.first_name_female()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.first_names
-        assert name in EsCOProvider.first_names_female
-
-        # Male first name
-        name = self.fake.first_name_male()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.first_names
-        assert name in EsCOProvider.first_names_male
-
-    def test_last_names(self):
-        # General last name
-        name = self.fake.last_name()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.last_names
-
-        # Female last name
-        name = self.fake.last_name_female()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.last_names
-
-        # Male last name
-        name = self.fake.last_name_male()
-        self.assertIsInstance(name, str)
-        assert name in EsCOProvider.last_names
-
-    def test_prefix(self):
-        # Female prefix
-        prefix = self.fake.prefix_female()
-        self.assertIsInstance(prefix, str)
-        assert prefix in EsCOProvider.prefixes_female
-
-        # Male prefix
-        prefix = self.fake.prefix_male()
-        self.assertIsInstance(prefix, str)
-        assert prefix in EsCOProvider.prefixes_male
-
-
-class TestHeIL(unittest.TestCase):
-    """Tests person in the he_IL locale."""
+    def test_pesel_value_error(self):
+        self.assertRaises(ValueError, self.fake.pesel, datetime.date(2300, 1, 1))
+        self.assertRaises(ValueError, self.fake.pesel, datetime.date(1799, 12, 31))
 
-    def setUp(self):
-        self.fake = Faker("he_IL")
-        Faker.seed(0)
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pwz_doctor(self, mock_random_digit):
+        mock_random_digit.side_effect = [6, 9, 1, 9, 6, 5, 2, 7, 9, 9, 1, 5]
+        assert self.fake.pwz_doctor() == "2691965"
+        assert self.fake.pwz_doctor() == "4279915"
 
-    def test_language_name(self):
-        language_name = self.fake.language_name()
-        assert language_name in HeILProvider.language_names
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pwz_doctor_check_digit_zero(self, mock_random_digit):
+        mock_random_digit.side_effect = [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 9, 9]
+        assert self.fake.pwz_doctor() == "6000012"
+        assert self.fake.pwz_doctor() == "1000090"
 
-    def test_male_first_name(self):
-        first_name_male = self.fake.first_name_male()
-        assert first_name_male in HeILProvider.first_names_male
+    @mock.patch.object(PlPLProvider, "random_int")
+    @mock.patch.object(PlPLProvider, "random_digit")
+    def test_pwz_nurse(self, mock_random_digit, mock_random_int):
+        mock_random_digit.side_effect = [3, 4, 5, 6, 7, 1, 7, 5, 1, 2]
+        mock_random_int.side_effect = [45, 3]
+        assert self.fake.pwz_nurse(kind="nurse") == "4534567P"
+        assert self.fake.pwz_nurse(kind="midwife") == "0317512A"
 
-    def test_female_first_name(self):
-        first_name_female = self.fake.first_name_female()
-        assert first_name_female in HeILProvider.first_names_female
+    @staticmethod
+    def validate_nip(nip_str):
+        """
+        Validates NIP using recommended code
+        https://pl.wikibooks.org/wiki/Kody_%C5%BAr%C3%B3d%C5%82owe/Implementacja_NIP
+        """
+        nip_str = nip_str.replace("-", "")
+        if len(nip_str) != 10 or not nip_str.isdigit():
+            return False
+        digits = [int(i) for i in nip_str]
+        weights = (6, 5, 7, 2, 3, 4, 5, 6, 7)
+        check_sum = sum(d * w for d, w in zip(digits, weights)) % 11
+        return check_sum == digits[9]
 
-    def test_last_name(self):
-        last_name = self.fake.last_name()
-        assert last_name in HeILProvider.last_names
+    def test_nip(self):
+        for _ in range(100):
+            assert self.validate_nip(self.fake.nip())
 
 
 class TestPtPt(unittest.TestCase):
@@ -1180,167 +1120,213 @@ class TestPtPt(unittest.TestCase):
         assert last_name in PtPtProvider.last_names
 
 
-class TestEnGB(unittest.TestCase):
+class TestRuRU(unittest.TestCase):
+    """Tests person in the ru_RU locale"""
+
     def setUp(self):
-        self.fake = Faker("en_GB")
+        self.fake = Faker("ru_RU")
         Faker.seed(0)
 
-    def test_first_name_female(self):
-        name = self.fake.first_name_female()
-        assert name in EnGBProvider.first_names_female
-
-    def test_first_name_male(self):
-        name = self.fake.first_name_male()
-        assert name in EnGBProvider.first_names_male
+    def test_translit(self):
+        assert translit("Александр Сергеевич Пушкин") == "Aleksandr Sergeevich Pushkin"
+        assert translit("Анна Андреевна Ахматова") == "Anna Andreevna Akhmatova"
+        assert translit("Михаил") == "Mikhail"
+        assert translit("Фёдор") == "Fedor"
+        assert translit("Екатерина") == "Yekaterina"
+        assert translit("Анастасия") == "Anastasiya"
+        assert translit("Юрьевич") == "Yurevich"
+        assert translit("Никитична") == "Nikitichna"
+        assert translit("Щербакова") == "Shcherbakova"
+        assert translit("Маяковский") == "Mayakovskiy"
+        assert translit("Петров-Водкин") == "Petrov-Vodkin"
+        assert translit("Воронцова-Дашкова") == "Vorontsova-Dashkova"
+        assert translit("А.С.Пушкин") == "A.S.Pushkin"
+        assert translit("А. С. Пушкин") == "A. S. Pushkin"
+        assert translit("тов. И.И.Сидоров") == "tov. I.I.Sidorov"
+        assert translit("г-н А.Б.Петров") == "g-n A.B.Petrov"
+        assert translit("г-жа Ю.М.Петрова") == "g-zha Yu.M.Petrova"
 
     def test_name_female(self):
-        full_name = self.fake.name_female()
-        first_name = self.get_first_name_from_full_name(full_name)
-        assert first_name in EnGBProvider.first_names_female
+        first_name = self.fake.first_name_female()
+        assert first_name in RuProvider.first_names_female
+        middle_name = self.fake.middle_name_female()
+        assert middle_name in RuProvider.middle_names_female
+        last_name = self.fake.last_name_female()
+        assert last_name in RuProvider.last_names_female
 
     def test_name_male(self):
-        full_name = self.fake.name_male()
-        first_name = self.get_first_name_from_full_name(full_name)
-        assert first_name in EnGBProvider.first_names_male
-
-    def get_first_name_from_full_name(self, full_name):
-        names = full_name.split(" ")
-        if len(names) == 2:
-            return names[0]
-        return names[1]
+        first_name = self.fake.first_name_male()
+        assert first_name in RuProvider.first_names_male
+        middle_name = self.fake.middle_name_male()
+        assert middle_name in RuProvider.middle_names_male
+        last_name = self.fake.last_name_male()
+        assert last_name in RuProvider.last_names_male
 
+    def test_language_name(self):
+        language_name = self.fake.language_name()
+        assert language_name in RuProvider.language_names
 
-class TestUs(unittest.TestCase):
-    """Tests person in the en_US locale"""
 
+class TestSvSE(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("en_US")
+        self.fake = Faker("sv_SE")
         Faker.seed(0)
 
-    def test_first_names(self):
-        # General first name
+    def test_gender_first_names(self):
+        """simple test to verify that we are pulling gender specific names"""
+        name = self.fake.first_name_female()
+        assert name in SvSEProvider.first_names_female
+        name = self.fake.first_name_male()
+        assert name in SvSEProvider.first_names_male
         name = self.fake.first_name()
-        self.assertIsInstance(name, str)
-        assert name in EnUSProvider.first_names
+        assert name in SvSEProvider.first_names
 
-        # Female first name
-        name = self.fake.first_name_female()
-        self.assertIsInstance(name, str)
-        assert name in EnUSProvider.first_names
-        assert name in EnUSProvider.first_names_female
 
-        # Male first name
-        name = self.fake.first_name_male()
-        self.assertIsInstance(name, str)
-        assert name in EnUSProvider.first_names
-        assert name in EnUSProvider.first_names_male
+class TestSkSK(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("sk_SK")
+        Faker.seed(0)
 
-        # Nonbinary first name
-        name = self.fake.first_name_nonbinary()
-        self.assertIsInstance(name, str)
-        assert name in EnUSProvider.first_names
-        assert name in EnUSProvider.first_names_nonbinary
+    def test_name_male(self):
+        male_name = self.fake.name_male()
+        name_parts = male_name.split(" ")
+        first_name, last_name = "", ""
+        if len(name_parts) == 2:
+            first_name = name_parts[0]
+            last_name = name_parts[1]
+        elif len(name_parts) == 4:
+            first_name = name_parts[1]
+            last_name = name_parts[2]
+        elif len(name_parts) == 3:
+            if name_parts[-1] in SkSKProvider.suffixes:
+                first_name = name_parts[0]
+                last_name = name_parts[1]
+            else:
+                first_name = name_parts[1]
+                last_name = name_parts[2]
+        assert first_name in SkSKProvider.first_names_male
+        assert last_name in SkSKProvider.last_names_male
 
-    def test_last_names(self):
-        # General last name
+    def test_name_female(self):
+        female_name = self.fake.name_female()
+        name_parts = female_name.split(" ")
+        first_name, last_name = "", ""
+        if len(name_parts) == 2:
+            first_name = name_parts[0]
+            last_name = name_parts[1]
+        elif len(name_parts) == 4:
+            first_name = name_parts[1]
+            last_name = name_parts[2]
+        elif len(name_parts) == 3:
+            if name_parts[-1] in SkSKProvider.suffixes:
+                first_name = name_parts[0]
+                last_name = name_parts[1]
+            else:
+                first_name = name_parts[1]
+                last_name = name_parts[2]
+        assert first_name in SkSKProvider.first_names_female
+        assert last_name in SkSKProvider.last_names_female
+
+
+class TestSw(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("sw")
+        Faker.seed(0)
+
+    def test_last_name(self):
+        """
+        Test the generation of Swahili last names.
+        """
+        # There's no gender-specific last name in Swahili.
+        self.assertTrue(hasattr(SwProvider, "last_names_male"))
+        self.assertTrue(hasattr(SwProvider, "last_names_female"))
+
+        # All last names apply to all genders.
+        self.assertTrue(hasattr(SwProvider, "last_names"))
+
+        # General last name.
         name = self.fake.last_name()
         self.assertIsInstance(name, str)
-        assert name in EnUSProvider.last_names
+        self.assertIn(name, SwProvider.last_names)
 
-        # Female last name
+        # Females last name.
         name = self.fake.last_name_female()
         self.assertIsInstance(name, str)
-        assert name in EnUSProvider.last_names
+        self.assertIn(name, SwProvider.last_names)
 
-        # Male last name
+        # Male last name.
         name = self.fake.last_name_male()
         self.assertIsInstance(name, str)
-        assert name in EnUSProvider.last_names
+        self.assertIn(name, SwProvider.last_names)
 
-        # Nonbinary last name
-        name = self.fake.last_name_nonbinary()
+    def test_first_name(self):
+        """
+        Test the generation of Swahili first names.
+        """
+        # General first name.
+        name = self.fake.first_name()
         self.assertIsInstance(name, str)
-        assert name in EnUSProvider.last_names
+        self.assertIn(name, SwProvider.first_names)
 
-    def test_prefix(self):
-        # Nonbinary prefix
-        prefix = self.fake.prefix_nonbinary()
-        self.assertIsInstance(prefix, str)
-        assert prefix in EnUSProvider.prefixes_nonbinary
+        # Female first name.
+        name = self.fake.first_name_female()
+        self.assertIsInstance(name, str)
+        self.assertIn(name, SwProvider.first_names)
+        self.assertIn(name, SwProvider.first_names_female)
 
-    def test_suffix(self):
-        # Nonbinary suffix
-        suffix = self.fake.suffix_nonbinary()
-        self.assertIsInstance(suffix, str)
-        assert suffix in EnUSProvider.suffixes_nonbinary
+        # Male first name.
+        name = self.fake.first_name_male()
+        self.assertIsInstance(name, str)
+        self.assertIn(name, SwProvider.first_names)
+        self.assertIn(name, SwProvider.first_names_male)
 
+    def test_full_name(self):
+        """
+        Test the generation of full Swahili names.
+        """
+        # Full name.
+        name = self.fake.name()
+        self.assertIsInstance(name, str)
 
-class TestEn(unittest.TestCase):
-    """Tests person in the en locale"""
+        full_name_parts = name.split()
 
-    def setUp(self):
-        self.fake = Faker("en")
-        Faker.seed(0)
+        if len(full_name_parts) == 2:
+            first_name = full_name_parts[0]
+            last_name = full_name_parts[1]
+            self.assertIn(first_name, SwProvider.first_names)
+            self.assertIn(last_name, SwProvider.last_names)
+        elif len(full_name_parts) == 3:
+            prefix = full_name_parts[0]
+            first_name = full_name_parts[1]
+            last_name = full_name_parts[2]
 
-    def test_suffix(self):
-        # Traditional suffix -- provider does not offer a nonbinary suffix at this time
-        suffix = self.fake.suffix()
-        self.assertIsInstance(suffix, str)
-        assert suffix in EnProvider.suffixes_male or suffix in EnProvider.suffixes_female
+            self.assertIn(prefix, SwProvider.prefixes_female + SwProvider.prefixes_male)
+            self.assertIn(first_name, SwProvider.first_names)
+            self.assertIn(last_name, SwProvider.last_names)
+        else:
+            raise AssertionError("Invalid number of name parts. Expected 2 or 3.")
 
 
-class TestOrIN(unittest.TestCase):
+class TestTaIN(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("or_IN")
+        self.fake = Faker("ta_IN")
         Faker.seed(0)
 
-    def test_first_names(self):
+    def test_gender_first_names(self):
         """simple test to verify that we are pulling gender specific names"""
         name = self.fake.first_name_female()
-        assert name in OrINProvider.first_names_female
-
+        assert name in TaINProvider.first_names_female
         name = self.fake.first_name_male()
-        assert name in OrINProvider.first_names_male
-
-        name = self.fake.first_name_unisex()
-        assert name in OrINProvider.first_names_unisex
-
+        assert name in TaINProvider.first_names_male
         name = self.fake.first_name()
-        assert name in OrINProvider.first_names
-
-    def test_middle_names(self):
-        """test the middle name"""
-        name = self.fake.middle_name()
-        assert name in OrINProvider.middle_names
-
-    def test_last_names(self):
-        """test the last name is generating from the provided tuple"""
-        last_name = self.fake.last_name()
-        assert last_name in OrINProvider.last_names
-
-
-class TestEnIN(unittest.TestCase):
-    """Tests person in the en_IN locale"""
-
-    def setUp(self):
-        self.fake = Faker("en_IN")
-        Faker.seed(0)
-
-    def test_first_name(self):
-        first_name = self.fake.first_name()
-        assert first_name in EnINProvider.first_names
-
-    def test_last_name(self):
-        last_name = self.fake.last_name()
-        assert last_name in EnINProvider.last_names
+        assert name in TaINProvider.first_names
 
 
-class TestEnIE(unittest.TestCase):
-    """Tests person in the en-IE locale"""
+class TestThTh(unittest.TestCase):
+    """Tests person in the th_TH locale"""
 
     def setUp(self):
-        self.fake = Faker("en-ie")
-        self.provider = EnIEProvider
+        self.fake = Faker("th_TH")
         Faker.seed(0)
 
     def test_first_name(self):
@@ -1348,55 +1334,126 @@ class TestEnIE(unittest.TestCase):
         name = self.fake.first_name()
         assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
-
-        # Females first name
-        name = self.fake.first_name_female()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
-        assert name in self.provider.first_names_female
-
-        # Male first name
-        name = self.fake.first_name_male()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in self.provider.first_names
-        assert name in self.provider.first_names_male
+        assert name in ThThProvider.first_names
 
     def test_last_name(self):
-        assert not hasattr(self.provider, "last_names_male")
-        assert not hasattr(self.provider, "last_names_female")
+        # There's no gender-specific last name in Thai.
+        assert not hasattr(ThThProvider, "last_names_male")
+        assert not hasattr(ThThProvider, "last_names_female")
         # All last names apply for all genders.
-        assert hasattr(self.provider, "last_names")
+        assert hasattr(ThThProvider, "last_names")
 
         # General last name.
         name = self.fake.last_name()
         assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
+        assert name in ThThProvider.last_names
 
-        # Females last name.
-        name = self.fake.last_name_female()
+    def test_name(self):
+        # Full name
+        name = self.fake.name()
         assert name
         self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
-        assert name in self.provider.last_names
 
-        # Male last name.
-        name = self.fake.last_name_male()
-        assert name
-        self.assertIsInstance(name, str)
-        assert name in self.provider.last_names
 
+class TestUkUa(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("uk_UA")
+        Faker.seed(0)
+        self.provider = UkUAProvider
+        self.translit = UkUATranslit
+
+    def test_middle_names(self):
+        for _ in range(100):
+            res = self.fake.middle_name()
+            assert res in self.provider.middle_names
+
+    def test_male_middle_names(self):
+        for _ in range(100):
+            res = self.fake.middle_name_male()
+            assert res in self.provider.middle_names_male
+
+    def test_female_middle_names(self):
+        for _ in range(100):
+            res = self.fake.middle_name_female()
+            assert res in self.provider.middle_names_female
+
+    def test_language_name(self):
+        for _ in range(100):
+            language_name = self.fake.language_name()
+            assert language_name in self.provider.language_names
+
+    def test_transliteration(self):
+        assert self.translit("Сергій") == "Serhii"
+        assert self.translit("Лілія") == "Liliia"
+        assert self.translit("Яся") == "Yasia"
+        assert self.translit("Демʼян") == "Demian"
+        assert self.translit("Марʼяна") == "Mariana"
+        assert (
+            self.translit("абвгґдеєжзиіїйклмнопрстуфхцчшщьюяєʼ'-") == "abvhgdeiezhzyiiiklmnoprstufkhtschshshchiuiaie'-"
+        )
+        assert self.translit("АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ") == "ABVHGDEYeZhZYIYiYKLMNOPRSTUFKhTsChShShchYuYa"
+
+    def test_full_name_male(self):
+        for _ in range(10):
+            res = self.fake.full_name(gender="M")
+            last_name, first_name, middle_name = res.split(" ")
+            assert last_name in self.provider.last_names
+            assert first_name in self.provider.first_names_male
+            assert middle_name in self.provider.middle_names_male
+
+    def test_full_name_female(self):
+        for _ in range(10):
+            res = self.fake.full_name(gender="F")
+            last_name, first_name, middle_name = res.split(" ")
+            assert last_name in self.provider.last_names
+            assert first_name in self.provider.first_names_female
+            assert middle_name in self.provider.middle_names_female
+
+    def test_full_name(self):
+        for _ in range(10):
+            res = self.fake.full_name()
+            last_name, first_name, middle_name = res.split(" ")
+            assert last_name in self.provider.last_names
+            assert first_name in self.provider.first_names
+            assert middle_name in self.provider.middle_names
+
+    def test_short_full_name(self):
+        res = self.fake.full_name(short=True)
+        assert res.count(".") == 2
+        assert res.count(" ") == 1
+
+
+class TestViVn(unittest.TestCase):
+    """Test vi_VN person provider methods"""
+
+    def setUp(self):
+        self.fake = Faker("vi_VN")
+        Faker.seed(0)
+
+    def test_first_names(self):
+        """simple test to verify that we are pulling gender specific names"""
+        name = self.fake.first_name_female()
+        assert name in ViVNProvider.first_names_female
+
+        name = self.fake.first_name_male()
+        assert name in ViVNProvider.first_names_male
+
+        name = self.fake.first_name_unisex()
+        assert name in ViVNProvider.first_names_unisex
+
+        name = self.fake.first_name()
+        assert name in ViVNProvider.first_names
 
-class TestGaIE(TestEnIE):
-    """Tests person in the ga-IE locale"""
+    def test_middle_names(self):
+        """test the middle name"""
+        name = self.fake.middle_name()
+        assert name in ViVNProvider.middle_names
 
-    def setUp(self):
-        self.fake = Faker("ga-ie")
-        self.provider = GaIEProvider
-        Faker.seed(0)
+    def test_last_names(self):
+        """test the last name is generating from the provided tuple"""
+        last_name = self.fake.last_name()
+        assert last_name in ViVNProvider.last_names
 
 
 class TestYoNG(unittest.TestCase):
@@ -1478,83 +1535,168 @@ class TestYoNG(unittest.TestCase):
             raise AssertionError("Invalid number of name parts. Expected 2 or 3.")
 
 
-class TestSw(unittest.TestCase):
+class TestZhCN(unittest.TestCase):
     def setUp(self):
-        self.fake = Faker("sw")
+        self.fake = Faker("zh_CN")
         Faker.seed(0)
 
     def test_last_name(self):
-        """
-        Test the generation of Swahili last names.
-        """
-        # There's no gender-specific last name in Swahili.
-        self.assertTrue(hasattr(SwProvider, "last_names_male"))
-        self.assertTrue(hasattr(SwProvider, "last_names_female"))
-
-        # All last names apply to all genders.
-        self.assertTrue(hasattr(SwProvider, "last_names"))
+        # There's no gender-specific last name in Chinese.
+        assert not hasattr(ZhCNProvider, "last_names_male")
+        assert not hasattr(ZhCNProvider, "last_names_female")
+        assert not hasattr(ZhCNProvider, "last_romanized_names_male")
+        assert not hasattr(ZhCNProvider, "last_romanized_names_female")
+        # All last names apply for all genders.
+        assert hasattr(ZhCNProvider, "last_names")
 
         # General last name.
         name = self.fake.last_name()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.last_names)
+        assert name in ZhCNProvider.last_names
 
         # Females last name.
         name = self.fake.last_name_female()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.last_names)
+        assert name in ZhCNProvider.last_names
 
         # Male last name.
         name = self.fake.last_name_male()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.last_names)
+        assert name in ZhCNProvider.last_names
+
+        # General last romanized name
+        name = self.fake.last_romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhCNProvider.last_romanized_names
 
     def test_first_name(self):
-        """
-        Test the generation of Swahili first names.
-        """
-        # General first name.
+        # General first name
         name = self.fake.first_name()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.first_names)
+        assert name in ZhCNProvider.first_names
 
-        # Female first name.
+        # Females first name
         name = self.fake.first_name_female()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.first_names)
-        self.assertIn(name, SwProvider.first_names_female)
+        assert name in ZhCNProvider.first_names
+        assert name in ZhCNProvider.first_names_female
 
-        # Male first name.
+        # Male first name
         name = self.fake.first_name_male()
+        assert name
         self.assertIsInstance(name, str)
-        self.assertIn(name, SwProvider.first_names)
-        self.assertIn(name, SwProvider.first_names_male)
+        assert name in ZhCNProvider.first_names
+        assert name in ZhCNProvider.first_names_male
 
-    def test_full_name(self):
-        """
-        Test the generation of full Swahili names.
-        """
-        # Full name.
+        # General first romanized name
+        name = self.fake.first_romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhCNProvider.first_romanized_names
+
+    def test_name(self):
+        # Full name
         name = self.fake.name()
+        assert name
         self.assertIsInstance(name, str)
+        assert name[0] in ZhCNProvider.last_names or name[:2] in ZhCNProvider.last_names
+        assert name[1:] in ZhCNProvider.first_names or name[2:] in ZhCNProvider.first_names
 
-        full_name_parts = name.split()
+        # Full romanized name
+        name = self.fake.romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        first_romanized_name, last_romanized_name = name.split(" ")
+        assert first_romanized_name in ZhCNProvider.first_romanized_names
+        assert last_romanized_name in ZhCNProvider.last_romanized_names
 
-        if len(full_name_parts) == 2:
-            first_name = full_name_parts[0]
-            last_name = full_name_parts[1]
-            self.assertIn(first_name, SwProvider.first_names)
-            self.assertIn(last_name, SwProvider.last_names)
-        elif len(full_name_parts) == 3:
-            prefix = full_name_parts[0]
-            first_name = full_name_parts[1]
-            last_name = full_name_parts[2]
 
-            self.assertIn(prefix, SwProvider.prefixes_female + SwProvider.prefixes_male)
-            self.assertIn(first_name, SwProvider.first_names)
-            self.assertIn(last_name, SwProvider.last_names)
-        else:
-            raise AssertionError("Invalid number of name parts. Expected 2 or 3.")
+class TestZhTW(unittest.TestCase):
+    def setUp(self):
+        self.fake = Faker("zh_TW")
+        Faker.seed(0)
+
+    def test_last_name(self):
+        # There's no gender-specific last name in Chinese.
+        assert not hasattr(ZhTWProvider, "last_names_male")
+        assert not hasattr(ZhTWProvider, "last_names_female")
+        assert not hasattr(ZhTWProvider, "last_romanized_names_male")
+        assert not hasattr(ZhTWProvider, "last_romanized_names_female")
+        # All last names apply for all genders.
+        assert hasattr(ZhTWProvider, "last_names")
+
+        # General last name.
+        name = self.fake.last_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.last_names
+
+        # Females last name.
+        name = self.fake.last_name_female()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.last_names
+
+        # Male last name.
+        name = self.fake.last_name_male()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.last_names
+
+        # General last romanized name
+        name = self.fake.last_romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.last_romanized_names
+
+    def test_first_name(self):
+        # General first name
+        name = self.fake.first_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.first_names
+
+        # Females first name
+        name = self.fake.first_name_female()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.first_names
+        assert name in ZhTWProvider.first_names_female
+
+        # Male first name
+        name = self.fake.first_name_male()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.first_names
+        assert name in ZhTWProvider.first_names_male
+
+        # General first romanized name
+        name = self.fake.first_romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name in ZhTWProvider.first_romanized_names
+
+    def test_name(self):
+        # Full name
+        name = self.fake.name()
+        assert name
+        self.assertIsInstance(name, str)
+        assert name[0] in ZhTWProvider.last_names or name[:2] in ZhTWProvider.last_names
+        assert name[1:] in ZhTWProvider.first_names or name[2:] in ZhTWProvider.first_names
+
+        # Full romanized name
+        name = self.fake.romanized_name()
+        assert name
+        self.assertIsInstance(name, str)
+        first_romanized_name, last_romanized_name = name.split(" ")
+        assert first_romanized_name in ZhTWProvider.first_romanized_names
+        assert last_romanized_name in ZhTWProvider.last_romanized_names
 
 
 class TestZuZa(unittest.TestCase):
@@ -1636,73 +1778,5 @@ class TestZuZa(unittest.TestCase):
             raise AssertionError("Invalid number of name parts. Expected 2 or 3.")
 
 
-class TestUkUa(unittest.TestCase):
-    def setUp(self):
-        self.fake = Faker("uk_UA")
-        Faker.seed(0)
-        self.provider = UkUAProvider
-        self.translit = UkUATranslit
-
-    def test_middle_names(self):
-        for _ in range(100):
-            res = self.fake.middle_name()
-            assert res in self.provider.middle_names
-
-    def test_male_middle_names(self):
-        for _ in range(100):
-            res = self.fake.middle_name_male()
-            assert res in self.provider.middle_names_male
-
-    def test_female_middle_names(self):
-        for _ in range(100):
-            res = self.fake.middle_name_female()
-            assert res in self.provider.middle_names_female
-
-    def test_language_name(self):
-        for _ in range(100):
-            language_name = self.fake.language_name()
-            assert language_name in self.provider.language_names
-
-    def test_transliteration(self):
-        assert self.translit("Сергій") == "Serhii"
-        assert self.translit("Лілія") == "Liliia"
-        assert self.translit("Яся") == "Yasia"
-        assert self.translit("Демʼян") == "Demian"
-        assert self.translit("Марʼяна") == "Mariana"
-        assert (
-            self.translit("абвгґдеєжзиіїйклмнопрстуфхцчшщьюяєʼ'-") == "abvhgdeiezhzyiiiklmnoprstufkhtschshshchiuiaie'-"
-        )
-        assert self.translit("АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ") == "ABVHGDEYeZhZYIYiYKLMNOPRSTUFKhTsChShShchYuYa"
-
-    def test_full_name_male(self):
-        for _ in range(10):
-            res = self.fake.full_name(gender="M")
-            last_name, first_name, middle_name = res.split(" ")
-            assert last_name in self.provider.last_names
-            assert first_name in self.provider.first_names_male
-            assert middle_name in self.provider.middle_names_male
-
-    def test_full_name_female(self):
-        for _ in range(10):
-            res = self.fake.full_name(gender="F")
-            last_name, first_name, middle_name = res.split(" ")
-            assert last_name in self.provider.last_names
-            assert first_name in self.provider.first_names_female
-            assert middle_name in self.provider.middle_names_female
-
-    def test_full_name(self):
-        for _ in range(10):
-            res = self.fake.full_name()
-            last_name, first_name, middle_name = res.split(" ")
-            assert last_name in self.provider.last_names
-            assert first_name in self.provider.first_names
-            assert middle_name in self.provider.middle_names
-
-    def test_short_full_name(self):
-        res = self.fake.full_name(short=True)
-        assert res.count(".") == 2
-        assert res.count(" ") == 1
-
-
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/providers/test_phone_number.py b/tests/providers/test_phone_number.py
index 39cf2ea6..75608369 100644
--- a/tests/providers/test_phone_number.py
+++ b/tests/providers/test_phone_number.py
@@ -417,3 +417,24 @@ class TestEnUs:
                     pattern_is_found = True
                     break
             assert pattern_is_found
+
+
+class TestViVn:
+    """Test vi_VN phone number provider methods"""
+
+    def test_phone_number(self, faker, num_samples):
+        pattern: Pattern = re.compile(
+            r"(?:"  # Non-capturing group
+            r"\+84 \d{2} \d{7}|"  # Example: +84 12 3456789
+            r"\(0\d\) \d{4} \d{4}|"  # Example: (012) 3456 7890
+            r"0\d \d{4} \d{4}|"  # Example: 012 3456 7890
+            r"0\d \d{7}|"  # Example: 012 3456789
+            r"\+84-\d{2}-\d{6}|"  # Example: +84-12-345678
+            r"\+84-\d{2}-\d{3} \d{4}|"  # Example: +84-12-345 6789
+            r"\(0\d\)\d{3}-\d{4}"  # Example: (012)345-6789
+            r")"  # Closing non-capturing group
+        )
+        for _ in range(num_samples):
+            phone_number = faker.phone_number()
+            assert isinstance(phone_number, str)
+            assert pattern.fullmatch(phone_number)
diff --git a/tests/pytest/test_manual_injection.py b/tests/pytest/test_manual_injection.py
index 29cd0e2a..dddfc715 100644
--- a/tests/pytest/test_manual_injection.py
+++ b/tests/pytest/test_manual_injection.py
@@ -6,7 +6,6 @@ were defined. The resulting behavior of the ``faker`` fixture will vary dependin
 on which fixtures are injected.
 """
 
-
 from random import Random
 
 import pytest