Skip to content

Commit

Permalink
Add PIN Code range and union territories in en_IN address provider (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
wh0th3h3llam1 authored Sep 30, 2024
1 parent e84d0a4 commit 2a25996
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 1 deletion.
178 changes: 177 additions & 1 deletion faker/providers/address/en_IN/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from .. import Provider as AddressProvider
import random

Check failure on line 1 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / flake8

'random' imported but unused

Check failure on line 1 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
from typing import Optional
from faker.providers.address import Provider as AddressProvider


class Provider(AddressProvider):
Expand Down Expand Up @@ -391,10 +393,184 @@ class Provider(AddressProvider):
"West Bengal",
)

states_abbr = (
"AP",
"AR",
"AS",
"BR",
"CG",
"GA",
"GJ",
"HR",
"HP",
"JH",
"KA",
"KL",
"MP",
"MH",
"MN",
"ML",
"MZ",
"NL",
"OD",
"PB",
"RJ",
"SK",
"TN",
"TG",
"TR",
"UK",
"UP",
"WB",
)

union_territories = (
("Andaman and Nicobar Islands",),
("Chandigarh",),
("Dadra and Nagar Haveli, Dadra & Nagar Haveli",),
("Daman and Diu",),
("Delhi, National Capital Territory of Delhi",),
("Jammu and Kashmir",),
("Ladakh",),
("Lakshadweep",),
("Pondicherry",),
("Puducherry",),
)

union_territories_abbr = (
"AN",
"CH",
"DN",
"DD",
"DL",
"JK",
"LA",
"LD",
"PY",
)

# https://en.wikipedia.org/wiki/Postal_Index_Number

# FIXME: Some states such as `BR/JH` / `UK/UP` have similar PIN code ranges
# FIXME: as mentioned in above link.

state_pincode = {
"AP": [(510_000, 539_999)],
"AR": [(790_000, 792_999)],
"AS": [(780_000, 789_999)],
"BR": [(800_000, 859_999)],
"CG": [(490_000, 499_999)],
"GA": [(403_000, 403_999)],
"GJ": [(360_000, 399_999)],
"HR": [(120_000, 139_999)],
"HP": [(170_000, 179_999)],
"JH": [(800_000, 859_999)],
"KA": [(560_000, 599_999)],
"KL": [(670_000, 681_999), (683_000, 699_999)],
"MP": [(450_000, 489_999)],
"MH": [(400_000, 402_999), (404_000, 449_999)],
"MN": [(795_000, 795_999)],
"ML": [(793_000, 794_999)],
"MZ": [(796_000, 796_999)],
"NL": [(797_000, 798_999)],
"OD": [(750_000, 779_999)],
"PB": [(140_000, 159_999)],
"RJ": [(300_000, 349_999)],
"SK": [(737_000, 737_999)],
"TN": [(600_000, 669_999)],
"TG": [(500_000, 509_999)],
"TR": [(799_000, 799_999)],
"UK": [(200_000, 289_999)],
"UP": [(200_000, 289_999)],
"WB": [(700_000, 736_999), (738_000, 743_999), (745_000, 749_999)],
}

union_territories_pincode = {
"AN": [(744_000, 744_999)],
"CH": [(160_000, 169_999)],
"DN": [(396_000, 396_999)],
"DD": [(396_000, 396_999)],
"DL": [(110_000, 119_999)],
"JK": [(180_000, 199_999)],
"LA": [(180_000, 199_999)],
"LD": [(682_000, 682_999)],
"PY": [(605_000, 605_999)],
}

army_pincode = {"APS": (900_000, 999_999)}

def city_name(self) -> str:
return self.random_element(self.cities)

def administrative_unit(self) -> str:
return self.random_element(self.states)

state = administrative_unit

def union_territory(self) -> str:
"""Returns random union territory name"""

return self.random_element(self.union_territories)[0]

def pincode_in_state(

Check failure on line 515 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / typing (3.10)

Function is missing a
self, state_abbr: Optional[str] = None, include_union_territories=False
) -> int:
"""Random PIN Code within provided state abbreviation
:param state_abbr: State Abbr, defaults to None
:param include_union_territories: Include Union Territories ?, defaults to False
:raises ValueError: If incorrect state abbr
:return: PIN Code
"""

known_abbrs = self.states_abbr
if include_union_territories:
known_abbrs += self.union_territories_abbr

Check failure on line 528 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / typing (3.10)

Incompatible types in

if state_abbr is None:
state_abbr = self.random_element(known_abbrs)

if state_abbr in known_abbrs:
codes = self.state_pincode
if include_union_territories:
codes = codes | self.union_territories_pincode

pincode_range = self.random_element(codes[state_abbr])

return self.generator.random.randint(*pincode_range)

raise ValueError("State Abbreviation not found in list")

def pincode_in_military(self) -> int:
"""Random PIN Code within Army Postal Service range"""

key = self.random_element(self.army_pincode.keys())

Check failure on line 547 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / typing (3.10)

Need type annotation

return self.generator.random.randint(*self.army_pincode[key])

# Aliases

def zipcode_in_state(

Check failure on line 553 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / typing (3.10)

Function is missing a
self, state_abbr: Optional[str] = None, include_union_territories=False
) -> int:
return self.pincode_in_state(state_abbr, include_union_territories)

def postcode_in_state(

Check failure on line 558 in faker/providers/address/en_IN/__init__.py

View workflow job for this annotation

GitHub Actions / typing (3.10)

Function is missing a
self, state_abbr: Optional[str] = None, include_union_territories=False
) -> int:
return self.pincode_in_state(state_abbr, include_union_territories)

def pincode_in_army(self) -> int:
return self.pincode_in_military()

def zipcode_in_military(self) -> int:
return self.pincode_in_military()

def zipcode_in_army(self) -> int:
return self.pincode_in_military()

def postcode_in_military(self) -> int:
return self.pincode_in_military()

def postcode_in_army(self) -> int:
return self.pincode_in_military()
41 changes: 41 additions & 0 deletions tests/providers/test_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -1865,17 +1865,58 @@ class TestEnIn:
"""Test en_IN address provider methods"""

def test_city_name(self, faker, num_samples):
"""Tests `city names` are fetched correctly"""

for _ in range(num_samples):
city_name = faker.city_name()
assert isinstance(city_name, str)
assert city_name in EnInAddressProvider.cities

def test_state(self, faker, num_samples):
"""Tests `states` are fetched correctly"""

for _ in range(num_samples):
state = faker.state()
assert isinstance(state, str)
assert state in EnInAddressProvider.states

def test_union_territories(self, faker, num_samples):
"""Tests `union_territories` are fetched correctly"""

for _ in range(num_samples):
union_territory = faker.union_territory()
assert isinstance(union_territory, str)
assert (union_territory,) in EnInAddressProvider.union_territories

@pytest.mark.parametrize("pincodes", ["pincode_in_state", "zipcode_in_state", "postcode_in_state"])
def test_pincodes_in_state(self, faker, num_samples, pincodes):
"""Test `pincodes` for state and union territories"""

for _ in range(num_samples):
include_ut = faker.random_element([True, False])
pincode = getattr(faker, pincodes)(include_union_territories=include_ut)
assert isinstance(pincode, int)
assert len(str(pincode)) == 6

@pytest.mark.parametrize(
"pincodes",
[
("pincode_in_army"),
("zipcode_in_army"),
("postcode_in_army"),
("postcode_in_military"),
("zipcode_in_military"),
("pincode_in_military"),
],
)
def test_pincodes_in_military(self, faker, num_samples, pincodes):
"""Test `pincodes` for Army"""

for _ in range(num_samples):
pincode = getattr(faker, pincodes)()
assert isinstance(pincode, int)
assert len(str(pincode)) == 6


class TestSkSk:
"""Test sk_SK address provider methods"""
Expand Down

0 comments on commit 2a25996

Please sign in to comment.