From 9a382ed237ef6ac40eb272703eb3b6ce0546ad0f Mon Sep 17 00:00:00 2001 From: "M.J. Robeer" Date: Tue, 19 Oct 2021 16:25:48 +0200 Subject: [PATCH] Add Typing [Fixed #1489!] (#1536) * Create nl_NL * Delete nl_NL * Add date_time provider for nl_NL * Added date_time nl_NL test case * Added nl_NL provider * Added nl_NL test case * Added nl_NL automotive provider * Added tests for nl_NL automotive provider * flake8 fixes * flake8 fixes in test_automotive * import order fixes * Added type annotations * mypy fixes * isort fixes * minor flake8 fixes * Fixed circular import error in generator.py * Circular import error fix * Typing fixes for OrderedDict * OrderedDict Python 3.6 fix * OrderedDictType fix in proxy * Added mypy test to tox.ini * Update tox.ini * Update tox.ini * PyPy is incompatible with mypy * Update tox.ini * Removed `automotive` provider `nl_NL` * Typo * Many typing fixes - New mypy version in tox.ini - Replaced Any with TypeVar('T') - Added List[str] pr Tuple[str, ...] in many places (e.g. base classes, so that inherited classes would not throw errors) - Fully fixed `providers.color.color.py` * Added ElementsType (input for `BaseProvider.random_element()`) * First typing fixes in date_time * Minor Typing fixes to date_time * Typing fixes in `providers.company` * Minor typing fixes in `providers.barcode` * Minor typing fixes in `providers.address` * Minor typing fixes in `providers.person` * Update decorators.py * Minor typing fixes in `providers.automotive` * Import typing.Pattern in test files * Added type: ignore[attr-defined] hotfix * Added final missing Pattern imports * Optional distrib, flake8 fix in test_user_agent * Minor typing fixes * Literal not supported before Python 3.8 * Bug fix in datetime.fromtimestamp * Fixed broken tests Except TestInternetProvider.test_ipv4_distribution_selection! * Fixed test_ipv4_distribution_selection * Update decimal in `geo.el_GR` * Add mypy config and improve command for tox * Fix last type errors - remove OrderedDictType and use Dict instead - remove type checking for Literal and use try catch instead - add Any for *args and **kwargs arguments * Updated MANIFEST.in to include mypy.ini * Renamed typing.py to typing.pyi * Some Python versions don't like .pyi * Updated coding_style.rst - Removed redundant TypeVar from Generator - Ordered typing.py in alphabetical order * Added mypy to .github/workflows/ci.yml * Added dependency order to ci.yml * Python 3.10 to "3.10" in ci.yml * Unused ignores across versions https://github.com/python/mypy/issues/8823 * Show error codes * Python 3.6 mypy fix * Final changes Co-authored-by: Nico Carl --- .github/workflows/ci.yml | 31 +- MANIFEST.in | 1 + docs/coding_style.rst | 16 +- faker/__main__.py | 2 +- faker/cli.py | 45 +-- faker/config.py | 2 +- faker/documentor.py | 31 +- faker/exceptions.py | 3 +- faker/factory.py | 25 +- faker/generator.py | 41 +-- faker/providers/__init__.py | 78 +++-- faker/providers/address/__init__.py | 60 ++-- faker/providers/address/cs_CZ/__init__.py | 12 +- faker/providers/address/da_DK/__init__.py | 6 +- faker/providers/address/de_AT/__init__.py | 12 +- faker/providers/address/de_CH/__init__.py | 8 +- faker/providers/address/de_DE/__init__.py | 12 +- faker/providers/address/el_GR/__init__.py | 16 +- faker/providers/address/en_AU/__init__.py | 8 +- faker/providers/address/en_CA/__init__.py | 24 +- faker/providers/address/en_GB/__init__.py | 10 +- faker/providers/address/en_IE/__init__.py | 6 +- faker/providers/address/en_IN/__init__.py | 4 +- faker/providers/address/en_NZ/__init__.py | 16 +- faker/providers/address/en_PH/__init__.py | 71 ++--- faker/providers/address/en_US/__init__.py | 49 ++- faker/providers/address/es_ES/__init__.py | 10 +- faker/providers/address/es_MX/__init__.py | 18 +- faker/providers/address/fa_IR/__init__.py | 6 +- faker/providers/address/fi_FI/__init__.py | 6 +- faker/providers/address/fr_CH/__init__.py | 12 +- faker/providers/address/fr_FR/__init__.py | 14 +- faker/providers/address/he_IL/__init__.py | 4 +- faker/providers/address/hi_IN/__init__.py | 4 +- faker/providers/address/hr_HR/__init__.py | 6 +- faker/providers/address/hu_HU/__init__.py | 18 +- faker/providers/address/hy_AM/__init__.py | 28 +- faker/providers/address/id_ID/__init__.py | 14 +- faker/providers/address/it_IT/__init__.py | 8 +- faker/providers/address/ja_JP/__init__.py | 18 +- faker/providers/address/ka_GE/__init__.py | 4 +- faker/providers/address/ko_KR/__init__.py | 54 ++-- faker/providers/address/ne_NP/__init__.py | 8 +- faker/providers/address/nl_BE/__init__.py | 4 +- faker/providers/address/nl_NL/__init__.py | 4 +- faker/providers/address/no_NO/__init__.py | 8 +- faker/providers/address/pl_PL/__init__.py | 12 +- faker/providers/address/pt_BR/__init__.py | 20 +- faker/providers/address/pt_PT/__init__.py | 14 +- faker/providers/address/ro_RO/__init__.py | 20 +- faker/providers/address/ru_RU/__init__.py | 28 +- faker/providers/address/sk_SK/__init__.py | 12 +- faker/providers/address/sl_SI/__init__.py | 6 +- faker/providers/address/sv_SE/__init__.py | 6 +- faker/providers/address/ta_IN/__init__.py | 4 +- faker/providers/address/th_TH/__init__.py | 71 ++--- faker/providers/address/uk_UA/__init__.py | 14 +- faker/providers/address/zh_CN/__init__.py | 8 +- faker/providers/address/zh_TW/__init__.py | 14 +- faker/providers/automotive/__init__.py | 6 +- faker/providers/automotive/ar_JO/__init__.py | 6 +- faker/providers/automotive/ar_PS/__init__.py | 6 +- faker/providers/automotive/ar_SA/__init__.py | 20 +- faker/providers/automotive/de_DE/__init__.py | 4 +- faker/providers/automotive/en_PH/__init__.py | 21 +- faker/providers/automotive/es_ES/__init__.py | 8 +- faker/providers/automotive/pl_PL/__init__.py | 4 +- faker/providers/automotive/ro_RO/__init__.py | 4 +- faker/providers/automotive/ru_RU/__init__.py | 16 +- faker/providers/automotive/sk_SK/__init__.py | 4 +- faker/providers/automotive/th_TH/__init__.py | 2 +- faker/providers/bank/__init__.py | 33 +- faker/providers/bank/en_PH/__init__.py | 4 +- faker/providers/bank/ru_RU/__init__.py | 20 +- faker/providers/barcode/__init__.py | 22 +- faker/providers/barcode/en_US/__init__.py | 51 +-- faker/providers/barcode/ja_JP/__init__.py | 6 +- faker/providers/color/__init__.py | 25 +- faker/providers/color/color.py | 215 +++++++------ faker/providers/color/he_IL/__init__.py | 14 +- faker/providers/company/__init__.py | 34 +- faker/providers/company/en_PH/__init__.py | 10 +- faker/providers/company/es_MX/__init__.py | 22 +- faker/providers/company/fa_IR/__init__.py | 2 +- faker/providers/company/fi_FI/__init__.py | 8 +- faker/providers/company/fil_PH/__init__.py | 15 +- faker/providers/company/fr_CH/__init__.py | 6 +- faker/providers/company/fr_FR/__init__.py | 20 +- faker/providers/company/hu_HU/__init__.py | 2 +- faker/providers/company/id_ID/__init__.py | 2 +- faker/providers/company/it_IT/__init__.py | 26 +- faker/providers/company/ja_JP/__init__.py | 4 +- faker/providers/company/ko_KR/__init__.py | 20 -- faker/providers/company/nl_NL/__init__.py | 4 +- faker/providers/company/pl_PL/__init__.py | 16 +- faker/providers/company/pt_BR/__init__.py | 21 +- faker/providers/company/ro_RO/__init__.py | 2 +- faker/providers/company/ru_RU/__init__.py | 68 ++-- faker/providers/company/th_TH/__init__.py | 8 +- faker/providers/company/tr_TR/__init__.py | 2 +- faker/providers/company/zh_CN/__init__.py | 2 +- faker/providers/company/zh_TW/__init__.py | 2 +- faker/providers/credit_card/__init__.py | 68 ++-- faker/providers/credit_card/fa_IR/__init__.py | 12 - faker/providers/credit_card/pt_PT/__init__.py | 13 - faker/providers/credit_card/ru_RU/__init__.py | 17 +- faker/providers/currency/__init__.py | 31 +- faker/providers/currency/cs_CZ/__init__.py | 2 +- faker/providers/currency/de_AT/__init__.py | 2 +- faker/providers/currency/en_AU/__init__.py | 2 +- faker/providers/currency/en_US/__init__.py | 2 +- faker/providers/currency/es_ES/__init__.py | 2 +- faker/providers/currency/fr_CA/__init__.py | 2 +- faker/providers/currency/nl_NL/__init__.py | 2 +- faker/providers/currency/pl_PL/__init__.py | 2 +- faker/providers/currency/pt_BR/__init__.py | 2 +- faker/providers/currency/ro_RO/__init__.py | 2 +- faker/providers/currency/ru_RU/__init__.py | 2 +- faker/providers/date_time/__init__.py | 290 +++++++++--------- faker/providers/date_time/ar_AA/__init__.py | 6 +- faker/providers/date_time/bn_BD/__init__.py | 4 +- faker/providers/date_time/fr_FR/__init__.py | 4 +- faker/providers/date_time/hi_IN/__init__.py | 4 +- faker/providers/date_time/hr_HR/__init__.py | 4 +- faker/providers/date_time/hu_HU/__init__.py | 4 +- faker/providers/date_time/id_ID/__init__.py | 4 +- faker/providers/date_time/ko_KR/__init__.py | 4 +- faker/providers/date_time/ru_RU/__init__.py | 4 +- faker/providers/date_time/sl_SI/__init__.py | 4 +- faker/providers/date_time/ta_IN/__init__.py | 4 +- faker/providers/date_time/th_TH/__init__.py | 20 +- faker/providers/file/__init__.py | 67 ++-- faker/providers/geo/__init__.py | 25 +- faker/providers/geo/de_AT/__init__.py | 6 +- faker/providers/geo/el_GR/__init__.py | 21 +- faker/providers/geo/pt_PT/__init__.py | 2 +- faker/providers/geo/tr_TR/__init__.py | 2 +- faker/providers/internet/__init__.py | 205 +++++++------ faker/providers/internet/el_GR/__init__.py | 10 +- faker/providers/internet/en_PH/__init__.py | 2 +- faker/providers/internet/ja_JP/__init__.py | 2 +- faker/providers/internet/zh_CN/__init__.py | 8 +- faker/providers/isbn/__init__.py | 22 +- faker/providers/isbn/isbn.py | 34 +- faker/providers/isbn/rules.py | 3 +- faker/providers/job/__init__.py | 6 +- faker/providers/job/hu_HU/__init__.py | 4 +- faker/providers/job/sk_SK/__init__.py | 2 +- faker/providers/lorem/__init__.py | 38 ++- faker/providers/lorem/en_PH/__init__.py | 18 +- faker/providers/misc/__init__.py | 120 +++++--- faker/providers/misc/en_PH/__init__.py | 10 +- faker/providers/person/__init__.py | 108 +++---- faker/providers/person/ar_AA/__init__.py | 16 +- faker/providers/person/en_NZ/__init__.py | 13 +- faker/providers/person/es_ES/__init__.py | 12 +- faker/providers/person/et_EE/__init__.py | 26 +- faker/providers/person/fa_IR/__init__.py | 2 +- faker/providers/person/fr_QC/__init__.py | 4 +- faker/providers/person/hu_HU/__init__.py | 23 +- faker/providers/person/it_IT/__init__.py | 2 +- faker/providers/person/ja_JP/__init__.py | 59 ++-- faker/providers/person/ko_KR/__init__.py | 4 +- faker/providers/person/or_IN/__init__.py | 4 +- faker/providers/person/pl_PL/__init__.py | 52 ++-- faker/providers/person/pt_PT/__init__.py | 2 +- faker/providers/person/ru_RU/__init__.py | 35 ++- faker/providers/person/zh_CN/__init__.py | 8 +- faker/providers/person/zh_TW/__init__.py | 8 +- faker/providers/phone_number/__init__.py | 14 +- .../providers/phone_number/ar_AE/__init__.py | 26 +- .../providers/phone_number/ar_JO/__init__.py | 20 +- .../providers/phone_number/ar_PS/__init__.py | 24 +- .../providers/phone_number/en_AU/__init__.py | 6 +- .../providers/phone_number/en_GB/__init__.py | 4 +- .../providers/phone_number/en_NZ/__init__.py | 6 +- .../providers/phone_number/en_PH/__init__.py | 84 ++--- .../providers/phone_number/pt_BR/__init__.py | 8 +- .../providers/phone_number/zh_CN/__init__.py | 2 +- faker/providers/profile/__init__.py | 21 +- faker/providers/python/__init__.py | 40 +-- faker/providers/ssn/__init__.py | 6 +- faker/providers/ssn/bg_BG/__init__.py | 2 +- faker/providers/ssn/cs_CZ/__init__.py | 12 +- faker/providers/ssn/de_AT/__init__.py | 2 +- faker/providers/ssn/de_DE/__init__.py | 2 +- faker/providers/ssn/dk_DK/__init__.py | 2 +- faker/providers/ssn/el_CY/__init__.py | 2 +- faker/providers/ssn/el_GR/__init__.py | 4 +- faker/providers/ssn/en_CA/__init__.py | 2 +- faker/providers/ssn/en_GB/__init__.py | 12 +- faker/providers/ssn/en_IE/__init__.py | 2 +- faker/providers/ssn/en_IN/__init__.py | 4 +- faker/providers/ssn/en_PH/__init__.py | 12 +- faker/providers/ssn/en_US/__init__.py | 16 +- faker/providers/ssn/es_ES/__init__.py | 14 +- faker/providers/ssn/es_MX/__init__.py | 12 +- faker/providers/ssn/et_EE/__init__.py | 8 +- faker/providers/ssn/fi_FI/__init__.py | 6 +- faker/providers/ssn/fr_CH/__init__.py | 18 +- faker/providers/ssn/fr_FR/__init__.py | 2 +- faker/providers/ssn/he_IL/__init__.py | 2 +- faker/providers/ssn/hr_HR/__init__.py | 8 +- faker/providers/ssn/hu_HU/__init__.py | 18 +- faker/providers/ssn/it_IT/__init__.py | 6 +- faker/providers/ssn/lb_LU/__init__.py | 2 +- faker/providers/ssn/lt_LT/__init__.py | 2 +- faker/providers/ssn/lv_LV/__init__.py | 2 +- faker/providers/ssn/mt_MT/__init__.py | 2 +- faker/providers/ssn/nl_BE/__init__.py | 4 +- faker/providers/ssn/nl_NL/__init__.py | 4 +- faker/providers/ssn/no_NO/__init__.py | 7 +- faker/providers/ssn/pl_PL/__init__.py | 11 +- faker/providers/ssn/pt_BR/__init__.py | 10 +- faker/providers/ssn/pt_PT/__init__.py | 2 +- faker/providers/ssn/ro_RO/__init__.py | 8 +- faker/providers/ssn/sk_SK/__init__.py | 6 +- faker/providers/ssn/sl_SI/__init__.py | 2 +- faker/providers/ssn/sv_SE/__init__.py | 16 +- faker/providers/ssn/th_TH/__init__.py | 4 +- faker/providers/ssn/tr_TR/__init__.py | 8 +- faker/providers/ssn/uk_UA/__init__.py | 2 +- faker/providers/ssn/zh_CN/__init__.py | 11 +- faker/providers/ssn/zh_TW/__init__.py | 2 +- faker/providers/user_agent/__init__.py | 129 ++++---- faker/proxy.py | 76 ++--- faker/sphinx/docstring.py | 9 +- faker/typing.py | 11 + faker/utils/decorators.py | 14 +- faker/utils/distribution.py | 9 +- faker/utils/loading.py | 9 +- faker/utils/text.py | 13 +- mypy.ini | 11 + tests/providers/test_address.py | 11 +- tests/providers/test_automotive.py | 40 +-- tests/providers/test_barcode.py | 14 +- tests/providers/test_color.py | 14 +- tests/providers/test_company.py | 3 +- tests/providers/test_credit_card.py | 30 +- tests/providers/test_internet.py | 11 +- tests/providers/test_misc.py | 3 +- tests/providers/test_phone_number.py | 46 +-- tests/providers/test_ssn.py | 11 +- tests/providers/test_user_agent.py | 9 +- tox.ini | 9 +- 245 files changed, 2276 insertions(+), 2097 deletions(-) create mode 100644 faker/typing.py create mode 100644 mypy.ini diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e8588a279..6eb64b773d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,14 +29,34 @@ jobs: run: tox env: TOXENV: checkmanifest - - name: isort + - name: Import order checking with isort run: tox env: TOXENV: isort + typing: + runs-on: ubuntu-latest + strategy: + matrix: + python: [3.6, 3.8, "3.10"] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Install dependencies + run: | + python -m pip install tox + - name: Static type checking with mypy + run: tox + env: + TOXENV: mypy + test_ubuntu: runs-on: ubuntu-latest - needs: [lint] + needs: [lint, typing] strategy: matrix: python: [3.6, 3.7, 3.8, 3.9, "pypy3"] @@ -62,7 +82,7 @@ jobs: test_windows: runs-on: windows-latest - needs: [lint] + needs: [lint, typing] strategy: matrix: python: [3.6, 3.7, 3.8, 3.9] @@ -89,7 +109,7 @@ jobs: test_alpine: runs-on: ubuntu-latest - needs: [lint] + needs: [lint, typing] steps: - uses: actions/checkout@v2 @@ -108,7 +128,7 @@ jobs: test_32bit: runs-on: ubuntu-latest - needs: [lint] + needs: [lint, typing] steps: - uses: actions/checkout@v2 @@ -125,7 +145,6 @@ jobs: TOXENV: 32bit TEST_32BIT: 1 - finish: needs: [test_ubuntu, test_windows, test_alpine, test_32bit] runs-on: ubuntu-latest diff --git a/MANIFEST.in b/MANIFEST.in index 72e4bd43f9..f62c9ef56e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,6 +5,7 @@ include CHANGELOG.md include RELEASE_PROCESS.rst include VERSION include CITATION.cff +include mypy.ini recursive-include tests *.json recursive-include tests *.py recursive-exclude faker/sphinx *.py diff --git a/docs/coding_style.rst b/docs/coding_style.rst index 7ceb84305a..ad60e1fb5e 100644 --- a/docs/coding_style.rst +++ b/docs/coding_style.rst @@ -3,7 +3,7 @@ Coding Style Lines length should not exceed 120 characters. Please use trailing commas. -Plese include `type hints`_ for every provider method you write. +Please include `type hints`_ for every provider method you write. An overview of generic types is included below. You can find our complete flake8 configuration in the tox.ini_ file. @@ -22,6 +22,20 @@ Name Lists When you have long lists of names, please order them alphabetically. Keep the lines length as close as possible to 120 characters, without exceeding the limit. + +Type Hints +---------- +`typing.py` includes generic types that can be re-used throughout the codebase. Moreover, some type definitions are +included in other parts of the code. If you add a generic type, please specify its usage below: + +| Type | Used for | +|------|----------| +| `providers.ElementsType` | When creating a variable in a `Provider` (e.g. for a specific locale), which is not defined in the superclass, `self.random_element()`, `self.random_elements()`, `self.random_choices()` and `self.random_sample()` assume this to be the input format. | +| `typing.DateParseType` | Input for various `faker.providers.date_time` functions that parse (relative) dates/times. | +| `typing.HueType` | Hue name, float value or integer range. | +| `typing.GenderType` | String variable that can only have values `'F'` (female) and `'M'` (male) | + + .. _`tox.ini`: https://github.com/joke2k/faker/blob/master/tox.ini .. _`pep 8`: https://python.org/dev/peps/pep-0008 .. _`pep 263`: https://python.org/dev/peps/pep-0263 diff --git a/faker/__main__.py b/faker/__main__.py index 091c5ce75c..489bc21472 100644 --- a/faker/__main__.py +++ b/faker/__main__.py @@ -1,3 +1,3 @@ if __name__ == "__main__": - from faker.cli import execute_from_command_line + from .cli import execute_from_command_line execute_from_command_line() diff --git a/faker/cli.py b/faker/cli.py index cef26c7ea1..c522f98b4d 100644 --- a/faker/cli.py +++ b/faker/cli.py @@ -4,22 +4,27 @@ import random import sys +from io import TextIOWrapper from pathlib import Path -from typing import Any, Dict, List, Optional, TextIO +from typing import Dict, List, Optional, TextIO, TypeVar, Union -from faker import VERSION, Faker, documentor, exceptions -from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE, META_PROVIDERS_MODULES +from . import VERSION, Faker, documentor, exceptions +from .config import AVAILABLE_LOCALES, DEFAULT_LOCALE, META_PROVIDERS_MODULES +from .documentor import Documentor +from .providers import BaseProvider __author__ = 'joke2k' +T = TypeVar('T') -def print_provider(doc, - provider: List[str], - formatters: Dict[str, Any], - excludes=None, - output: Optional[TextIO] = None) -> None: - output = output or sys.stdout +def print_provider(doc: Documentor, + provider: BaseProvider, + formatters: Dict[str, T], + excludes: Optional[List[str]] = None, + output: Optional[TextIO] = None) -> None: + if output is None: + output = sys.stdout if excludes is None: excludes = [] @@ -48,11 +53,16 @@ def print_provider(doc, signature = separator = ' ' -def print_doc(provider_or_field=None, - args=None, lang: str = DEFAULT_LOCALE, output=None, seed=None, - includes=None) -> None: - args = args or [] - output = output or sys.stdout +def print_doc(provider_or_field: Optional[str] = None, + args: Optional[List[T]] = None, + lang: str = DEFAULT_LOCALE, + output: Optional[Union[TextIO, TextIOWrapper]] = None, + seed: Optional[float] = None, + includes: Optional[List[str]] = None) -> None: + if args is None: + args = [] + if output is None: + output = sys.stdout fake = Faker(locale=lang, includes=includes) fake.seed_instance(seed) @@ -86,7 +96,7 @@ def print_doc(provider_or_field=None, else: doc = documentor.Documentor(fake) - unsupported = [] + unsupported: List[str] = [] while True: try: @@ -97,7 +107,6 @@ def print_doc(provider_or_field=None, break for provider, fakers in formatters: - print_provider(doc, provider, fakers, output=output) for language in AVAILABLE_LOCALES: @@ -117,7 +126,7 @@ def print_doc(provider_or_field=None, class Command: - def __init__(self, argv=None) -> None: + def __init__(self, argv: Optional[str] = None) -> None: self.argv = argv or sys.argv[:] self.prog_name = Path(self.argv[0]).name @@ -259,7 +268,7 @@ def execute(self) -> None: break -def execute_from_command_line(argv=None) -> None: +def execute_from_command_line(argv: Optional[str] = None) -> None: """A simple method that runs a Command.""" if sys.stdout.encoding is None: print('please set python env PYTHONIOENCODING=UTF-8, example: ' diff --git a/faker/config.py b/faker/config.py index 306f9de469..30055d9326 100644 --- a/faker/config.py +++ b/faker/config.py @@ -1,6 +1,6 @@ from importlib import import_module -from faker.utils.loading import find_available_locales, find_available_providers +from .utils.loading import find_available_locales, find_available_providers DEFAULT_LOCALE = 'en_US' diff --git a/faker/documentor.py b/faker/documentor.py index 8f28753788..0baaac45e3 100644 --- a/faker/documentor.py +++ b/faker/documentor.py @@ -1,24 +1,33 @@ import inspect import warnings +from typing import Any, Dict, List, Optional, Tuple, Union + +from .generator import Generator +from .providers import BaseProvider +from .proxy import Faker + class Documentor: - def __init__(self, generator): + def __init__(self, generator: Union[Generator, Faker]) -> None: """ :param generator: a localized Generator with providers filled, for which to write the documentation :type generator: faker.Generator() """ self.generator = generator - self.max_name_len = 0 - self.already_generated = [] + self.max_name_len: int = 0 + self.already_generated: List[str] = [] - def get_formatters(self, locale=None, excludes=None, **kwargs): + def get_formatters(self, + locale: Optional[str] = None, + excludes: Optional[List[str]] = None, + **kwargs: Any) -> List[Tuple[BaseProvider, Dict[str, str]]]: self.max_name_len = 0 self.already_generated = [] if excludes is None else excludes[:] formatters = [] - providers = self.generator.get_providers() + providers: List[BaseProvider] = self.generator.get_providers() for provider in providers[::-1]: # reverse if locale and provider.__lang__ != locale: continue @@ -27,9 +36,11 @@ def get_formatters(self, locale=None, excludes=None, **kwargs): ) return formatters - def get_provider_formatters(self, provider, prefix='fake.', - with_args=True, with_defaults=True): - + def get_provider_formatters(self, + provider: BaseProvider, + prefix: str = 'fake.', + with_args: bool = True, + with_defaults: bool = True) -> Dict[str, str]: formatters = {} for name, method in inspect.getmembers(provider, inspect.ismethod): @@ -38,7 +49,7 @@ def get_provider_formatters(self, provider, prefix='fake.', continue arguments = [] - faker_args = [] + faker_args: List[str] = [] faker_kwargs = {} if name == 'binary': @@ -98,5 +109,5 @@ def get_provider_formatters(self, provider, prefix='fake.', return formatters @staticmethod - def get_provider_name(provider_class): + def get_provider_name(provider_class: BaseProvider) -> str: return provider_class.__provider__ diff --git a/faker/exceptions.py b/faker/exceptions.py index 21bc606d4d..5aa03987ce 100644 --- a/faker/exceptions.py +++ b/faker/exceptions.py @@ -10,6 +10,7 @@ class UniquenessException(BaseFakerException): class UnsupportedFeature(BaseFakerException): """The requested feature is not available on this system.""" - def __init__(self, msg, name): + + def __init__(self, msg: str, name: str) -> None: self.name = name super().__init__(msg) diff --git a/faker/factory.py b/faker/factory.py index 39b13998dc..2fac3dd557 100644 --- a/faker/factory.py +++ b/faker/factory.py @@ -3,10 +3,11 @@ import sys from importlib import import_module +from typing import Any, List, Optional, Tuple -from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE, PROVIDERS -from faker.generator import Generator -from faker.utils.loading import list_module +from .config import AVAILABLE_LOCALES, DEFAULT_LOCALE, PROVIDERS +from .generator import Generator +from .utils.loading import list_module logger = logging.getLogger(__name__) @@ -23,14 +24,14 @@ class Factory: @classmethod def create( cls, - locale=None, - providers=None, - generator=None, - includes=None, + locale: Optional[str] = None, + providers: Optional[List[str]] = None, + generator: Generator = None, + includes: Optional[List[str]] = None, # Should we use weightings (more realistic) or weight every element equally (faster)? # By default, use weightings for backwards compatibility & realism - use_weighting=True, - **config): + use_weighting: bool = True, + **config: Any) -> Generator: if includes is None: includes = [] @@ -63,7 +64,7 @@ def create( return faker @classmethod - def _get_provider_class(cls, provider, locale=''): + def _get_provider_class(cls, provider: str, locale: Optional[str] = '') -> Tuple[Any, Optional[str]]: provider_class = cls._find_provider_class(provider, locale) @@ -85,7 +86,7 @@ def _get_provider_class(cls, provider, locale=''): raise ValueError(msg) @classmethod - def _find_provider_class(cls, provider_path, locale=None): + def _find_provider_class(cls, provider_path: str, locale: Optional[str] = None) -> Any: provider_module = import_module(provider_path) @@ -117,4 +118,4 @@ def _find_provider_class(cls, provider_path, locale=None): if locale is not None: provider_module = import_module(provider_path) - return provider_module.Provider + return provider_module.Provider # type: ignore diff --git a/faker/generator.py b/faker/generator.py index 25aed556c5..89bfba40e2 100644 --- a/faker/generator.py +++ b/faker/generator.py @@ -1,6 +1,11 @@ import random as random_module import re +from typing import TYPE_CHECKING, Any, Callable, Dict, Hashable, List, Optional + +if TYPE_CHECKING: + from .providers import BaseProvider + _re_token = re.compile(r'\{\{\s*(\w+)(:\s*\w+?)?\s*\}\}') random = random_module.Random() mod_random = random # compat with name released in 0.8 @@ -8,17 +13,17 @@ class Generator: - __config = { + __config: Dict[str, Dict[Hashable, Any]] = { 'arguments': {}, } - def __init__(self, **config): - self.providers = [] + def __init__(self, **config: Dict) -> None: + self.providers: List["BaseProvider"] = [] self.__config = dict( list(self.__config.items()) + list(config.items())) self.__random = random - def add_provider(self, provider): + def add_provider(self, provider: "BaseProvider") -> None: if isinstance(provider, type): provider = provider(self) @@ -36,27 +41,27 @@ def add_provider(self, provider): # add all faker method to generator self.set_formatter(method_name, faker_function) - def provider(self, name): + def provider(self, name: str) -> Optional["BaseProvider"]: try: lst = [p for p in self.get_providers() - if p.__provider__ == name.lower()] + if hasattr(p, '__provider__') and p.__provider__ == name.lower()] return lst[0] except IndexError: return None - def get_providers(self): + def get_providers(self) -> List["BaseProvider"]: """Returns added providers.""" return self.providers @property - def random(self): + def random(self) -> random_module.Random: return self.__random @random.setter - def random(self, value): + def random(self, value: random_module.Random) -> None: self.__random = value - def seed_instance(self, seed=None): + def seed_instance(self, seed: Optional[Hashable] = None) -> "Generator": """Calls random.seed""" if self.__random == random: # create per-instance random obj when first time seed_instance() is @@ -66,16 +71,16 @@ def seed_instance(self, seed=None): return self @classmethod - def seed(cls, seed=None): + def seed(cls, seed: Optional[Hashable] = None) -> None: random.seed(seed) - def format(self, formatter, *args, **kwargs): + def format(self, formatter: str, *args: Any, **kwargs: Any) -> str: """ This is a secure way to make a fake from another Provider. """ return self.get_formatter(formatter)(*args, **kwargs) - def get_formatter(self, formatter): + def get_formatter(self, formatter: str) -> Callable: try: return getattr(self, formatter) except AttributeError: @@ -85,14 +90,14 @@ def get_formatter(self, formatter): raise AttributeError(f'Unknown formatter {formatter!r}') raise AttributeError(msg) - def set_formatter(self, name, method): + def set_formatter(self, name: str, method: Callable) -> None: """ This method adds a provider method to generator. Override this method to add some decoration or logging stuff. """ setattr(self, name, method) - def set_arguments(self, group, argument, value=None): + def set_arguments(self, group: str, argument: str, value: Optional[Any] = None) -> None: """ Creates an argument group, with an individual argument or a dictionary of arguments. The argument groups is used to apply arguments to tokens, @@ -112,7 +117,7 @@ def set_arguments(self, group, argument, value=None): else: self.__config['arguments'][group][argument] = value - def get_arguments(self, group, argument=None): + def get_arguments(self, group: str, argument: Optional[str] = None) -> Any: """ Get the value of an argument configured within a argument group, or the entire group as a dictionary. Used in conjunction with the @@ -128,7 +133,7 @@ def get_arguments(self, group, argument=None): return result - def del_arguments(self, group, argument=None): + def del_arguments(self, group: str, argument: Optional[str] = None) -> Any: """ Delete an argument from an argument group or the entire argument group. Used in conjunction with the set_arguments() method. @@ -146,7 +151,7 @@ def del_arguments(self, group, argument=None): return result - def parse(self, text): + def parse(self, text: str) -> str: """ Replaces tokens like '{{ tokenName }}' or '{{tokenName}}' in a string with the result from the token method call. Arguments can be parsed by using an diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py index e976f1571d..62e04d1a52 100644 --- a/faker/providers/__init__.py +++ b/faker/providers/__init__.py @@ -2,8 +2,9 @@ import string from collections import OrderedDict +from typing import Any, Dict, KeysView, Optional, Sequence, TypeVar, Union -from faker.utils.distribution import choices_distribution, choices_distribution_unique +from ..utils.distribution import choices_distribution, choices_distribution_unique _re_hash = re.compile(r'#') _re_perc = re.compile(r'%') @@ -12,6 +13,9 @@ _re_qm = re.compile(r'\?') _re_cir = re.compile(r'\^') +T = TypeVar('T') +ElementsType = Union[Sequence[T], Dict[T, float], KeysView[T]] + class BaseProvider: @@ -81,10 +85,10 @@ class BaseProvider: 'zu': ('ZA',), } - def __init__(self, generator): + def __init__(self, generator: Any) -> None: self.generator = generator - def locale(self): + def locale(self) -> str: """Generate a random underscored i18n locale code (e.g. en_US). :sample: @@ -94,14 +98,14 @@ def locale(self): BaseProvider.language_locale_codes[language_code], ) - def language_code(self): + def language_code(self) -> str: """Generate a random i18n language code (e.g. en). :sample: """ return self.random_element(BaseProvider.language_locale_codes.keys()) - def random_int(self, min=0, max=9999, step=1): + def random_int(self, min: int = 0, max: int = 9999, step: int = 1) -> int: """Generate a random integer between two integers ``min`` and ``max`` inclusive while observing the provided ``step`` value. @@ -114,21 +118,21 @@ def random_int(self, min=0, max=9999, step=1): """ return self.generator.random.randrange(min, max + 1, step) - def random_digit(self): + def random_digit(self) -> int: """Generate a random digit (0 to 9). :sample: """ return self.generator.random.randint(0, 9) - def random_digit_not_null(self): + def random_digit_not_null(self) -> int: """Generate a random non-zero digit (1 to 9). :sample: """ return self.generator.random.randint(1, 9) - def random_digit_or_empty(self): + def random_digit_or_empty(self) -> Union[int, str]: """Generate a random digit (0 to 9) or an empty string. This method will return an empty string 50% of the time, @@ -141,7 +145,7 @@ def random_digit_or_empty(self): else: return '' - def random_digit_not_null_or_empty(self): + def random_digit_not_null_or_empty(self) -> Union[int, str]: """Generate a random non-zero digit (1 to 9) or an empty string. This method will return an empty string 50% of the time, @@ -154,7 +158,7 @@ def random_digit_not_null_or_empty(self): else: return '' - def random_number(self, digits=None, fix_len=False): + def random_number(self, digits: Optional[int] = None, fix_len: bool = False) -> int: """Generate a random integer according to the following rules: - If ``digits`` is ``None`` (default), its value will be set to a random @@ -183,7 +187,7 @@ def random_number(self, digits=None, fix_len=False): else: return self.generator.random.randint(0, pow(10, digits) - 1) - def random_letter(self): + def random_letter(self) -> str: """Generate a random ASCII letter (a-z and A-Z). :sample: @@ -191,7 +195,7 @@ def random_letter(self): return self.generator.random.choice( getattr(string, 'letters', string.ascii_letters)) - def random_letters(self, length=16): + def random_letters(self, length: int = 16) -> Sequence[str]: """Generate a list of random ASCII letters (a-z and A-Z) of the specified ``length``. :sample: @@ -202,22 +206,25 @@ def random_letters(self, length=16): length=length, ) - def random_lowercase_letter(self): + def random_lowercase_letter(self) -> str: """Generate a random lowercase ASCII letter (a-z). :sample: """ return self.generator.random.choice(string.ascii_lowercase) - def random_uppercase_letter(self): + def random_uppercase_letter(self) -> str: """Generate a random uppercase ASCII letter (A-Z). :sample: """ return self.generator.random.choice(string.ascii_uppercase) - def random_elements(self, elements=('a', 'b', 'c'), length=None, unique=False, - use_weighting=None): + def random_elements(self, + elements: ElementsType = ('a', 'b', 'c'), + length: Optional[int] = None, + unique: bool = False, + use_weighting: Optional[bool] = None) -> Sequence[T]: """Generate a list of randomly sampled objects from ``elements``. Set ``unique`` to ``False`` for random sampling with replacement, and set ``unique`` to @@ -291,9 +298,9 @@ def random_elements(self, elements=('a', 'b', 'c'), length=None, unique=False, if isinstance(elements, dict): if not hasattr(elements, "_key_cache"): - elements._key_cache = tuple(elements.keys()) + elements._key_cache = tuple(elements.keys()) # type: ignore - choices = elements._key_cache + choices = elements._key_cache # type: ignore[attr-defined] probabilities = tuple(elements.values()) if use_weighting else None else: if unique: @@ -309,7 +316,9 @@ def random_elements(self, elements=('a', 'b', 'c'), length=None, unique=False, length=length, ) - def random_choices(self, elements=('a', 'b', 'c'), length=None): + def random_choices(self, + elements: ElementsType = ('a', 'b', 'c'), + length: Optional[int] = None) -> Sequence[T]: """Generate a list of objects randomly sampled from ``elements`` with replacement. For information on the ``elements`` and ``length`` arguments, please refer to @@ -333,7 +342,8 @@ def random_choices(self, elements=('a', 'b', 'c'), length=None): """ return self.random_elements(elements, length, unique=False) - def random_element(self, elements=('a', 'b', 'c')): + def random_element(self, + elements: ElementsType = ('a', 'b', 'c')) -> T: """Generate a randomly sampled object from ``elements``. For information on the ``elements`` argument, please refer to @@ -352,7 +362,9 @@ def random_element(self, elements=('a', 'b', 'c')): return self.random_elements(elements, length=1)[0] - def random_sample(self, elements=('a', 'b', 'c'), length=None): + def random_sample(self, + elements: ElementsType = ('a', 'b', 'c'), + length: Optional[int] = None) -> Sequence[T]: """Generate a list of objects randomly sampled from ``elements`` without replacement. For information on the ``elements`` and ``length`` arguments, please refer to @@ -364,13 +376,12 @@ def random_sample(self, elements=('a', 'b', 'c'), length=None): """ return self.random_elements(elements, length, unique=True) - def randomize_nb_elements( - self, - number=10, - le=False, - ge=False, - min=None, - max=None): + def randomize_nb_elements(self, + number: int = 10, + le: bool = False, + ge: bool = False, + min: Optional[int] = None, + max: Optional[int] = None) -> int: """Generate a random integer near ``number`` according to the following rules: - If ``le`` is ``False`` (default), allow generation up to 140% of ``number``. @@ -402,7 +413,7 @@ def randomize_nb_elements( nb = max return nb - def numerify(self, text='###'): + def numerify(self, text: str = '###') -> str: """Generate a string with each placeholder in ``text`` replaced according to the following rules: @@ -434,7 +445,7 @@ def numerify(self, text='###'): text) return text - def lexify(self, text='????', letters=string.ascii_letters): + def lexify(self, text: str = '????', letters: str = string.ascii_letters) -> str: """Generate a string with each question mark ('?') in ``text`` replaced with a random character from ``letters``. @@ -445,9 +456,8 @@ def lexify(self, text='????', letters=string.ascii_letters): """ return _re_qm.sub(lambda x: self.random_element(letters), text) - def bothify(self, text='## ??', letters=string.ascii_letters): - """Generate a string with each placeholder in ``text`` replaced according - to the following rules: + def bothify(self, text: str = '## ??', letters: str = string.ascii_letters) -> str: + """Generate a string with each placeholder in ``text`` replaced according to the following rules: - Number signs ('#') are replaced with a random digit (0 to 9). - Question marks ('?') are replaced with a random character from ``letters``. @@ -464,7 +474,7 @@ def bothify(self, text='## ??', letters=string.ascii_letters): """ return self.lexify(self.numerify(text), letters=letters) - def hexify(self, text='^^^^', upper=False): + def hexify(self, text: str = '^^^^', upper: bool = False) -> str: """Generate a string with each circumflex ('^') in ``text`` replaced with a random hexadecimal character. diff --git a/faker/providers/address/__init__.py b/faker/providers/address/__init__.py index 267f1f4966..2bed931277 100644 --- a/faker/providers/address/__init__.py +++ b/faker/providers/address/__init__.py @@ -1,81 +1,81 @@ -from .. import BaseProvider, date_time +from .. import BaseProvider, ElementsType, date_time localized = True class Provider(BaseProvider): - city_suffixes = ['Ville'] - street_suffixes = ['Street'] - city_formats = ('{{first_name}} {{city_suffix}}', ) - street_name_formats = ('{{last_name}} {{street_suffix}}', ) - street_address_formats = ('{{building_number}} {{street_name}}', ) - address_formats = ('{{street_address}} {{postcode}} {{city}}', ) - building_number_formats = ('##', ) - postcode_formats = ('#####', ) - countries = [tz['name'] for tz in date_time.Provider.countries] + city_suffixes: ElementsType = ['Ville'] + street_suffixes: ElementsType = ['Street'] + city_formats: ElementsType = ('{{first_name}} {{city_suffix}}', ) + street_name_formats: ElementsType = ('{{last_name}} {{street_suffix}}', ) + street_address_formats: ElementsType = ('{{building_number}} {{street_name}}', ) + address_formats: ElementsType = ('{{street_address}} {{postcode}} {{city}}', ) + building_number_formats: ElementsType = ('##', ) + postcode_formats: ElementsType = ('#####', ) + countries: ElementsType = [tz['name'] for tz in date_time.Provider.countries] ALPHA_2 = 'alpha-2' ALPHA_3 = 'alpha-3' - alpha_2_country_codes = [tz['alpha-2-code'] for tz in date_time.Provider.countries] - alpha_3_country_codes = [tz['alpha-3-code'] for tz in date_time.Provider.countries] + alpha_2_country_codes: ElementsType = [tz['alpha-2-code'] for tz in date_time.Provider.countries] + alpha_3_country_codes: ElementsType = [tz['alpha-3-code'] for tz in date_time.Provider.countries] - def city_suffix(self): + def city_suffix(self) -> str: """ :example 'town' """ return self.random_element(self.city_suffixes) - def street_suffix(self): + def street_suffix(self) -> str: """ :example 'Avenue' """ return self.random_element(self.street_suffixes) - def building_number(self): + def building_number(self) -> str: """ :example '791' """ return self.numerify(self.random_element(self.building_number_formats)) - def city(self): + def city(self) -> str: """ :example 'Sashabury' """ - pattern = self.random_element(self.city_formats) + pattern: str = self.random_element(self.city_formats) return self.generator.parse(pattern) - def street_name(self): + def street_name(self) -> str: """ :example 'Crist Parks' """ - pattern = self.random_element(self.street_name_formats) + pattern: str = self.random_element(self.street_name_formats) return self.generator.parse(pattern) - def street_address(self): + def street_address(self) -> str: """ :example '791 Crist Parks' """ - pattern = self.random_element(self.street_address_formats) + pattern: str = self.random_element(self.street_address_formats) return self.generator.parse(pattern) - def postcode(self): + def postcode(self) -> str: """ :example 86039-9874 """ return self.bothify(self.random_element(self.postcode_formats)).upper() - def address(self): + def address(self) -> str: """ :example '791 Crist Parks, Sashabury, IL 86039-9874' """ - pattern = self.random_element(self.address_formats) + pattern: str = self.random_element(self.address_formats) return self.generator.parse(pattern) - def country(self): + def country(self) -> str: return self.random_element(self.countries) - def country_code(self, representation=ALPHA_2): + def country_code(self, representation: str = ALPHA_2) -> str: if representation == self.ALPHA_2: return self.random_element(self.alpha_2_country_codes) elif representation == self.ALPHA_3: @@ -83,19 +83,19 @@ def country_code(self, representation=ALPHA_2): else: raise ValueError("`representation` must be one of `alpha-2` or `alpha-3`.") - def current_country_code(self): + def current_country_code(self) -> str: try: - return self.__lang__.split("_")[1] + return self.__lang__.split("_")[1] # type: ignore except IndexError: raise AttributeError("Country code cannot be determined from locale") - def current_country(self): + def current_country(self) -> str: current_country_code = self.current_country_code() current_country = [tz['name'] for tz in date_time.Provider.countries if tz['alpha-2-code'] == current_country_code] if len(current_country) == 1: - return current_country[0] + return current_country[0] # type: ignore elif len(current_country) > 1: raise ValueError(f"Ambiguous country for country code {current_country_code}: {current_country}") else: diff --git a/faker/providers/address/cs_CZ/__init__.py b/faker/providers/address/cs_CZ/__init__.py index 97c796a031..1bd1cc6583 100644 --- a/faker/providers/address/cs_CZ/__init__.py +++ b/faker/providers/address/cs_CZ/__init__.py @@ -748,22 +748,22 @@ class Provider(AddressProvider): 'Švédsko', 'Švýcarsko') - def street_suffix_short(self): + def street_suffix_short(self) -> str: return self.random_element(self.street_suffixes_short) - def street_suffix_long(self): + def street_suffix_long(self) -> str: return self.random_element(self.street_suffixes_long) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.streets) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def city_with_postcode(self): + def city_with_postcode(self) -> str: return self.postcode() + " " + self.random_element(self.cities) diff --git a/faker/providers/address/da_DK/__init__.py b/faker/providers/address/da_DK/__init__.py index 64e21dc093..8594155ba5 100644 --- a/faker/providers/address/da_DK/__init__.py +++ b/faker/providers/address/da_DK/__init__.py @@ -97,13 +97,13 @@ class Provider(AddressProvider): 'Hovedstaden', 'Midtjylland', 'Nordjylland', 'Sjælland', 'Syddanmark', ) - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element(self.street_prefixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/de_AT/__init__.py b/faker/providers/address/de_AT/__init__.py index 4358050f2a..18393e6b12 100644 --- a/faker/providers/address/de_AT/__init__.py +++ b/faker/providers/address/de_AT/__init__.py @@ -70,20 +70,20 @@ class Provider(AddressProvider): 'Oberösterreich', 'Salzburg', 'Kärnten', 'Vorarlberg', ) - def street_suffix_short(self): + def street_suffix_short(self) -> str: return self.random_element(self.street_suffixes_short) - def street_suffix_long(self): + def street_suffix_long(self) -> str: return self.random_element(self.street_suffixes_long) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def city_with_postcode(self): - pattern = self.random_element(self.city_with_postcode_formats) + def city_with_postcode(self) -> str: + pattern: str = self.random_element(self.city_with_postcode_formats) return self.generator.parse(pattern) diff --git a/faker/providers/address/de_CH/__init__.py b/faker/providers/address/de_CH/__init__.py index 136c47f29c..ec84769046 100644 --- a/faker/providers/address/de_CH/__init__.py +++ b/faker/providers/address/de_CH/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as AddressProvider @@ -20,14 +22,14 @@ class Provider(AddressProvider): ('SZ', 'Schwyz'), ('TG', 'Thurgau'), ('TI', 'Tessin'), ('UR', 'Uri'), ('VD', 'Waadt'), ('VS', 'Wallis'), ('ZG', 'Zug'), ('ZH', 'Zürich')) - def canton(self): + def canton(self) -> Tuple[str, str]: """ Randomly returns a swiss canton ('Abbreviated', 'Name'). :example ('ZH', 'Zürich') """ return self.random_element(self.cantons) - def administrative_unit(self): + def administrative_unit(self) -> str: """ Randomly returns a Swiss canton name. :example 'Zürich' @@ -36,7 +38,7 @@ def administrative_unit(self): canton_name = administrative_unit - def canton_code(self): + def canton_code(self) -> str: """ Randomly returns a Swiss canton code. :example 'ZH' diff --git a/faker/providers/address/de_DE/__init__.py b/faker/providers/address/de_DE/__init__.py index ee29274860..a01598a53b 100644 --- a/faker/providers/address/de_DE/__init__.py +++ b/faker/providers/address/de_DE/__init__.py @@ -113,20 +113,20 @@ class Provider(AddressProvider): 'Sachsen-Anhalt', 'Schleswig-Holstein', 'Thüringen', ) - def street_suffix_short(self): + def street_suffix_short(self) -> str: return self.random_element(self.street_suffixes_short) - def street_suffix_long(self): + def street_suffix_long(self) -> str: return self.random_element(self.street_suffixes_long) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def city_with_postcode(self): - pattern = self.random_element(self.city_with_postcode_formats) + def city_with_postcode(self) -> str: + pattern: str = self.random_element(self.city_with_postcode_formats) return self.generator.parse(pattern) diff --git a/faker/providers/address/el_GR/__init__.py b/faker/providers/address/el_GR/__init__.py index 73216598b5..605aa17b79 100644 --- a/faker/providers/address/el_GR/__init__.py +++ b/faker/providers/address/el_GR/__init__.py @@ -54,28 +54,28 @@ class Provider(AddressProvider): "{{street_address}}, {{postcode}} {{city}}", ) - def line_address(self): - pattern = self.random_element(self.line_address_formats) + def line_address(self) -> str: + pattern: str = self.random_element(self.line_address_formats) return self.generator.parse(pattern) - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element( self.street_prefixes_short + self.street_prefixes_long) - def street_prefix_short(self): + def street_prefix_short(self) -> str: return self.random_element(self.street_prefixes_short) - def street_prefix_long(self): + def street_prefix_long(self) -> str: return self.random_element(self.street_prefixes_long) - def street(self): + def street(self) -> str: return self.random_element(self.localities) - def city(self): + def city(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.regions) region = administrative_unit diff --git a/faker/providers/address/en_AU/__init__.py b/faker/providers/address/en_AU/__init__.py index 6a2350fbdf..ceace95c32 100644 --- a/faker/providers/address/en_AU/__init__.py +++ b/faker/providers/address/en_AU/__init__.py @@ -123,18 +123,18 @@ class Provider(AddressProvider): secondary_address_formats = ('Apt. ### ', 'Flat ## ', 'Suite ### ', 'Unit ## ', 'Level # ', '###/', '##/', '#/') - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: return self.random_element(self.states_abbr) diff --git a/faker/providers/address/en_CA/__init__.py b/faker/providers/address/en_CA/__init__.py index ddcaa7303e..3b92f3cd47 100644 --- a/faker/providers/address/en_CA/__init__.py +++ b/faker/providers/address/en_CA/__init__.py @@ -1,5 +1,7 @@ import re +from typing import Optional + from ..en import Provider as AddressProvider @@ -305,32 +307,32 @@ class Provider(AddressProvider): ) secondary_address_formats = ('Apt. ###', 'Suite ###') - def administrative_unit(self): + def administrative_unit(self) -> str: """ """ return self.random_element(self.provinces) province = administrative_unit - def province_abbr(self): + def province_abbr(self) -> str: return self.random_element(self.provinces_abbr) - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def postal_code_letter(self): + def postal_code_letter(self) -> str: """ Returns a random letter from the list of allowable letters in a canadian postal code """ return self.random_element(self.postal_code_letters) - def _postcode_replace(self, postal_code_format): + def _postcode_replace(self, postal_code_format: str) -> str: """ Replaces all question mark ('?') occurrences with a random letter from given postal_code_format, then passes result to numerify to insert @@ -341,14 +343,14 @@ def _postcode_replace(self, postal_code_format): postal_code_format) return self.numerify(temp) - def postcode(self): + def postcode(self) -> str: """ Returns a random postcode """ return self._postcode_replace( self.random_element(self.postal_code_formats)) - def postcode_in_province(self, province_abbr=None): + def postcode_in_province(self, province_abbr: Optional[str] = None) -> str: """ Returns a random postcode within the provided province abbreviation """ @@ -356,7 +358,7 @@ def postcode_in_province(self, province_abbr=None): province_abbr = self.random_element(self.provinces_abbr) if province_abbr in self.provinces_abbr: - postal_code_format = self.random_element(self.postal_code_formats) + postal_code_format: str = self.random_element(self.postal_code_formats) postal_code_format = postal_code_format.replace( '?', self.generator.random_element( @@ -366,8 +368,8 @@ def postcode_in_province(self, province_abbr=None): else: raise Exception('Province Abbreviation not found in list') - def postalcode_in_province(self, province_abbr=None): + def postalcode_in_province(self, province_abbr: Optional[str] = None) -> str: return self.postcode_in_province(province_abbr) - def postalcode(self): + def postalcode(self) -> str: return self.postcode() diff --git a/faker/providers/address/en_GB/__init__.py b/faker/providers/address/en_GB/__init__.py index 4d293d3a11..f399bec7c2 100644 --- a/faker/providers/address/en_GB/__init__.py +++ b/faker/providers/address/en_GB/__init__.py @@ -409,24 +409,24 @@ class Provider(AddressProvider): secondary_address_formats = ( 'Flat #', 'Flat ##', 'Flat ##?', 'Studio #', 'Studio ##', 'Studio ##?') - def postcode(self): + def postcode(self) -> str: """ See http://web.archive.org/web/20090930140939/http://www.govtalk.gov.uk/gdsc/html/noframes/PostCode-2-1-Release.htm """ postcode = '' - pattern = self.random_element(self.postcode_formats) + pattern: str = self.random_element(self.postcode_formats) for placeholder in pattern: postcode += self.random_element(self._postcode_sets[placeholder]) return postcode - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.bothify(self.random_element(self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.counties) county = administrative_unit diff --git a/faker/providers/address/en_IE/__init__.py b/faker/providers/address/en_IE/__init__.py index 64deb31821..c385c03425 100644 --- a/faker/providers/address/en_IE/__init__.py +++ b/faker/providers/address/en_IE/__init__.py @@ -17,15 +17,15 @@ class Provider(AddressProvider): ('L', 'ACDEFHKNPRTVWXY'), ('A', 'ACDEFHKNPRTVWXY0123456789'), )) - postcode_pattern = "LNN AAAA" + postcode_pattern: str = "LNN AAAA" - def postcode(self): + def postcode(self) -> str: postcode = '' for placeholder in self.postcode_pattern: postcode += self.random_element(self._postcode_sets[placeholder]) return postcode - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.counties) county = administrative_unit diff --git a/faker/providers/address/en_IN/__init__.py b/faker/providers/address/en_IN/__init__.py index da23535da1..bb4376997a 100644 --- a/faker/providers/address/en_IN/__init__.py +++ b/faker/providers/address/en_IN/__init__.py @@ -392,10 +392,10 @@ class Provider(AddressProvider): 'West Bengal', ) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/en_NZ/__init__.py b/faker/providers/address/en_NZ/__init__.py index 8f9fc0af72..c4fb2f76f9 100644 --- a/faker/providers/address/en_NZ/__init__.py +++ b/faker/providers/address/en_NZ/__init__.py @@ -224,25 +224,25 @@ class Provider(AddressProvider): 'Level %', ) - def te_reo_part(self): + def te_reo_part(self) -> str: return self.random_element(self.te_reo_parts) - def te_reo_first(self): - return self.random_element(self.te_reo_parts).capitalize() + def te_reo_first(self) -> str: + return str(self.random_element(self.te_reo_parts)).capitalize() - def te_reo_ending(self): + def te_reo_ending(self) -> str: return self.random_element(self.te_reo_parts + self.te_reo_endings) - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def city_suffix(self): + def city_suffix(self) -> str: return self.random_element(self.city_suffixes) - def rd_number(self): + def rd_number(self) -> str: return self.random_element([str(i) for i in range(1, 11)]) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) diff --git a/faker/providers/address/en_PH/__init__.py b/faker/providers/address/en_PH/__init__.py index 1e0a013f07..5e7723517c 100644 --- a/faker/providers/address/en_PH/__init__.py +++ b/faker/providers/address/en_PH/__init__.py @@ -1,5 +1,6 @@ from collections import OrderedDict from string import ascii_uppercase +from typing import Sequence, Tuple, Union from .. import Provider as AddressProvider @@ -357,7 +358,7 @@ class Provider(AddressProvider): (mindanao_province_address_formats, 0.239017), ]) - def _ordinal_string(self, num): + def _ordinal_string(self, num: Union[int, str]) -> str: if isinstance(num, str): num = int(num) suffix = ['th', 'st', 'nd', 'rd', 'th'][min(num % 10, 4)] @@ -365,109 +366,109 @@ def _ordinal_string(self, num): suffix = 'th' return str(num) + suffix - def _create_postcode(self, postcodes): + def _create_postcode(self, postcodes: Sequence[int]) -> str: return f'{self.random_element(postcodes):04d}' - def _create_address(self, address_formats): + def _create_address(self, address_formats: Tuple[str]) -> str: return self.generator.parse(self.random_element(address_formats)) - def metro_manila_postcode(self): + def metro_manila_postcode(self) -> str: return self._create_postcode(self.metro_manila_postcodes) - def luzon_province_postcode(self): + def luzon_province_postcode(self) -> str: return self._create_postcode(self.luzon_province_postcodes) - def visayas_province_postcode(self): + def visayas_province_postcode(self) -> str: return self._create_postcode(self.visayas_province_postcodes) - def mindanao_province_postcode(self): + def mindanao_province_postcode(self) -> str: return self._create_postcode(self.mindanao_province_postcodes) - def postcode(self): + def postcode(self) -> str: return self._create_postcode(self.postcodes) - def luzon_province(self): + def luzon_province(self) -> str: return self.random_element(self.luzon_provinces) - def visayas_province(self): + def visayas_province(self) -> str: return self.random_element(self.visayas_provinces) - def mindanao_province(self): + def mindanao_province(self) -> str: return self.random_element(self.mindanao_provinces) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.provinces) province = administrative_unit - def standalone_building_number(self): + def standalone_building_number(self) -> str: return str(self.random_int(min=1)) - def partitioned_building_number(self): - pattern = self.lexify( + def partitioned_building_number(self) -> str: + pattern: str = self.lexify( self.random_element(self.partitioned_building_number_formats), letters=ascii_uppercase[:10], ) return self.generator.parse(pattern) - def building_number(self): + def building_number(self) -> str: if self.random_int() % 2 == 0: return self.standalone_building_number() else: return self.partitioned_building_number() - def ordinal_street_number(self): + def ordinal_street_number(self) -> str: return self._ordinal_string(self.random_int(1, 99)) - def floor_number(self): + def floor_number(self) -> str: return self.random_element(self.floor_numbers) - def ordinal_floor_number(self): + def ordinal_floor_number(self) -> str: return self._ordinal_string(self.floor_number()) - def floor_unit_number(self): + def floor_unit_number(self) -> str: return f'{self.floor_number()}{self.random_int(1, 40):02d}' - def building_unit_number(self): + def building_unit_number(self) -> str: return self.generator.parse(self.random_element(self.building_unit_number_formats)) - def building_name(self): + def building_name(self) -> str: return self.generator.parse(self.random_element(self.building_name_formats)) - def building_name_suffix(self): + def building_name_suffix(self) -> str: return self.numerify(self.random_element(self.building_name_suffixes)) - def subdivision_block_number(self): + def subdivision_block_number(self) -> str: return f'{self.random_int(1, 25):02d}' - def subdivision_lot_number(self): + def subdivision_lot_number(self) -> str: return f'{self.random_int(1, 99):02d}' - def subdivision_unit_number(self): + def subdivision_unit_number(self) -> str: return self.generator.parse(self.random_element(self.subdivision_unit_number_formats)) - def subdivision_name(self): + def subdivision_name(self) -> str: return self.generator.parse(self.random_element(self.subdivision_name_formats)) - def subdivision_name_suffix(self): + def subdivision_name_suffix(self) -> str: return self.numerify(self.random_element(self.subdivision_name_suffixes)) - def metro_manila_lgu(self): + def metro_manila_lgu(self) -> str: return self.random_element(self.metro_manila_lgus) - def province_lgu(self): + def province_lgu(self) -> str: return self.random_element(self.province_lgus) - def metro_manila_address(self): + def metro_manila_address(self) -> str: return self._create_address(self.metro_manila_address_formats) - def luzon_province_address(self): + def luzon_province_address(self) -> str: return self._create_address(self.luzon_province_address_formats) - def visayas_province_address(self): + def visayas_province_address(self) -> str: return self._create_address(self.visayas_province_address_formats) - def mindanao_province_address(self): + def mindanao_province_address(self) -> str: return self._create_address(self.mindanao_province_address_formats) - def address(self): + def address(self) -> str: return self._create_address(self.random_element(self.address_formats)) diff --git a/faker/providers/address/en_US/__init__.py b/faker/providers/address/en_US/__init__.py index f87f5f2b3f..6d6ed72de0 100644 --- a/faker/providers/address/en_US/__init__.py +++ b/faker/providers/address/en_US/__init__.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from typing import Optional from ..en import Provider as AddressProvider @@ -329,34 +330,30 @@ class Provider(AddressProvider): '{{building_number}} {{street_name}} {{secondary_address}}', ) - address_formats = ( - "{{street_address}}\n{{city}}, {{state_abbr}} {{postcode}}", - ) - address_formats = OrderedDict(( - ("{{street_address}}\n{{city}}, {{state_abbr}} {{postcode}}", 25), + ("{{street_address}}\n{{city}}, {{state_abbr}} {{postcode}}", 25.), # military address formatting. - ("{{military_apo}}\nAPO {{military_state}} {{postcode}}", 1), - ("{{military_ship}} {{last_name}}\nFPO {{military_state}} {{postcode}}", 1), - ("{{military_dpo}}\nDPO {{military_state}} {{postcode}}", 1), + ("{{military_apo}}\nAPO {{military_state}} {{postcode}}", 1.), + ("{{military_ship}} {{last_name}}\nFPO {{military_state}} {{postcode}}", 1.), + ("{{military_dpo}}\nDPO {{military_state}} {{postcode}}", 1.), )) secondary_address_formats = ('Apt. ###', 'Suite ###') - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def state_abbr(self, include_territories=True): + def state_abbr(self, include_territories: bool = True) -> str: """ :returns: A random state or territory abbreviation. @@ -367,14 +364,14 @@ def state_abbr(self, include_territories=True): self.random_element(self.states_and_territories_abbr) return self.random_element(self.states_abbr) - def postcode(self): + def postcode(self) -> str: return "%05d" % self.generator.random.randint(501, 99950) - def zipcode_plus4(self): + def zipcode_plus4(self) -> str: return "%s-%04d" % (self.zipcode(), self.generator.random.randint(1, 9999)) - def postcode_in_state(self, state_abbr=None): + def postcode_in_state(self, state_abbr: Optional[str] = None) -> str: """ :returns: A random postcode within the provided state abbreviation @@ -385,8 +382,8 @@ def postcode_in_state(self, state_abbr=None): if state_abbr in self.states_abbr: postcode = "%d" % (self.generator.random.randint( - self.states_postcode[state_abbr][0], - self.states_postcode[state_abbr][1])) + self.states_postcode[state_abbr][0], + self.states_postcode[state_abbr][1])) if len(postcode) == 4: postcode = "0%s" % postcode @@ -396,42 +393,42 @@ def postcode_in_state(self, state_abbr=None): else: raise Exception('State Abbreviation not found in list') - def military_ship(self): + def military_ship(self) -> str: """ :example 'USS' """ return self.random_element(self.military_ship_prefix) - def military_state(self): + def military_state(self) -> str: """ :example 'APO' """ return self.random_element(self.military_state_abbr) - def military_apo(self): + def military_apo(self) -> str: """ :example 'PSC 5394 Box 3492 """ return self.numerify(self.military_apo_format) - def military_dpo(self): + def military_dpo(self) -> str: """ :example 'Unit 3333 Box 9342' """ return self.numerify(self.military_dpo_format) # Aliases - def zipcode(self): + def zipcode(self) -> str: return self.postcode() - def zipcode_in_state(self, state_abbr=None): + def zipcode_in_state(self, state_abbr: Optional[str] = None) -> str: return self.postcode_in_state(state_abbr) - def postalcode(self): + def postalcode(self) -> str: return self.postcode() - def postalcode_in_state(self, state_abbr=None): + def postalcode_in_state(self, state_abbr: Optional[str] = None) -> str: return self.postcode_in_state(state_abbr) - def postalcode_plus4(self): + def postalcode_plus4(self) -> str: return self.zipcode_plus4() diff --git a/faker/providers/address/es_ES/__init__.py b/faker/providers/address/es_ES/__init__.py index 494116b350..8d42f68a7c 100644 --- a/faker/providers/address/es_ES/__init__.py +++ b/faker/providers/address/es_ES/__init__.py @@ -105,23 +105,23 @@ class Provider(AddressProvider): ) secondary_address_formats = ('Apt. ##', 'Piso #', 'Puerta #') - def state_name(self): + def state_name(self) -> str: return self.random_element(self.states) - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element(self.street_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def region(self): + def region(self) -> str: return self.random_element(self.regions) autonomous_community = region diff --git a/faker/providers/address/es_MX/__init__.py b/faker/providers/address/es_MX/__init__.py index c8039735d1..e09e5ac5ba 100644 --- a/faker/providers/address/es_MX/__init__.py +++ b/faker/providers/address/es_MX/__init__.py @@ -91,22 +91,22 @@ class Provider(AddressProvider): secondary_address_formats = ('### ###', '### Interior ###', '### Edif. ### , Depto. ###') - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def city_suffix(self): + def city_suffix(self) -> str: return self.random_element(self.city_suffixes) - def city_adjective(self): + def city_adjective(self) -> str: return self.random_element(self.city_adjectives) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'Avenida' """ return self.random_element(self.street_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: """ :example '020 Interior 999' """ @@ -114,16 +114,16 @@ def secondary_address(self): self.random_element( self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: """ example: u'Guerrero' """ - return self.random_element(self.states)[1] + return self.random_element(self.states)[1] # type: ignore state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: """ example: u'GRO' """ - return self.random_element(self.states)[0] + return self.random_element(self.states)[0] # type: ignore diff --git a/faker/providers/address/fa_IR/__init__.py b/faker/providers/address/fa_IR/__init__.py index 2bea2c7dcc..fd0c27028e 100644 --- a/faker/providers/address/fa_IR/__init__.py +++ b/faker/providers/address/fa_IR/__init__.py @@ -74,15 +74,15 @@ class Provider(AddressProvider): ) secondary_address_formats = ('سوئیت ###', 'واحد ###') - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/fi_FI/__init__.py b/faker/providers/address/fi_FI/__init__.py index 9ea65fb694..4df605c0ee 100644 --- a/faker/providers/address/fi_FI/__init__.py +++ b/faker/providers/address/fi_FI/__init__.py @@ -155,13 +155,13 @@ class Provider(AddressProvider): 'Ylänkö', 'Ylätuvan', 'Yrjö-Koskisen ', 'Yrjön', 'Yrttimaan', 'Zaidan', ) - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element(self.street_prefixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/fr_CH/__init__.py b/faker/providers/address/fr_CH/__init__.py index 6ff9341be3..10949a1e0a 100644 --- a/faker/providers/address/fr_CH/__init__.py +++ b/faker/providers/address/fr_CH/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as AddressProvider @@ -97,26 +99,26 @@ class Provider(AddressProvider): 'Vierges britanniques (Îles)', 'Vietnam', 'Wallis et Futuna (Îles)', 'Yemen', 'Yougoslavie', 'Zambie', 'Zaïre', 'Zimbabwe') - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'rue' """ return self.random_element(self.street_prefixes) - def city_prefix(self): + def city_prefix(self) -> str: """ :example 'rue' """ return self.random_element(self.city_prefixes) - def canton(self): + def canton(self) -> Tuple[str, str]: """ Randomly returns a swiss canton ('Abbreviated' , 'Name'). :example ('VD' . 'Vaud') """ return self.random_element(self.cantons) - def administrative_unit(self): + def administrative_unit(self) -> str: """ Randomly returns a Swiss canton name. :example 'Vaud' @@ -125,7 +127,7 @@ def administrative_unit(self): canton_name = administrative_unit - def canton_code(self): + def canton_code(self) -> str: """ Randomly returns a Swiss canton code. :example 'VD' diff --git a/faker/providers/address/fr_FR/__init__.py b/faker/providers/address/fr_FR/__init__.py index e698172c83..cecf450692 100644 --- a/faker/providers/address/fr_FR/__init__.py +++ b/faker/providers/address/fr_FR/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as AddressProvider @@ -135,19 +137,19 @@ class Provider(AddressProvider): ('976', 'Mayotte'), ) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'rue' """ return self.random_element(self.street_prefixes) - def city_prefix(self): + def city_prefix(self) -> str: """ :example 'rue' """ return self.random_element(self.city_prefixes) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 'Guadeloupe' """ @@ -155,21 +157,21 @@ def administrative_unit(self): region = administrative_unit - def department(self): + def department(self) -> Tuple[str, str]: """ Randomly returns a french department ('departmentNumber' , 'departmentName'). :example ('2B' . 'Haute-Corse') """ return self.random_element(self.departments) - def department_name(self): + def department_name(self) -> str: """ Randomly returns a french department name. :example 'Ardèche' """ return self.department()[1] - def department_number(self): + def department_number(self) -> str: """ Randomly returns a french department number. diff --git a/faker/providers/address/he_IL/__init__.py b/faker/providers/address/he_IL/__init__.py index 71dc858b1b..fb485550d0 100644 --- a/faker/providers/address/he_IL/__init__.py +++ b/faker/providers/address/he_IL/__init__.py @@ -614,8 +614,8 @@ class Provider(AddressProvider): "שתולים", "תלמי אליהו") - def city_name(self): + def city_name(self) -> str: return self.random_element(self.city_names) - def street_title(self): + def street_title(self) -> str: return self.random_element(self.street_titles) diff --git a/faker/providers/address/hi_IN/__init__.py b/faker/providers/address/hi_IN/__init__.py index 52f994a40a..264e08f722 100644 --- a/faker/providers/address/hi_IN/__init__.py +++ b/faker/providers/address/hi_IN/__init__.py @@ -226,10 +226,10 @@ class Provider(AddressProvider): 'अफ़ग़ानिस्तान', ) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/hr_HR/__init__.py b/faker/providers/address/hr_HR/__init__.py index 01e69e3d14..2ef5e9fe1c 100755 --- a/faker/providers/address/hr_HR/__init__.py +++ b/faker/providers/address/hr_HR/__init__.py @@ -164,13 +164,13 @@ class Provider(AddressProvider): "Wallis i Futuna", "Zambija", "Zapadna Sahara", "Zeleni Rt", ) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.streets) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/hu_HU/__init__.py b/faker/providers/address/hu_HU/__init__.py index 1d4b1d7add..f1e806acc0 100644 --- a/faker/providers/address/hu_HU/__init__.py +++ b/faker/providers/address/hu_HU/__init__.py @@ -210,33 +210,33 @@ class Provider(AddressProvider): "Uruguay", "Üzbegisztán", "Vanuatu", "Venezuela", "Vietnam", "Wallis és Futuna", "Zambia", "Zimbabwe", "Zöld-foki szigetek") - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.counties) county = administrative_unit - def street_address_with_county(self): + def street_address_with_county(self) -> str: return f'{self.street_address()}\n{self.county()} megye\n{self.postcode()} {self.city().capitalize()}' - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefs) - def city_part(self): + def city_part(self) -> str: return self.random_element(self.city_parts) - def real_city_name(self): + def real_city_name(self) -> str: return self.random_element(self.real_city_names) - def frequent_street_name(self): + def frequent_street_name(self) -> str: return self.random_element(self.frequent_street_names) - def postcode(self): + def postcode(self) -> str: return (f'H-{super().random_digit_not_null()}{super().random_digit()}' f'{super().random_digit()}{super().random_digit()}') - def street_name(self): + def street_name(self) -> str: return super().street_name().capitalize() - def building_number(self): + def building_number(self) -> str: numeric_part = super().random_int(1, 250) return str(numeric_part) + "." diff --git a/faker/providers/address/hy_AM/__init__.py b/faker/providers/address/hy_AM/__init__.py index 9653fb3208..4abb0cbabf 100644 --- a/faker/providers/address/hy_AM/__init__.py +++ b/faker/providers/address/hy_AM/__init__.py @@ -1,3 +1,5 @@ +from typing import Optional + from .. import Provider as AddressProvider @@ -599,25 +601,25 @@ class Provider(AddressProvider): 'Սարիգյուղ', ) - def city(self): + def city(self) -> str: """ :example 'Բյուրեղավան' """ return self.random_element(self.cities) - def city_prefix(self): + def city_prefix(self) -> str: """ :example 'ք.' """ return self.random_element(self.city_prefixes) - def postcode(self): + def postcode(self) -> str: """ :example '3159' """ return "%04d" % self.generator.random.randint(200, 4299) - def postcode_in_state(self, state_abbr=None): + def postcode_in_state(self, state_abbr: Optional[str] = None) -> str: """ :example '4703' """ @@ -626,8 +628,8 @@ def postcode_in_state(self, state_abbr=None): if state_abbr in self.states_abbr: postcode = "%d" % (self.generator.random.randint( - self.states_postcode[state_abbr][0], - self.states_postcode[state_abbr][1])) + self.states_postcode[state_abbr][0], + self.states_postcode[state_abbr][1])) if len(postcode) == 3: postcode = "0%s" % postcode @@ -637,13 +639,13 @@ def postcode_in_state(self, state_abbr=None): else: raise Exception('State Abbreviation not found in list') - def secondary_address(self): + def secondary_address(self) -> str: """ :example 'բն. 49' """ return self.numerify(self.random_element(self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 'Կոտայք' """ @@ -651,31 +653,31 @@ def administrative_unit(self): state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: """ :example 'ՎՁ' """ return self.random_element(self.states_abbr) - def street(self): + def street(self) -> str: """ :example 'Ոսկերիչների' """ return self.random_element(self.streets) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'փողոց' """ return self.random_element(self.street_prefixes) - def village(self): + def village(self) -> str: """ :example 'Ոսկեվազ' """ return self.random_element(self.villages) - def village_prefix(self): + def village_prefix(self) -> str: """ :example 'գ.' """ diff --git a/faker/providers/address/id_ID/__init__.py b/faker/providers/address/id_ID/__init__.py index 85a5d32295..f15ffa9682 100644 --- a/faker/providers/address/id_ID/__init__.py +++ b/faker/providers/address/id_ID/__init__.py @@ -147,25 +147,25 @@ class Provider(AddressProvider): 'Zimbabwe', ) - def street(self): + def street(self) -> str: return self.random_element(self.streets) - def street_prefix_short(self): + def street_prefix_short(self) -> str: return self.random_element(self.street_prefixes_short) - def street_prefix_long(self): + def street_prefix_long(self) -> str: return self.random_element(self.street_prefixes_long) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: return self.random_element(self.states_abbr) - def country(self): + def country(self) -> str: return self.random_element(self.countries) diff --git a/faker/providers/address/it_IT/__init__.py b/faker/providers/address/it_IT/__init__.py index ea27da5b8f..8594341cac 100644 --- a/faker/providers/address/it_IT/__init__.py +++ b/faker/providers/address/it_IT/__init__.py @@ -114,17 +114,17 @@ class Provider(AddressProvider): ) secondary_address_formats = ('Appartamento ##', 'Piano #') - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element(self.secondary_address_formats)) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: return self.random_element(self.states_abbr) diff --git a/faker/providers/address/ja_JP/__init__.py b/faker/providers/address/ja_JP/__init__.py index 0bc00f6c7c..c50db8fee4 100644 --- a/faker/providers/address/ja_JP/__init__.py +++ b/faker/providers/address/ja_JP/__init__.py @@ -302,7 +302,7 @@ class Provider(AddressProvider): 'パレス', 'ハイツ', 'コーポ', 'アーバン', 'クレスト', 'パーク', 'シティ', 'シャルム', 'コート', ) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example '東京都' """ @@ -310,48 +310,48 @@ def administrative_unit(self): prefecture = administrative_unit - def city(self): + def city(self) -> str: """ :example '台東区' """ return self.random_element(self.cities) - def town(self): + def town(self) -> str: """ :example '浅草' """ return self.random_element(self.towns) - def chome(self): + def chome(self) -> str: """ :example '1丁目' """ return "%d丁目" % self.generator.random.randint(1, 42) - def ban(self): + def ban(self) -> str: """ :example '3番' """ return "%d番" % self.generator.random.randint(1, 27) - def gou(self): + def gou(self) -> str: """ :example '10号' """ return "%d号" % self.generator.random.randint(1, 20) - def building_name(self): + def building_name(self) -> str: """ :example 'コーポ芝浦' """ return self.random_element(self.building_names) - def postcode(self): + def postcode(self) -> str: """ :example '101-1212' """ return "%03d-%04d" % (self.generator.random.randint(0, 999), self.generator.random.randint(0, 9999)) - def zipcode(self): + def zipcode(self) -> str: return self.postcode() diff --git a/faker/providers/address/ka_GE/__init__.py b/faker/providers/address/ka_GE/__init__.py index 271516a878..28732735fa 100644 --- a/faker/providers/address/ka_GE/__init__.py +++ b/faker/providers/address/ka_GE/__init__.py @@ -297,8 +297,8 @@ class Provider(AddressProvider): 'ჯვარი', ) - def street_title(self): + def street_title(self) -> str: return self.random_element(self.street_titles) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.city_names) diff --git a/faker/providers/address/ko_KR/__init__.py b/faker/providers/address/ko_KR/__init__.py index f3e1af5619..11b8be38f7 100644 --- a/faker/providers/address/ko_KR/__init__.py +++ b/faker/providers/address/ko_KR/__init__.py @@ -315,66 +315,66 @@ class Provider(AddressProvider): street_address_formats = road_address_formats address_formats = road_address_formats - def land_number(self): + def land_number(self) -> str: """ :example 507 """ return self.bothify(self.random_element(self.land_numbers)) - def land_address(self): + def land_address(self) -> str: """ :example 세종특별자치시 어진동 507 """ - pattern = self.random_element(self.land_address_formats) + pattern: str = self.random_element(self.land_address_formats) return self.generator.parse(pattern) - def road_number(self): + def road_number(self) -> str: """ :example 24 """ return self.bothify(self.random_element(self.road_numbers)) - def road_address(self): + def road_address(self) -> str: """ :example 세종특별자치시 도움5로 19 (어진동) """ - pattern = self.random_element(self.road_address_formats) + pattern: str = self.random_element(self.road_address_formats) return self.generator.parse(pattern) - def address_detail(self): + def address_detail(self) -> str: """ :example 가나아파트 가동 102호 """ - pattern = self.bothify(self.random_element( + pattern: str = self.bothify(self.random_element( self.address_detail_formats)) return self.generator.parse(pattern) - def road(self): + def road(self) -> str: """ :example 도움5로 """ - pattern = self.random_element(self.road_formats) + pattern: str = self.random_element(self.road_formats) return self.generator.parse(pattern) - def road_name(self): + def road_name(self) -> str: """ :example 압구정 """ return self.random_element(self.road_names) - def road_suffix(self): + def road_suffix(self) -> str: """ :example 길 """ return self.random_element(self.road_suffixes) - def metropolitan_city(self): + def metropolitan_city(self) -> str: """ :example 서울특별시 """ return self.random_element(self.metropolitan_cities) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 경기도 """ @@ -382,64 +382,64 @@ def administrative_unit(self): province = administrative_unit - def city(self): + def city(self) -> str: """ :example 고양시 """ - pattern = self.random_element(self.cities) + pattern: str = self.random_element(self.cities) return self.generator.parse(pattern) - def borough(self): + def borough(self) -> str: """ :example 중구 """ return self.random_element(self.boroughs) - def town(self): + def town(self) -> str: """ :example 가나동 """ - pattern = self.random_element(self.town_formats) + pattern: str = self.random_element(self.town_formats) return self.generator.parse(pattern) - def town_suffix(self): + def town_suffix(self) -> str: """ :example 동 """ return self.random_element(self.town_suffixes) - def building_name(self): + def building_name(self) -> str: """ :example 김구아파트 """ - pattern = self.random_element(self.building_name_formats) + pattern: str = self.random_element(self.building_name_formats) return self.generator.parse(pattern) - def building_suffix(self): + def building_suffix(self) -> str: """ :example 아파트 """ return self.random_element(self.building_suffixes) - def building_dong(self): + def building_dong(self) -> str: """ :example 가 """ return self.bothify(self.random_element(self.building_dongs)) - def old_postal_code(self): + def old_postal_code(self) -> str: """ :example 123-456 """ return self.bothify(self.random_element(self.postcode_formats)) - def postcode(self): + def postcode(self) -> str: """ :example 12345 """ return self.bothify(self.random_element(self.new_postal_code_formats)) - def postal_code(self): + def postal_code(self) -> str: """ :example 12345 """ diff --git a/faker/providers/address/ne_NP/__init__.py b/faker/providers/address/ne_NP/__init__.py index 10498e00bb..3ff159be7a 100644 --- a/faker/providers/address/ne_NP/__init__.py +++ b/faker/providers/address/ne_NP/__init__.py @@ -596,7 +596,7 @@ class Provider(AddressProvider): 'सुदूरपश्चिम प्रदेश', ) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example सुदूरपश्चिम प्रदेश """ @@ -604,19 +604,19 @@ def administrative_unit(self): province = administrative_unit - def district(self): + def district(self) -> str: """ :example अछाम """ return self.random_element(self.districts) - def city(self): + def city(self) -> str: """ :example कावासोती """ return self.random_element(self.cities) - def building_prefix(self): + def building_prefix(self) -> str: """ :example वडा """ diff --git a/faker/providers/address/nl_BE/__init__.py b/faker/providers/address/nl_BE/__init__.py index 44b218abda..1b964ed673 100644 --- a/faker/providers/address/nl_BE/__init__.py +++ b/faker/providers/address/nl_BE/__init__.py @@ -570,10 +570,10 @@ class Provider(AddressProvider): "{{street_address}}\n{{postcode}} {{city}}", ) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.provinces) province = administrative_unit - def city(self): + def city(self) -> str: return self.random_element(self.cities) diff --git a/faker/providers/address/nl_NL/__init__.py b/faker/providers/address/nl_NL/__init__.py index ea15d7b4c4..6d8990e3bd 100644 --- a/faker/providers/address/nl_NL/__init__.py +++ b/faker/providers/address/nl_NL/__init__.py @@ -580,10 +580,10 @@ class Provider(AddressProvider): "{{street_address}}\n{{postcode}}\n{{city}}", ) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.provinces) province = administrative_unit - def city(self): + def city(self) -> str: return self.random_element(self.cities) diff --git a/faker/providers/address/no_NO/__init__.py b/faker/providers/address/no_NO/__init__.py index a49c759129..60bea42be5 100644 --- a/faker/providers/address/no_NO/__init__.py +++ b/faker/providers/address/no_NO/__init__.py @@ -37,15 +37,15 @@ class Provider(AddressProvider): ]) postcode_formats = ('####',) - def building_number(self): - suffix = self.random_element(self.building_number_suffixes) + def building_number(self) -> str: + suffix: str = self.random_element(self.building_number_suffixes) return self.numerify( self.random_element( self.building_number_formats)).replace( '?', suffix) - def city_suffix(self): + def city_suffix(self) -> str: return self.random_element(self.city_suffixes) - def street_suffix(self): + def street_suffix(self) -> str: return self.random_element(self.street_suffixes) diff --git a/faker/providers/address/pl_PL/__init__.py b/faker/providers/address/pl_PL/__init__.py index f884c63ad8..397b735a02 100644 --- a/faker/providers/address/pl_PL/__init__.py +++ b/faker/providers/address/pl_PL/__init__.py @@ -152,35 +152,35 @@ class Provider(AddressProvider): "{{street_address}}\n{{postcode}} {{city}}", ) - def street_prefix(self): + def street_prefix(self) -> str: """ Randomly returns a street prefix :example 'aleja' """ return self.random_element(self.street_prefixes) - def street_prefix_short(self): + def street_prefix_short(self) -> str: """ Randomly returns an abbreviation of the street prefix. :example 'al.' """ - return self.random_element(self.street_prefixes)[:2] + '.' + return self.random_element(self.street_prefixes)[:2] + '.' # type: ignore - def street_name(self): + def street_name(self) -> str: """ Randomly returns a street name :example 'Wróblewskiego' """ return self.random_element(self.streets) - def city(self): + def city(self) -> str: """ Randomly returns a street name :example 'Konin' """ return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 'Wielkopolskie' """ diff --git a/faker/providers/address/pt_BR/__init__.py b/faker/providers/address/pt_BR/__init__.py index dadff37b72..b1e1a77f4a 100644 --- a/faker/providers/address/pt_BR/__init__.py +++ b/faker/providers/address/pt_BR/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as AddressProvider @@ -260,27 +262,27 @@ class Provider(AddressProvider): ('SE', 'Sergipe'), ('TO', 'Tocantins'), ) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'rua' """ return self.random_element(self.street_prefixes) - def estado(self): + def estado(self) -> Tuple[str, str]: """ Randomly returns a Brazilian State ('sigla' , 'nome'). :example ('MG' . 'Minas Gerais') """ return self.random_element(self.estados) - def estado_nome(self): + def estado_nome(self) -> str: """ Randomly returns a Brazilian State Name :example 'Minas Gerais' """ return self.estado()[1] - def estado_sigla(self): + def estado_sigla(self) -> str: """ Randomly returns the abbreviation of a Brazilian State @@ -288,7 +290,7 @@ def estado_sigla(self): """ return self.estado()[0] - def bairro(self): + def bairro(self) -> str: """ Randomly returns a bairro (neighborhood) name. The names were taken from the city of Belo Horizonte - Minas Gerais @@ -297,7 +299,7 @@ def bairro(self): """ return self.random_element(self.bairros) - def postcode(self, formatted=True): + def postcode(self, formatted: bool = True) -> str: """ Randomly returns a postcode. :param formatted: True to allow formatted postcodes, else False (default True) @@ -308,13 +310,13 @@ def postcode(self, formatted=True): return self.bothify(self.random_element(template)) # aliases - def neighborhood(self): + def neighborhood(self) -> str: return self.bairro() - def administrative_unit(self): + def administrative_unit(self) -> str: return self.estado_nome() state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: return self.estado_sigla() diff --git a/faker/providers/address/pt_PT/__init__.py b/faker/providers/address/pt_PT/__init__.py index 07c6d9ec41..8459f2f4c3 100644 --- a/faker/providers/address/pt_PT/__init__.py +++ b/faker/providers/address/pt_PT/__init__.py @@ -385,21 +385,21 @@ class Provider(AddressProvider): "da Carvalhosa", "da Companhia", "da Ilha do Ferro", "da Pedreira", "da Senhora da Lapa", "das Andrezas", "de Grijó", "de Lamas", "de S. Brás", "de Santana", "do Anjo", "do Anjo da Guarda", "do Buraco", "do José da Mestra", "do Monte da Pena", "do Picoto", "do Sobreirinho", - ) + ) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'Rua' """ return self.random_element(self.street_prefixes) - def city_name(self): + def city_name(self) -> str: """ :example 'Amora' """ return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 'Bragança' """ @@ -407,19 +407,19 @@ def administrative_unit(self): distrito = administrative_unit - def concelho(self): + def concelho(self) -> str: """ :example 'Tondela' """ return self.random_element(self.concelhos) - def freguesia(self): + def freguesia(self) -> str: """ :example 'Miranda do Douro' """ return self.random_element(self.freguesias) - def place_name(self): + def place_name(self) -> str: """ :example "do Pombal" """ diff --git a/faker/providers/address/ro_RO/__init__.py b/faker/providers/address/ro_RO/__init__.py index 076e2e8c3a..a8c4538be5 100644 --- a/faker/providers/address/ro_RO/__init__.py +++ b/faker/providers/address/ro_RO/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as AddressProvider @@ -83,7 +85,7 @@ class Provider(AddressProvider): 'Rasinari', 'Sebis', 'Raducaneni', 'Siria', 'Paunesti', 'Saveni', 'Tunari', ) - states = ( + states: Tuple[Tuple[str, str], ...] = ( ('AB', 'Alba'), ('AG', 'Argeș'), ('AR', 'Arad'), ('B', 'București'), ('BC', 'Bacău'), ('BH', 'Bihor'), ('BN', 'Bistrița-Năsăud'), ('BR', 'Brăila'), ('BT', 'Botoșani'), ('BV', 'Brașov'), ('BZ', 'Buzău'), @@ -97,13 +99,13 @@ class Provider(AddressProvider): ('VL', 'Vâlcea'), ('VN', 'Vrancea'), ('VS', 'Vaslui'), ) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'Strada' """ return self.random_element(self.street_prefixes) - def secondary_address(self): + def secondary_address(self) -> str: """ :example 'Bl. 123 Sc. 2 Ap. 15' """ @@ -111,22 +113,22 @@ def secondary_address(self): self.random_element( self.secondary_address_formats)) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def city_with_postcode(self): + def city_with_postcode(self) -> str: return self.postcode() + " " + self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: """ example: u'Timiș' """ - return self.random_element(self.states)[1] + return self.random_element(self.states)[1] # type: ignore state = administrative_unit - def state_abbr(self): + def state_abbr(self) -> str: """ example: u'TM' """ - return self.random_element(self.states)[0] + return self.random_element(self.states)[0] # type: ignore diff --git a/faker/providers/address/ru_RU/__init__.py b/faker/providers/address/ru_RU/__init__.py index 0febabc8a5..bb68efde9b 100644 --- a/faker/providers/address/ru_RU/__init__.py +++ b/faker/providers/address/ru_RU/__init__.py @@ -348,35 +348,37 @@ class Provider(AddressProvider): 'Эсватини', 'Эстония', 'Эфиопия', 'ЮАР', 'Южный Судан', 'Ямайка', 'Япония', ) - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.city_names) - def country(self): + def country(self) -> str: return self.random_element(self.countries) - def administrative_unit(self): - regions_suffix = self.random_element(self.region_suffixes) + def administrative_unit(self) -> str: + regions_suffix: str = self.random_element(self.region_suffixes) if regions_suffix == 'респ.': - return regions_suffix + ' ' + self.random_element(self.region_republics) + return f'{regions_suffix} {self.random_element(self.region_republics)}' elif regions_suffix == 'край': - return self.random_element(self.region_krai) + ' ' + regions_suffix + return f'{self.random_element(self.region_krai)} {regions_suffix}' elif regions_suffix == 'обл.': - return self.random_element(self.region_oblast) + ' ' + regions_suffix + return f'{self.random_element(self.region_oblast)} {regions_suffix}' elif regions_suffix == 'АО': - return self.random_element(self.region_ao) + ' ' + regions_suffix + return f'{self.random_element(self.region_ao)} {regions_suffix}' + else: + raise ValueError(f'Unknown region "{regions_suffix}"') region = administrative_unit - def street_suffix(self): + def street_suffix(self) -> str: return self.random_element(self.street_suffixes) - def street_title(self): + def street_title(self) -> str: return self.random_element(self.street_titles + self.street_titles_noflex) - def street_name(self): + def street_name(self) -> str: suffix = self.street_suffix() street = self.street_title() stem = street[:-2] @@ -395,4 +397,4 @@ def street_name(self): result = self.street_titles_irregular_neu[street] else: result = stem + 'ое' - return suffix + ' ' + result + return f'{suffix} {result}' diff --git a/faker/providers/address/sk_SK/__init__.py b/faker/providers/address/sk_SK/__init__.py index 3eeee30957..356c46e453 100644 --- a/faker/providers/address/sk_SK/__init__.py +++ b/faker/providers/address/sk_SK/__init__.py @@ -1147,22 +1147,22 @@ class Provider(AddressProvider): 'Socialistická federatívna republika Juhoslávia', 'Zairská republika', ) - def street_suffix_short(self): + def street_suffix_short(self) -> str: return self.random_element(self.street_suffixes_short) - def street_suffix_long(self): + def street_suffix_long(self) -> str: return self.random_element(self.street_suffixes_long) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.streets) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit - def city_with_postcode(self): + def city_with_postcode(self) -> str: return self.postcode() + " " + self.random_element(self.cities) diff --git a/faker/providers/address/sl_SI/__init__.py b/faker/providers/address/sl_SI/__init__.py index eea1106e60..157af3daa0 100755 --- a/faker/providers/address/sl_SI/__init__.py +++ b/faker/providers/address/sl_SI/__init__.py @@ -499,13 +499,13 @@ class Provider(AddressProvider): "Združeni arabski emirati", "Zelenortski otoki", ) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.streets) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/sv_SE/__init__.py b/faker/providers/address/sv_SE/__init__.py index 5069ff2ae0..ecd4796030 100644 --- a/faker/providers/address/sv_SE/__init__.py +++ b/faker/providers/address/sv_SE/__init__.py @@ -100,13 +100,13 @@ class Provider(AddressProvider): 'Norrbottens län', ) - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element(self.street_prefixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/ta_IN/__init__.py b/faker/providers/address/ta_IN/__init__.py index fd4837cd77..38e039306e 100644 --- a/faker/providers/address/ta_IN/__init__.py +++ b/faker/providers/address/ta_IN/__init__.py @@ -411,10 +411,10 @@ class Provider(AddressProvider): 'மொன்செராட்', ) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.states) state = administrative_unit diff --git a/faker/providers/address/th_TH/__init__.py b/faker/providers/address/th_TH/__init__.py index ba7514dd3f..efea586bd1 100644 --- a/faker/providers/address/th_TH/__init__.py +++ b/faker/providers/address/th_TH/__init__.py @@ -8,26 +8,26 @@ class Provider(AddressProvider): street_address_formats = ("{{building_number}} {{street_name}}",) address_formats = OrderedDict(( - ("{{street_address}} {{tambon}} {{amphoe}} {{province}} {{postcode}}", 50), - ("{{street_address}} ตำบล{{tambon}} อำเภอ{{amphoe}} {{province}} {{postcode}}", 50), - ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} {{province}} {{postcode}}", 50), - ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} จ.{{province}} {{postcode}}", 40), - ("{{street_address}} อำเภอ{{amphoe}} {{province}} {{postcode}}", 30), - ("{{street_address}} อ.{{amphoe}} {{province}} {{postcode}}", 30), - ("{{street_address}} {{amphoe}} {{province}} {{postcode}}", 30), - ("{{street_address}} {{tambon}} {{province}} {{postcode}}", 15), - ("{{street_address}} {{amphoe}} จ.{{province}} {{postcode}}", 15), - ("{{street_address}} {{tambon}} จ.{{province}} {{postcode}}", 15), - ("{{street_address}} อ.{{amphoe}} จ.{{province}} {{postcode}}", 15), - ("{{street_address}} ต.{{tambon}} จ.{{province}} {{postcode}}", 15), - ("{{street_address}} อำเภอ{{amphoe}} จังหวัด{{province}} {{postcode}}", 15), - ("{{street_address}} ตำบล{{tambon}} อำเภอ{{amphoe}} จังหวัด{{province}} {{postcode}}", 10), - ("{{street_address}} {{province}} {{postcode}}", 15), - ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} {{province}}", 15), - ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} จ.{{province}}", 15), - ("{{street_address}} ตำบล{{tambon}} จังหวัด{{province}} {{postcode}}", 10), - ("{{building_number}} ต.{{tambon}} อ.{{amphoe}} {{province}} {{postcode}}", 10), - ("{{building_number}} หมู่บ้าน{{first_name}} {{amphoe}} {{province}} {{postcode}}", 10), + ("{{street_address}} {{tambon}} {{amphoe}} {{province}} {{postcode}}", 50.), + ("{{street_address}} ตำบล{{tambon}} อำเภอ{{amphoe}} {{province}} {{postcode}}", 50.), + ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} {{province}} {{postcode}}", 50.), + ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} จ.{{province}} {{postcode}}", 40.), + ("{{street_address}} อำเภอ{{amphoe}} {{province}} {{postcode}}", 30.), + ("{{street_address}} อ.{{amphoe}} {{province}} {{postcode}}", 30.), + ("{{street_address}} {{amphoe}} {{province}} {{postcode}}", 30.), + ("{{street_address}} {{tambon}} {{province}} {{postcode}}", 15.), + ("{{street_address}} {{amphoe}} จ.{{province}} {{postcode}}", 15.), + ("{{street_address}} {{tambon}} จ.{{province}} {{postcode}}", 15.), + ("{{street_address}} อ.{{amphoe}} จ.{{province}} {{postcode}}", 15.), + ("{{street_address}} ต.{{tambon}} จ.{{province}} {{postcode}}", 15.), + ("{{street_address}} อำเภอ{{amphoe}} จังหวัด{{province}} {{postcode}}", 15.), + ("{{street_address}} ตำบล{{tambon}} อำเภอ{{amphoe}} จังหวัด{{province}} {{postcode}}", 10.), + ("{{street_address}} {{province}} {{postcode}}", 15.), + ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} {{province}}", 15.), + ("{{street_address}} ต.{{tambon}} อ.{{amphoe}} จ.{{province}}", 15.), + ("{{street_address}} ตำบล{{tambon}} จังหวัด{{province}} {{postcode}}", 10.), + ("{{building_number}} ต.{{tambon}} อ.{{amphoe}} {{province}} {{postcode}}", 10.), + ("{{building_number}} หมู่บ้าน{{first_name}} {{amphoe}} {{province}} {{postcode}}", 10.), )) # city names are actual city municipalities in Thailand @@ -296,13 +296,13 @@ class Provider(AddressProvider): ) tambon_prefixes = OrderedDict(( - ("", 40), - ("วัด", 2), - ("บ้าน", 2), - ("บ่อ", 2), - ("บึง", 2), - ("ป่า", 1), - ("ห้วย", 1), + ("", 40.), + ("วัด", 2.), + ("บ้าน", 2.), + ("บ่อ", 2.), + ("บึง", 2.), + ("ป่า", 1.), + ("ห้วย", 1.), )) tambon_suffixes = OrderedDict(( @@ -318,13 +318,13 @@ class Provider(AddressProvider): city_suffixes = ("นคร",) - def street_prefix(self): + def street_prefix(self) -> str: """ :example 'ถนน' """ return self.random_element(self.street_prefixes) - def administrative_unit(self): + def administrative_unit(self) -> str: """ :example 'อุบลราชธานี' """ @@ -332,7 +332,7 @@ def administrative_unit(self): province = administrative_unit - def amphoe(self): + def amphoe(self) -> str: """ Get a random Amphoe (district) name. Currently it's total random and not necessarily matched with a province. @@ -340,17 +340,14 @@ def amphoe(self): """ return self.random_element(self.amphoes) - def tambon(self): + def tambon(self) -> str: """ Get a random Tambon (subdistrict) name. Currently it's total random and not necessarily matched with an amphoe or province. :example 'ห้วยนาง' """ - return ( - self.random_element(self.tambon_prefixes) - + self.random_element(self.tambons) - + self.random_element(self.tambon_suffixes) - ) + return f'{self.random_element(self.tambon_prefixes)}{self.random_element(self.tambons)}' + \ + f'{self.random_element(self.tambon_suffixes)}' - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) diff --git a/faker/providers/address/uk_UA/__init__.py b/faker/providers/address/uk_UA/__init__.py index 75742c600a..2a3b7f57b7 100644 --- a/faker/providers/address/uk_UA/__init__.py +++ b/faker/providers/address/uk_UA/__init__.py @@ -2055,26 +2055,26 @@ class Provider(AddressProvider): 'Яші Гордієнка', ] - def city_prefix(self): + def city_prefix(self) -> str: return self.random_element(self.city_prefixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.city_names) - def postcode(self): + def postcode(self) -> str: """The code consists of five digits (01000-99999)""" return f'{self.generator.random.randint(0, 10)}{self.generator.random.randint(1000, 10000)}' - def street_prefix(self): + def street_prefix(self) -> str: return self.random_element(self.street_prefixes) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.street_titles) - def street_title(self): + def street_title(self) -> str: prefix = self.street_prefix() street = self.street_name() return prefix + ' ' + street - def region(self): + def region(self) -> str: return self.random_element(self.region_names) diff --git a/faker/providers/address/zh_CN/__init__.py b/faker/providers/address/zh_CN/__init__.py index 73f1702677..be64ec63d4 100644 --- a/faker/providers/address/zh_CN/__init__.py +++ b/faker/providers/address/zh_CN/__init__.py @@ -74,16 +74,16 @@ class Provider(AddressProvider): "也门", "南斯拉夫", "扎伊尔", "赞比亚", "桑给巴尔", "津巴布韦", "中华人民共和国", "中国", ) - def building_number(self): + def building_number(self) -> str: return self.lexify(self.random_element(self.building_number_formats)) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def administrative_unit(self): + def administrative_unit(self) -> str: return self.random_element(self.provinces) province = administrative_unit - def district(self): + def district(self) -> str: return self.random_element(self.districts) diff --git a/faker/providers/address/zh_TW/__init__.py b/faker/providers/address/zh_TW/__init__.py index 7202e2a8e5..125940caa3 100644 --- a/faker/providers/address/zh_TW/__init__.py +++ b/faker/providers/address/zh_TW/__init__.py @@ -87,25 +87,25 @@ class Provider(AddressProvider): "羅馬尼亞", "葉門", "俄羅斯", "尚比亞", "盧安達", "辛巴威", "聖克里斯多福及尼維斯") - def secondary_address(self): + def secondary_address(self) -> str: return self.numerify( self.random_element( self.secondary_address_formats)) - def building_number(self): + def building_number(self) -> str: return self.numerify(self.random_element(self.building_number_formats)) - def street_name(self): + def street_name(self) -> str: return self.random_element(self.street_names) - def street_name_suffix(self): + def street_name_suffix(self) -> str: return self.random_element(self.street_suffixes) - def city_name(self): + def city_name(self) -> str: return self.random_element(self.cities) - def city_name_suffix(self): + def city_name_suffix(self) -> str: return self.random_element(self.city_suffixes) - def section_number(self): + def section_number(self) -> str: return self.numerify(self.random_element(self.section_formats)) diff --git a/faker/providers/automotive/__init__.py b/faker/providers/automotive/__init__.py index d83a7cd46f..28f8c348d6 100644 --- a/faker/providers/automotive/__init__.py +++ b/faker/providers/automotive/__init__.py @@ -2,7 +2,7 @@ from string import ascii_uppercase -from .. import BaseProvider +from .. import BaseProvider, ElementsType localized = True @@ -10,9 +10,9 @@ class Provider(BaseProvider): """Implement default automotive provider for Faker.""" - license_formats = () + license_formats: ElementsType = () - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" temp = re.sub(r'\?', lambda x: self.random_element(ascii_uppercase), diff --git a/faker/providers/automotive/ar_JO/__init__.py b/faker/providers/automotive/ar_JO/__init__.py index 3432c64d07..193bcb4d7c 100644 --- a/faker/providers/automotive/ar_JO/__init__.py +++ b/faker/providers/automotive/ar_JO/__init__.py @@ -14,7 +14,7 @@ class Provider(AutomotiveProvider): '{{initials}}-#####', ) - def initials(self): + def initials(self) -> str: """Generate an initial number for license plates.""" return self.random_element([ '1', # Ministers @@ -41,7 +41,7 @@ def initials(self): '99', # Police ]) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - pattern = self.random_element(self.license_formats) + pattern: str = self.random_element(self.license_formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/automotive/ar_PS/__init__.py b/faker/providers/automotive/ar_PS/__init__.py index be5845d9e0..171a4dfc3d 100644 --- a/faker/providers/automotive/ar_PS/__init__.py +++ b/faker/providers/automotive/ar_PS/__init__.py @@ -41,7 +41,7 @@ class Provider(AutomotiveProvider): '3-####-5#', ) - def district(self): + def district(self) -> str: """Generate a district code for license plates.""" return self.random_element([ # Gaza Strip @@ -61,7 +61,7 @@ def district(self): '9', ]) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - pattern = self.random_element(self.license_formats) + pattern: str = self.random_element(self.license_formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/automotive/ar_SA/__init__.py b/faker/providers/automotive/ar_SA/__init__.py index e0cd953dd7..0ee8643e4a 100644 --- a/faker/providers/automotive/ar_SA/__init__.py +++ b/faker/providers/automotive/ar_SA/__init__.py @@ -51,13 +51,13 @@ class Provider(AutomotiveProvider): '9': '٩', } - def license_plate_en(self): + def license_plate_en(self) -> str: """Generate a license plate in Latin/Western characters.""" return self.bothify( self.LICENSE_FORMAT_EN, letters=self.PLATE_CHARS_EN, ) - def license_plate_ar(self): + def license_plate_ar(self) -> str: """Generate a license plate in Arabic characters. This method first generates a license plate in Latin/Western characters @@ -68,7 +68,7 @@ def license_plate_ar(self): english_plate = self.license_plate_en() return self._translate_license_plate(english_plate) - def _translate_license_plate(self, license_plate): + def _translate_license_plate(self, license_plate: str) -> str: nums = list(reversed(license_plate[0:4])) chars = list(license_plate[5:8]) @@ -85,15 +85,5 @@ def _translate_license_plate(self, license_plate): return ar_plate - def license_plate(self): - """Generate a license plate. - - This method first generates a license plate in Latin/Western characters - using |license_plate_en|, and the result is translated internally to - generate the Arabic counterpart. A 2-tuple containing those results - will serve as the return value. - """ - en_palate = self.license_plate_en() - ar_palate = self._translate_license_plate(en_palate) - - return en_palate, ar_palate + def license_plate(self, ar: bool = True) -> str: + return self.license_plate_ar() if ar else self.license_plate_en() diff --git a/faker/providers/automotive/de_DE/__init__.py b/faker/providers/automotive/de_DE/__init__.py index 4ce8434a34..5bf586bfda 100644 --- a/faker/providers/automotive/de_DE/__init__.py +++ b/faker/providers/automotive/de_DE/__init__.py @@ -43,8 +43,8 @@ class Provider(AutomotiveProvider): '-?-%@@@', ) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - prefix = self.random_element(self.license_plate_prefix) + prefix: str = self.random_element(self.license_plate_prefix) suffix = self.bothify(self.random_element(self.license_plate_suffix), letters=string.ascii_uppercase) return prefix + suffix diff --git a/faker/providers/automotive/en_PH/__init__.py b/faker/providers/automotive/en_PH/__init__.py index 97b4a907df..99402c0409 100644 --- a/faker/providers/automotive/en_PH/__init__.py +++ b/faker/providers/automotive/en_PH/__init__.py @@ -1,4 +1,5 @@ from string import ascii_uppercase +from typing import List from ... import BaseProvider @@ -18,21 +19,21 @@ class Provider(BaseProvider): - https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_the_Philippines """ - protocol_licenses = tuple(str(x) for x in range(1, 18) if x != 15) - motorcycle_license_formats = ( + protocol_licenses = [str(x) for x in range(1, 18) if x != 15] + motorcycle_license_formats = [ '??####', # 1981 series '??#####', # 2014 series - ) - automobile_license_formats = ( + ] + automobile_license_formats = [ '???###', # 1981 series '???####', # 2014 series - ) + ] license_formats = motorcycle_license_formats + automobile_license_formats - def _license_plate(self, license_format): + def _license_plate(self, license_format: List[str]) -> str: return self.bothify(self.random_element(license_format), ascii_uppercase) - def protocol_license_plate(self): + def protocol_license_plate(self) -> str: """Generate a protocol license plate. .. note:: @@ -41,7 +42,7 @@ def protocol_license_plate(self): """ return self.random_element(self.protocol_licenses) - def motorcycle_license_plate(self): + def motorcycle_license_plate(self) -> str: """Generate a motorcycle license plate. .. note:: @@ -50,7 +51,7 @@ def motorcycle_license_plate(self): """ return self._license_plate(self.motorcycle_license_formats) - def automobile_license_plate(self): + def automobile_license_plate(self) -> str: """Generate an automobile license plate. .. note:: @@ -59,7 +60,7 @@ def automobile_license_plate(self): """ return self._license_plate(self.automobile_license_formats) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate. .. note:: diff --git a/faker/providers/automotive/es_ES/__init__.py b/faker/providers/automotive/es_ES/__init__.py index 6df6c72d47..f41e513c9f 100644 --- a/faker/providers/automotive/es_ES/__init__.py +++ b/faker/providers/automotive/es_ES/__init__.py @@ -2,6 +2,8 @@ import re +from typing import Optional + from .. import Provider as AutomotiveProvider @@ -89,7 +91,7 @@ class Provider(AutomotiveProvider): "ZA", # Zamora ) - def license_plate_unified(self): + def license_plate_unified(self) -> str: """Generate a unified license plate.""" temp = re.sub(r'\?', lambda x: self.random_element( @@ -97,7 +99,7 @@ def license_plate_unified(self): self.license_formats[0]) return self.numerify(temp) - def license_plate_by_province(self, province_prefix=None): + def license_plate_by_province(self, province_prefix: Optional[str] = None) -> str: """Generate a provincial license plate. If a value for ``province_prefix`` is provided, the value will be used @@ -112,7 +114,7 @@ def license_plate_by_province(self, province_prefix=None): "#### ??") return province_prefix + " " + self.numerify(temp) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate. This method randomly chooses (50/50) between |license_plate_unified| diff --git a/faker/providers/automotive/pl_PL/__init__.py b/faker/providers/automotive/pl_PL/__init__.py index 304280ee9c..cf1155dff3 100644 --- a/faker/providers/automotive/pl_PL/__init__.py +++ b/faker/providers/automotive/pl_PL/__init__.py @@ -1,3 +1,5 @@ +from typing import List + from .. import Provider as AutomotiveProvider @@ -26,7 +28,7 @@ class Provider(AutomotiveProvider): '??? ###??', ) - def license_plate_regex_formats(self): + def license_plate_regex_formats(self) -> List[str]: """Return a regex for matching license plates. .. warning:: diff --git a/faker/providers/automotive/ro_RO/__init__.py b/faker/providers/automotive/ro_RO/__init__.py index e33764b549..30a63d85bb 100644 --- a/faker/providers/automotive/ro_RO/__init__.py +++ b/faker/providers/automotive/ro_RO/__init__.py @@ -18,9 +18,9 @@ class Provider(AutomotiveProvider): '-##-???', ) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - prefix = self.random_element(self.license_plate_prefix) + prefix: str = self.random_element(self.license_plate_prefix) suffix = self.bothify(self.random_element( self.license_plate_suffix), letters=string.ascii_uppercase) return prefix + suffix diff --git a/faker/providers/automotive/ru_RU/__init__.py b/faker/providers/automotive/ru_RU/__init__.py index 7f07894710..f9f2627a75 100644 --- a/faker/providers/automotive/ru_RU/__init__.py +++ b/faker/providers/automotive/ru_RU/__init__.py @@ -229,31 +229,31 @@ class Provider(AutomotiveProvider): '00#CD#', '00#D###', '00#T###', ) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - pattern = self.random_element(self.license_plate_formats) + pattern: str = self.random_element(self.license_plate_formats) return self.generator.parse(pattern) - def plate_letter(self): + def plate_letter(self) -> str: """Generate a letter for license plates.""" return self.random_element(self.license_plate_letters) - def plate_number(self): + def plate_number(self) -> str: """Generate a number for license plates.""" return self.numerify(self.random_element(self.plate_number_formats)) - def plate_number_extra(self): + def plate_number_extra(self) -> str: """Generate extra numerical code for license plates.""" return self.numerify(self.random_element(self.plate_extra_formats)) - def plate_number_special(self): + def plate_number_special(self) -> str: """Generate a special code for license plates.""" return self.numerify(self.random_element(self.plate_special_formats)) - def plate_suffix(self): + def plate_suffix(self) -> str: """Generate a suffix code for license plates.""" return self.random_element(self.license_plate_suffix) - def vehicle_category(self): + def vehicle_category(self) -> str: """Generate a vehicle category code for license plates.""" return self.random_element(self.vehicle_categories) diff --git a/faker/providers/automotive/sk_SK/__init__.py b/faker/providers/automotive/sk_SK/__init__.py index ef2c1945e8..de15a14748 100644 --- a/faker/providers/automotive/sk_SK/__init__.py +++ b/faker/providers/automotive/sk_SK/__init__.py @@ -90,8 +90,8 @@ class Provider(AutomotiveProvider): '###??', ) - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" - prefix = self.random_element(self.license_plate_prefix) + prefix: str = self.random_element(self.license_plate_prefix) suffix = self.bothify(self.random_element(self.license_plate_suffix), letters=string.ascii_uppercase) return prefix + suffix diff --git a/faker/providers/automotive/th_TH/__init__.py b/faker/providers/automotive/th_TH/__init__.py index 187e13e6ff..078c210475 100644 --- a/faker/providers/automotive/th_TH/__init__.py +++ b/faker/providers/automotive/th_TH/__init__.py @@ -28,7 +28,7 @@ class Provider(AutomotiveProvider): thai_consonants = "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ" - def license_plate(self): + def license_plate(self) -> str: """Generate a license plate.""" temp = re.sub( diff --git a/faker/providers/bank/__init__.py b/faker/providers/bank/__init__.py index 9c7407b337..7cb79f81da 100644 --- a/faker/providers/bank/__init__.py +++ b/faker/providers/bank/__init__.py @@ -3,6 +3,7 @@ from math import ceil from string import ascii_uppercase +from typing import Dict, Optional from .. import BaseProvider @@ -26,11 +27,11 @@ class Provider(BaseProvider): - https://www.theswiftcodes.com/swift-code-checker/ """ - ALPHA = {c: str(ord(c) % 55) for c in string.ascii_uppercase} - bban_format = '????#############' - country_code = 'GB' + ALPHA: Dict[str, str] = {c: str(ord(c) % 55) for c in string.ascii_uppercase} + bban_format: str = '????#############' + country_code: str = 'GB' - def aba(self): + def aba(self) -> str: """Generate an ABA routing transit number.""" fed_num = self.random_int(min=1, max=12) rand = self.numerify('######') @@ -43,29 +44,29 @@ def aba(self): return f"{aba}{chk_digit}" - def bank_country(self): + def bank_country(self) -> str: """Generate the bank provider's ISO 3166-1 alpha-2 country code.""" return self.country_code - def bban(self): + def bban(self) -> str: """Generate a Basic Bank Account Number (BBAN).""" temp = re.sub(r'\?', lambda x: self.random_element(ascii_uppercase), self.bban_format) return self.numerify(temp) - def iban(self): + def iban(self) -> str: """Generate an International Bank Account Number (IBAN).""" bban = self.bban() check = bban + self.country_code + '00' - check = int(''.join(self.ALPHA.get(c, c) for c in check)) - check = 98 - (check % 97) - check = str(check).zfill(2) + check_ = int(''.join(self.ALPHA.get(c, c) for c in check)) + check_ = 98 - (check_ % 97) + check = str(check_).zfill(2) return self.country_code + check + bban - def swift8(self, use_dataset=False): + def swift8(self, use_dataset: bool = False) -> str: """Generate an 8-digit SWIFT code. This method uses |swift| under the hood with the ``length`` argument set @@ -77,7 +78,7 @@ def swift8(self, use_dataset=False): """ return self.swift(length=8, use_dataset=use_dataset) - def swift11(self, primary=None, use_dataset=False): + def swift11(self, primary: bool = False, use_dataset: bool = False) -> str: """Generate an 11-digit SWIFT code. This method uses |swift| under the hood with the ``length`` argument set @@ -90,7 +91,7 @@ def swift11(self, primary=None, use_dataset=False): """ return self.swift(length=11, primary=primary, use_dataset=use_dataset) - def swift(self, length=None, primary=None, use_dataset=False): + def swift(self, length: Optional[int] = None, primary: bool = False, use_dataset: bool = False) -> str: """Generate a SWIFT code. SWIFT codes, reading from left to right, are composed of a 4 alphabet @@ -129,12 +130,12 @@ def swift(self, length=None, primary=None, use_dataset=False): raise AssertionError('length can only be 8 or 11') if use_dataset and hasattr(self, 'swift_bank_codes'): - bank_code = self.random_element(self.swift_bank_codes) + bank_code: str = self.random_element(self.swift_bank_codes) # type: ignore[attr-defined] else: bank_code = self.lexify('????', letters=string.ascii_uppercase) if use_dataset and hasattr(self, 'swift_location_codes'): - location_code = self.random_element(self.swift_location_codes) + location_code: str = self.random_element(self.swift_location_codes) # type: ignore[attr-defined] else: location_code = self.lexify('??', letters=string.ascii_uppercase + string.digits) @@ -144,7 +145,7 @@ def swift(self, length=None, primary=None, use_dataset=False): if primary: branch_code = 'XXX' elif use_dataset and hasattr(self, 'swift_branch_codes'): - branch_code = self.random_element(self.swift_branch_codes) + branch_code = self.random_element(self.swift_branch_codes) # type: ignore[attr-defined] else: branch_code = self.lexify('???', letters=string.ascii_uppercase + string.digits) diff --git a/faker/providers/bank/en_PH/__init__.py b/faker/providers/bank/en_PH/__init__.py index 0bc9500ed2..29da2d5bc3 100644 --- a/faker/providers/bank/en_PH/__init__.py +++ b/faker/providers/bank/en_PH/__init__.py @@ -27,7 +27,7 @@ class Provider(BankProvider): 'CBU', 'EQI', 'TSU', 'XXX', ) - def bban(self): + def bban(self) -> str: """Generate a Basic Bank Account Number (BBAN). .. warning:: @@ -42,7 +42,7 @@ def bban(self): logger.warning("Numbers generated by this method are purely hypothetical.") return super().bban() - def iban(self): + def iban(self) -> str: """Generate an International Bank Account Number (IBAN). .. warning:: diff --git a/faker/providers/bank/ru_RU/__init__.py b/faker/providers/bank/ru_RU/__init__.py index 30a315fc9b..a0686382fd 100644 --- a/faker/providers/bank/ru_RU/__init__.py +++ b/faker/providers/bank/ru_RU/__init__.py @@ -122,18 +122,18 @@ class Provider(BankProvider): 'Эс-Би-Ай Банк', 'Ю Би Эс Банк', 'Юг-Инвестбанк', 'ЮМК Банк', 'Юникредит Банк', 'Юнистрим', 'Яринтербанк', ) - def bic(self): + def bic(self) -> str: """Generate a bank identification code (BIC). BIC is a bank identification code that is used in Russia. See https://ru.wikipedia.org/wiki/Банковский_идентификационный_код. """ - region = self.random_element(self.region_codes) - department_code = self.numerify(self.random_element(self.department_code_formats)) - credit_organization_code = self.numerify(self.random_element(self.credit_organization_code_formats)) + region: str = self.random_element(self.region_codes) + department_code: str = self.numerify(self.random_element(self.department_code_formats)) + credit_organization_code: str = self.numerify(self.random_element(self.credit_organization_code_formats)) return '04' + region + department_code + credit_organization_code - def correspondent_account(self): + def correspondent_account(self) -> str: """Generate a correspondent account number. Correspondent account is established to handle various financial @@ -143,18 +143,18 @@ def correspondent_account(self): credit_organization_code = self.numerify(self.random_element(self.credit_organization_code_formats)) return '301' + self.numerify('#' * 14) + credit_organization_code - def checking_account(self): + def checking_account(self) -> str: """Generate a checking account number. Checking account is used in banks to handle financial operations of clients. See https://ru.wikipedia.org/wiki/Расчётный_счёт. """ - account = self.random_element(self.checking_account_codes) - organization = self.random_element(self.organization_codes) - currency = self.random_element(self.currency_codes) + account: str = self.random_element(self.checking_account_codes) + organization: str = self.random_element(self.organization_codes) + currency: str = self.random_element(self.currency_codes) return account + organization + currency + self.numerify('#' * 12) - def bank(self): + def bank(self) -> str: """Generate a bank name.""" return self.random_element(self.banks) diff --git a/faker/providers/barcode/__init__.py b/faker/providers/barcode/__init__.py index e388f1d52a..4f29f79c10 100644 --- a/faker/providers/barcode/__init__.py +++ b/faker/providers/barcode/__init__.py @@ -1,7 +1,11 @@ +from typing import Tuple, Union + from .. import BaseProvider localized = True +PrefixType = Tuple[Union[int, str, Tuple[Union[int, str], ...]], ...] + class Provider(BaseProvider): """Implement default barcode provider for Faker. @@ -11,16 +15,16 @@ class Provider(BaseProvider): - https://gs1.org/standards/id-keys/company-prefix """ - local_prefixes = () + local_prefixes: PrefixType = () - def _ean(self, length=13, prefixes=()): + def _ean(self, length: int = 13, prefixes: PrefixType = ()) -> str: if length not in (8, 13): raise AssertionError("length can only be 8 or 13") code = [self.random_digit() for _ in range(length - 1)] if prefixes: - prefix = self.random_element(prefixes) + prefix: str = self.random_element(prefixes) code[:len(prefix)] = map(int, prefix) if length == 8: @@ -34,7 +38,7 @@ def _ean(self, length=13, prefixes=()): return ''.join(str(x) for x in code) - def ean(self, length=13, prefixes=()): + def ean(self, length: int = 13, prefixes: PrefixType = ()) -> str: """Generate an EAN barcode of the specified ``length``. The value of ``length`` can only be ``8`` or ``13`` (default) which will @@ -50,7 +54,7 @@ def ean(self, length=13, prefixes=()): """ return self._ean(length, prefixes=prefixes) - def ean8(self, prefixes=()): + def ean8(self, prefixes: Tuple[()] = ()) -> str: """Generate an EAN-8 barcode. This method uses |ean| under the hood with the ``length`` argument @@ -65,7 +69,7 @@ def ean8(self, prefixes=()): """ return self._ean(8, prefixes=prefixes) - def ean13(self, prefixes=()): + def ean13(self, prefixes: PrefixType = ()) -> str: """Generate an EAN-13 barcode. This method uses |ean| under the hood with the ``length`` argument @@ -85,7 +89,7 @@ def ean13(self, prefixes=()): """ return self._ean(13, prefixes=prefixes) - def localized_ean(self, length=13): + def localized_ean(self, length: int = 13) -> str: """Generate a localized EAN barcode of the specified ``length``. The value of ``length`` can only be ``8`` or ``13`` (default) which will @@ -101,7 +105,7 @@ def localized_ean(self, length=13): """ return self._ean(length, prefixes=self.local_prefixes) - def localized_ean8(self): + def localized_ean8(self) -> str: """Generate a localized EAN-8 barcode. This method uses |localized_ean| under the hood with the ``length`` @@ -109,7 +113,7 @@ def localized_ean8(self): """ return self.localized_ean(8) - def localized_ean13(self): + def localized_ean13(self) -> str: """Generate a localized EAN-13 barcode. This method uses |localized_ean| under the hood with the ``length`` diff --git a/faker/providers/barcode/en_US/__init__.py b/faker/providers/barcode/en_US/__init__.py index 9a3578e618..9802d4ad6e 100644 --- a/faker/providers/barcode/en_US/__init__.py +++ b/faker/providers/barcode/en_US/__init__.py @@ -1,7 +1,9 @@ import re from itertools import product +from typing import Dict, Optional, Pattern +from .. import PrefixType from .. import Provider as BarcodeProvider @@ -18,8 +20,8 @@ class Provider(BarcodeProvider): *product((1,), range(4)), ) - upc_e_base_pattern = re.compile(r'^\d{6}$') - upc_ae_pattern1 = re.compile( + upc_e_base_pattern: Pattern = re.compile(r'^\d{6}$') + upc_ae_pattern1: Pattern = re.compile( r'^(?P[01])' # The first digit must be 0 or 1 r'(?=\d{11}$)' # followed by 11 digits of which r'(?P\d{2})' # the first 2 digits make up the manufacturer code, @@ -27,7 +29,7 @@ class Provider(BarcodeProvider): r'(?P\d{3})' # a 3-digit product code, r'(?P\d)$', # and finally a check digit. ) - upc_ae_pattern2 = re.compile( + upc_ae_pattern2: Pattern = re.compile( r'^(?P[01])' # The first digit must be 0 or 1 r'(?=\d{11}$)' # followed by 11 digits of which r'(?P\d{3,4}?)' # the first 3 or 4 digits make up the manufacturer code, @@ -35,7 +37,7 @@ class Provider(BarcodeProvider): r'(?P\d{1,2})' # a 2-digit or single digit product code, r'(?P\d)$', # and finally a check digit. ) - upc_ae_pattern3 = re.compile( + upc_ae_pattern3: Pattern = re.compile( r'^(?P[01])' # The first digit must be 0 or 1 r'(?=\d{11}$)' # followed by 11 digits of which r'(?P\d{5})' # the first 5 digits make up the manufacturer code, @@ -43,7 +45,7 @@ class Provider(BarcodeProvider): r'(?P\d)$', # and finally a check digit. ) - def ean13(self, leading_zero=None, prefixes=()): + def ean13(self, prefixes: PrefixType = (), leading_zero: Optional[bool] = None) -> str: """Generate an EAN-13 barcode. If ``leading_zero`` is ``True``, the leftmost digit of the barcode will @@ -82,7 +84,7 @@ def ean13(self, leading_zero=None, prefixes=()): return super().ean13(prefixes=prefixes) - def _convert_upc_a2e(self, upc_a): + def _convert_upc_a2e(self, upc_a: str) -> str: """Convert a 12-digit UPC-A barcode to its 8-digit UPC-E equivalent. .. warning:: @@ -99,16 +101,17 @@ def _convert_upc_a2e(self, upc_a): if m1: upc_e = upc_e_template.format(**m1.groupdict()) elif m2: - groupdict = m2.groupdict() - groupdict['extra'] = str(len(groupdict.get('mfr_code'))) + groupdict: Dict[str, str] = m2.groupdict() + mfr_code = groupdict.get('mfr_code') or "" + groupdict['extra'] = str(len(mfr_code)) upc_e = upc_e_template.format(**groupdict) - else: + elif m3: groupdict = m3.groupdict() groupdict['product_code'] = '' upc_e = upc_e_template.format(**groupdict) return upc_e - def _upc_ae(self, base=None, number_system_digit=None): + def _upc_ae(self, base: Optional[str] = None, number_system_digit: Optional[int] = None) -> str: """Create a 12-digit UPC-A barcode that can be converted to UPC-E. The expected value of ``base`` is a 6-digit string. If any other value @@ -121,19 +124,17 @@ def _upc_ae(self, base=None, number_system_digit=None): Please also view notes on |EnUsBarcodeProvider.upc_a| and |EnUsBarcodeProvider.upc_e| for more details. """ - if isinstance(base, str) and self.upc_e_base_pattern.match(base): - base = [int(x) for x in base] - else: - base = [self.random_int(0, 9) for _ in range(6)] + base_ = [int(x) for x in base] if isinstance(base, str) and self.upc_e_base_pattern.match(base) \ + else [self.random_int(0, 9) for _ in range(6)] if number_system_digit not in [0, 1]: number_system_digit = self.random_int(0, 1) - if base[-1] <= 2: - code = base[:2] + base[-1:] + [0] * 4 + base[2:-1] - elif base[-1] <= 4: - code = base[:base[-1]] + [0] * 5 + base[base[-1]:-1] + if base_[-1] <= 2: + code = base_[:2] + base_[-1:] + [0] * 4 + base_[2:-1] + elif base_[-1] <= 4: + code = base_[:base_[-1]] + [0] * 5 + base_[base_[-1]:-1] else: - code = base[:5] + [0] * 4 + base[-1:] + code = base_[:5] + [0] * 4 + base_[-1:] code.insert(0, number_system_digit) weights = [3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3] @@ -142,7 +143,10 @@ def _upc_ae(self, base=None, number_system_digit=None): code.append(check_digit) return ''.join(str(x) for x in code) - def upc_a(self, upc_ae_mode=False, base=None, number_system_digit=None): + def upc_a(self, + upc_ae_mode: bool = False, + base: Optional[str] = None, + number_system_digit: Optional[int] = None) -> str: """Generate a 12-digit UPC-A barcode. The value of ``upc_ae_mode`` controls how barcodes will be generated. If @@ -182,7 +186,10 @@ def upc_a(self, upc_ae_mode=False, base=None, number_system_digit=None): ean13 = self.ean13(leading_zero=True) return ean13[1:] - def upc_e(self, base=None, number_system_digit=None, safe_mode=True): + def upc_e(self, + base: Optional[str] = None, + number_system_digit: Optional[int] = None, + safe_mode: bool = True) -> str: """Generate an 8-digit UPC-E barcode. UPC-E barcodes can be expressed in 6, 7, or 8-digit formats, but this @@ -232,4 +239,4 @@ def upc_e(self, base=None, number_system_digit=None, safe_mode=True): return self._convert_upc_a2e(upc_ae) else: upc_ae = self._upc_ae(base=base, number_system_digit=number_system_digit) - return upc_ae[0] + ''.join(str(x) for x in base) + upc_ae[-1] + return upc_ae[0] + ''.join(str(x) for x in base or "") + upc_ae[-1] diff --git a/faker/providers/barcode/ja_JP/__init__.py b/faker/providers/barcode/ja_JP/__init__.py index 4fc6191b06..b4d571f283 100644 --- a/faker/providers/barcode/ja_JP/__init__.py +++ b/faker/providers/barcode/ja_JP/__init__.py @@ -23,7 +23,7 @@ class Provider(BarcodeProvider): local_prefixes = (4, 5), (4, 9) - def jan(self, length=13): + def jan(self, length: int = 13) -> str: """Generate a JAN barcode of the specified ``length``. This method is an alias for |JaJpProvider.localized_ean|. @@ -34,14 +34,14 @@ def jan(self, length=13): """ return self.localized_ean(length) - def jan8(self): + def jan8(self) -> str: """Generate a 8 digit JAN barcode. This method is an alias for |JaJpProvider.localized_ean8|. """ return self.localized_ean8() - def jan13(self): + def jan13(self) -> str: """Generate a 13 digit JAN barcode. This method is an alias for |JaJpProvider.localized_ean13|. diff --git a/faker/providers/color/__init__.py b/faker/providers/color/__init__.py index 2263147573..ef0d0e5afc 100644 --- a/faker/providers/color/__init__.py +++ b/faker/providers/color/__init__.py @@ -1,6 +1,8 @@ from collections import OrderedDict +from typing import Dict, Optional -from .. import BaseProvider +from ...typing import HueType +from .. import BaseProvider, ElementsType from .color import RandomColor localized = True @@ -9,7 +11,7 @@ class Provider(BaseProvider): """Implement default color provider for Faker.""" - all_colors = OrderedDict(( + all_colors: Dict[str, str] = OrderedDict(( ("AliceBlue", "#F0F8FF"), ("AntiqueWhite", "#FAEBD7"), ("Aqua", "#00FFFF"), @@ -152,37 +154,40 @@ class Provider(BaseProvider): ("YellowGreen", "#9ACD32"), )) - safe_colors = ( + safe_colors: ElementsType = ( 'black', 'maroon', 'green', 'navy', 'olive', 'purple', 'teal', 'lime', 'blue', 'silver', 'gray', 'yellow', 'fuchsia', 'aqua', 'white', ) - def color_name(self): + def color_name(self) -> str: """Generate a color name.""" return self.random_element(self.all_colors.keys()) - def safe_color_name(self): + def safe_color_name(self) -> str: """Generate a web-safe color name.""" return self.random_element(self.safe_colors) - def hex_color(self): + def hex_color(self) -> str: """Generate a color formatted as a hex triplet.""" return f'#{self.random_int(1, 16777215):06x}' - def safe_hex_color(self): + def safe_hex_color(self) -> str: """Generate a web-safe color formatted as a hex triplet.""" return f'#{self.random_int(0, 15) * 17:02x}{self.random_int(0, 15) * 17:02x}{self.random_int(0, 15) * 17:02x}' - def rgb_color(self): + def rgb_color(self) -> str: """Generate a color formatted as a comma-separated RGB value.""" return ','.join(map(str, (self.random_int(0, 255) for _ in range(3)))) - def rgb_css_color(self): + def rgb_css_color(self) -> str: """Generate a color formatted as a CSS rgb() function.""" return f'rgb({self.random_int(0, 255)},{self.random_int(0, 255)},{self.random_int(0, 255)})' - def color(self, hue=None, luminosity=None, color_format='hex'): + def color(self, + hue: Optional[HueType] = None, + luminosity: Optional[str] = None, + color_format: str = 'hex') -> str: """Generate a color in a human-friendly way. Under the hood, this method first creates a color represented in the HSV diff --git a/faker/providers/color/color.py b/faker/providers/color/color.py index 3b539bee7e..1c30f7d3b3 100644 --- a/faker/providers/color/color.py +++ b/faker/providers/color/color.py @@ -16,63 +16,70 @@ import random import sys -COLOR_MAP = { +from typing import TYPE_CHECKING, Dict, Hashable, Optional, Sequence, Tuple + +if TYPE_CHECKING: + from ...factory import Generator + +from ...typing import HueType + +COLOR_MAP: Dict[str, Dict[str, Sequence[Tuple[int, int]]]] = { 'monochrome': { - 'hue_range': [0, 0], + 'hue_range': [(0, 0)], 'lower_bounds': [ - [0, 0], [100, 0], + (0, 0), (100, 0), ], }, 'red': { - 'hue_range': [-26, 18], + 'hue_range': [(-26, 18)], 'lower_bounds': [ - [20, 100], [30, 92], [40, 89], - [50, 85], [60, 78], [70, 70], - [80, 60], [90, 55], [100, 50], + (20, 100), (30, 92), (40, 89), + (50, 85), (60, 78), (70, 70), + (80, 60), (90, 55), (100, 50), ], }, 'orange': { - 'hue_range': [19, 46], + 'hue_range': [(19, 46)], 'lower_bounds': [ - [20, 100], [30, 93], [40, 88], [50, 86], - [60, 85], [70, 70], [100, 70], + (20, 100), (30, 93), (40, 88), (50, 86), + (60, 85), (70, 70), (100, 70), ], }, 'yellow': { - 'hue_range': [47, 62], + 'hue_range': [(47, 62)], 'lower_bounds': [ - [25, 100], [40, 94], [50, 89], [60, 86], - [70, 84], [80, 82], [90, 80], [100, 75], + (25, 100), (40, 94), (50, 89), (60, 86), + (70, 84), (80, 82), (90, 80), (100, 75), ], }, 'green': { - 'hue_range': [63, 178], + 'hue_range': [(63, 178)], 'lower_bounds': [ - [30, 100], [40, 90], [50, 85], [60, 81], - [70, 74], [80, 64], [90, 50], [100, 40], + (30, 100), (40, 90), (50, 85), (60, 81), + (70, 74), (80, 64), (90, 50), (100, 40), ], }, 'blue': { - 'hue_range': [179, 257], + 'hue_range': [(179, 257)], 'lower_bounds': [ - [20, 100], [30, 86], [40, 80], - [50, 74], [60, 60], [70, 52], - [80, 44], [90, 39], [100, 35], + (20, 100), (30, 86), (40, 80), + (50, 74), (60, 60), (70, 52), + (80, 44), (90, 39), (100, 35), ], }, 'purple': { - 'hue_range': [258, 282], + 'hue_range': [(258, 282)], 'lower_bounds': [ - [20, 100], [30, 87], [40, 79], - [50, 70], [60, 65], [70, 59], - [80, 52], [90, 45], [100, 42], + (20, 100), (30, 87), (40, 79), + (50, 70), (60, 65), (70, 59), + (80, 52), (90, 45), (100, 42), ], }, 'pink': { - 'hue_range': [283, 334], + 'hue_range': [(283, 334)], 'lower_bounds': [ - [20, 100], [30, 90], [40, 86], [60, 84], - [80, 80], [90, 75], [100, 73], + (20, 100), (30, 90), (40, 86), (60, 84), + (80, 80), (90, 75), (100, 73), ], }, } @@ -85,7 +92,7 @@ class RandomColor: :meth:`color() ` method. """ - def __init__(self, generator=None, seed=None): + def __init__(self, generator: Optional["Generator"] = None, seed: Optional[Hashable] = None) -> None: self.colormap = COLOR_MAP # Option to specify a seed was not removed so this class @@ -97,17 +104,17 @@ def __init__(self, generator=None, seed=None): self.random = random.Random(self.seed) for color_name, color_attrs in self.colormap.items(): - lower_bounds = color_attrs['lower_bounds'] - s_min = lower_bounds[0][0] - s_max = lower_bounds[-1][0] - - b_min = lower_bounds[-1][1] - b_max = lower_bounds[0][1] + lower_bounds: Sequence[Tuple[int, int]] = color_attrs['lower_bounds'] + s_min, b_max = lower_bounds[0] + s_max, b_min = lower_bounds[-1] - self.colormap[color_name]['saturation_range'] = [s_min, s_max] - self.colormap[color_name]['brightness_range'] = [b_min, b_max] + self.colormap[color_name]['saturation_range'] = [(s_min, s_max)] + self.colormap[color_name]['brightness_range'] = [(b_min, b_max)] - def generate(self, hue=None, luminosity=None, color_format='hex'): + def generate(self, + hue: Optional[HueType] = None, + luminosity: Optional[str] = None, + color_format: str = 'hex') -> str: """Generate a color. Whenever :meth:`color() ` is @@ -124,32 +131,30 @@ def generate(self, hue=None, luminosity=None, color_format='hex'): b = self.pick_brightness(h, s, luminosity) # Then we return the HSB color in the desired format - return self.set_format([h, s, b], color_format) + return self.set_format((h, s, b), color_format) - def pick_hue(self, hue): + def pick_hue(self, hue: Optional[HueType]) -> int: """Return a numerical hue value.""" - hue_range = self.get_hue_range(hue) - hue = self.random_within(hue_range) + hue_ = self.random_within(self.get_hue_range(hue)) # Instead of storing red as two separate ranges, # we group them, using negative numbers - if hue < 0: - hue += 360 + if hue_ < 0: + hue_ += 360 - return hue + return hue_ - def pick_saturation(self, hue, hue_name, luminosity): + def pick_saturation(self, hue: int, hue_name: Optional[HueType], luminosity: Optional[str]) -> int: """Return a numerical saturation value.""" + if luminosity is None: + luminosity = '' if luminosity == 'random': - return self.random_within([0, 100]) + return self.random_within((0, 100)) - if hue_name == 'monochrome': + if isinstance(hue_name, str) and hue_name == 'monochrome': return 0 - saturation_range = self.get_saturation_range(hue) - - s_min = saturation_range[0] - s_max = saturation_range[1] + s_min, s_max = self.get_saturation_range(hue) if luminosity == 'bright': s_min = 55 @@ -158,125 +163,122 @@ def pick_saturation(self, hue, hue_name, luminosity): elif luminosity == 'light': s_max = 55 - return self.random_within([s_min, s_max]) + return self.random_within((s_min, s_max)) - def pick_brightness(self, h, s, luminosity): + def pick_brightness(self, h: int, s: int, luminosity: Optional[str]) -> int: """Return a numerical brightness value.""" + if luminosity is None: + luminosity = '' + b_min = self.get_minimum_brightness(h, s) b_max = 100 if luminosity == 'dark': b_max = b_min + 20 elif luminosity == 'light': - b_min = (b_max + b_min) / 2 + b_min = (b_max + b_min) // 2 elif luminosity == 'random': b_min = 0 b_max = 100 - return self.random_within([b_min, b_max]) + return self.random_within((b_min, b_max)) - def set_format(self, hsv, color_format): + def set_format(self, hsv: Tuple[int, int, int], color_format: str) -> str: """Handle conversion of HSV values into desired format.""" if color_format == 'hsv': color = f'hsv({hsv[0]}, {hsv[1]}, {hsv[2]})' elif color_format == 'hsl': - hsl = tuple(self.hsv_to_hsl(hsv)) + hsl = self.hsv_to_hsl(hsv) color = f'hsl({hsl[0]}, {hsl[1]}, {hsl[2]})' elif color_format == 'rgb': - rgb = tuple(self.hsv_to_rgb(hsv)) + rgb = self.hsv_to_rgb(hsv) color = f'rgb({rgb[0]}, {rgb[1]}, {rgb[2]})' else: - rgb = tuple(self.hsv_to_rgb(hsv)) + rgb = self.hsv_to_rgb(hsv) color = f'#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}' return color - def get_minimum_brightness(self, h, s): + def get_minimum_brightness(self, h: int, s: int) -> int: """Return the minimum allowed brightness for ``h`` and ``s``.""" - lower_bounds = self.get_color_info(h)['lower_bounds'] + lower_bounds: Sequence[Tuple[int, int]] = self.get_color_info(h)['lower_bounds'] for i in range(len(lower_bounds) - 1): - s1 = lower_bounds[i][0] - v1 = lower_bounds[i][1] - - s2 = lower_bounds[i + 1][0] - v2 = lower_bounds[i + 1][1] + s1, v1 = lower_bounds[i] + s2, v2 = lower_bounds[i + 1] if s1 <= s <= s2: - m = (v2 - v1) / (s2 - s1) - b = v1 - m * s1 + m: float = (v2 - v1) / (s2 - s1) + b: float = v1 - m * s1 - return m * s + b + return int(m * s + b) return 0 - def get_hue_range(self, color_input): + def get_hue_range(self, color_input: Optional[HueType]) -> Tuple[int, int]: """Return the hue range for a given ``color_input``.""" if isinstance(color_input, (int, float)) and 0 <= color_input <= 360: color_input = int(color_input) - return [color_input, color_input] - + return (color_input, color_input) elif isinstance(color_input, str) and color_input in self.colormap: - return self.colormap[color_input]['hue_range'] - + return self.colormap[color_input]['hue_range'][0] elif color_input is None: - return [0, 360] - - try: - v1, v2 = color_input - v1 = int(v1) - v2 = int(v2) - except (ValueError, TypeError): - msg = 'Hue must be a valid string, numeric type, or a tuple/list of 2 numeric types.' - raise TypeError(msg) - else: + return (0, 360) + + if isinstance(color_input, list): + color_input = tuple(color_input) + if (isinstance(color_input, tuple) and len(color_input) == 2 + and all(isinstance(c, (float, int)) for c in color_input)): + v1 = int(color_input[0]) + v2 = int(color_input[1]) + if v2 < v1: v1, v2 = v2, v1 - if v1 < 0: - v1 = 0 - if v2 > 360: - v2 = 360 - return [v1, v2] + v1 = max(v1, 0) + v2 = min(v2, 360) + return (v1, v2) + raise TypeError('Hue must be a valid string, numeric type, or a tuple/list of 2 numeric types.') - def get_saturation_range(self, hue): + def get_saturation_range(self, hue: int) -> Tuple[int, int]: """Return the saturation range for a given numerical ``hue`` value.""" - return self.get_color_info(hue)['saturation_range'] + return self.get_color_info(hue)['saturation_range'][0] - def get_color_info(self, hue): + def get_color_info(self, hue: int) -> Dict[str, Sequence[Tuple[int, int]]]: """Return the color info for a given numerical ``hue`` value.""" # Maps red colors to make picking hue easier if 334 <= hue <= 360: hue -= 360 for color_name, color in self.colormap.items(): - if color['hue_range'][0] <= hue <= color['hue_range'][1]: + hue_range: Tuple[int, int] = color['hue_range'][0] + if hue_range[0] <= hue <= hue_range[1]: return self.colormap[color_name] else: raise ValueError('Value of hue `%s` is invalid.' % hue) - def random_within(self, r): + def random_within(self, r: Sequence[int]) -> int: """Return a random integer within the range ``r``.""" return self.random.randint(int(r[0]), int(r[1])) @classmethod - def hsv_to_rgb(cls, hsv): + def hsv_to_rgb(cls, hsv: Tuple[int, int, int]) -> Tuple[int, int, int]: """Convert HSV to RGB. This method expects ``hsv`` to be a 3-tuple of H, S, and V values, and it will return a 3-tuple of the equivalent R, G, and B values. """ h, s, v = hsv - h = 1 if h == 0 else h - h = 359 if h == 360 else h + h = max(h, 1) + h = min(h, 359) - rgb = colorsys.hsv_to_rgb(h / 360, s / 100, v / 100) - return (int(c * 255) for c in rgb) + r, g, b = colorsys.hsv_to_rgb(h / 360, s / 100, v / 100) + return (int(r * 255), int(g * 255), int(b * 255)) @classmethod - def hsv_to_hsl(cls, hsv): + def hsv_to_hsl(cls, hsv: Tuple[int, int, int]) -> Tuple[int, int, int]: """Convert HSV to HSL. This method expects ``hsv`` to be a 3-tuple of H, S, and V values, and @@ -284,12 +286,9 @@ def hsv_to_hsl(cls, hsv): """ h, s, v = hsv - s = s / 100 - v = v / 100 - l = 0.5 * v * (2 - s) # noqa: E741 + s_: float = s / 100.0 + v_: float = v / 100.0 + l = 0.5 * (v_) * (2 - s_) # noqa: E741 - if l in [0, 1]: - s = 0 - else: - s = v * s / (1 - math.fabs(2 * l - 1)) - return (int(c) for c in [h, s * 100, l * 100]) + s_ = 0.0 if l in [0, 1] else v_ * s_ / (1 - math.fabs(2 * l - 1)) + return (int(h), int(s_ * 100), int(l * 100)) diff --git a/faker/providers/color/he_IL/__init__.py b/faker/providers/color/he_IL/__init__.py index be1a3fae5a..e338648dbb 100644 --- a/faker/providers/color/he_IL/__init__.py +++ b/faker/providers/color/he_IL/__init__.py @@ -60,11 +60,11 @@ class Provider(ColorProvider): )) safe_colors = ( - "אדום", - "ירוק", - "כחול", - "צהוב", - "ציאן", - "מג'נטה", - "לבן", + "אדום", + "ירוק", + "כחול", + "צהוב", + "ציאן", + "מג'נטה", + "לבן", ) diff --git a/faker/providers/company/__init__.py b/faker/providers/company/__init__.py index ecf2fc36fe..da46eb604a 100644 --- a/faker/providers/company/__init__.py +++ b/faker/providers/company/__init__.py @@ -1,18 +1,20 @@ -from .. import BaseProvider +from typing import Tuple + +from .. import BaseProvider, ElementsType localized = True class Provider(BaseProvider): - formats = ( + formats: ElementsType = ( '{{last_name}} {{company_suffix}}', '{{last_name}}-{{last_name}}', '{{last_name}}, {{last_name}} and {{last_name}}', ) - company_suffixes = ('Inc', 'and Sons', 'LLC', 'Group', 'PLC', 'Ltd') + company_suffixes: ElementsType = ('Inc', 'and Sons', 'LLC', 'Group', 'PLC', 'Ltd') - catch_phrase_words = ( + catch_phrase_words: Tuple[ElementsType, ...] = ( ('Adaptive', 'Advanced', 'Ameliorated', @@ -319,7 +321,7 @@ class Provider(BaseProvider): 'website', 'workforce')) - bsWords = ( + bsWords: Tuple[ElementsType, ...] = ( ('implement', 'utilize', 'integrate', @@ -489,35 +491,27 @@ class Provider(BaseProvider): 'web services', 'methodologies')) - def company(self): + def company(self) -> str: """ :example 'Acme Ltd' """ - pattern = self.random_element(self.formats) + pattern: str = self.random_element(self.formats) return self.generator.parse(pattern) - def company_suffix(self): + def company_suffix(self) -> str: """ :example 'Ltd' """ return self.random_element(self.company_suffixes) - def catch_phrase(self): + def catch_phrase(self) -> str: """ :example 'Robust full-range hub' """ - result = [] - for word_list in self.catch_phrase_words: - result.append(self.random_element(word_list)) - - return " ".join(result) + return ' '.join([self.random_element(word_list) for word_list in self.catch_phrase_words]) - def bs(self): + def bs(self) -> str: """ :example 'integrate extensible convergence' """ - result = [] - for word_list in self.bsWords: - result.append(self.random_element(word_list)) - - return " ".join(result) + return ' '.join([self.random_element(word_list) for word_list in self.bsWords]) diff --git a/faker/providers/company/en_PH/__init__.py b/faker/providers/company/en_PH/__init__.py index b528ca31af..128d2a1868 100644 --- a/faker/providers/company/en_PH/__init__.py +++ b/faker/providers/company/en_PH/__init__.py @@ -114,18 +114,18 @@ class Provider(CompanyProvider): 'Prime', ) - def company_type(self): + def company_type(self) -> str: return self.random_element(self.company_types) - def random_company_adjective(self): + def random_company_adjective(self) -> str: return self.random_element(self.company_adjectives) - def random_company_noun_chain(self): + def random_company_noun_chain(self) -> str: return ' '.join(self.random_elements(self.company_nouns, length=self.random_int(1, 2), unique=True)) - def random_company_product(self): + def random_company_product(self) -> str: return self.random_element(self.company_products) - def random_company_acronym(self): + def random_company_acronym(self) -> str: letters = self.random_letters(self.random_int(2, 4)) return ''.join(letters).upper() diff --git a/faker/providers/company/es_MX/__init__.py b/faker/providers/company/es_MX/__init__.py index a260be1b77..c2b67d94fd 100644 --- a/faker/providers/company/es_MX/__init__.py +++ b/faker/providers/company/es_MX/__init__.py @@ -141,28 +141,8 @@ class Provider(CompanyProvider): company_suffixes = ('A.C.', 'S.A.', 'S.A. de C.V.', 'S.C.', 'S. R.L. de C.V.', 'e Hijos', 'y Asociados') - def company_prefix(self): + def company_prefix(self) -> str: """ Ejemplo: Grupo """ return self.random_element(self.company_preffixes) - - def catch_phrase(self): - """ - :example 'Robust full-range hub' - """ - result = [] - for word_list in self.catch_phrase_words: - result.append(self.random_element(word_list)) - - return " ".join(result) - - def bs(self): - """ - :example 'integrate extensible convergence' - """ - result = [] - for word_list in self.bsWords: - result.append(self.random_element(word_list)) - - return " ".join(result) diff --git a/faker/providers/company/fa_IR/__init__.py b/faker/providers/company/fa_IR/__init__.py index 267aedf605..8e5923edf0 100644 --- a/faker/providers/company/fa_IR/__init__.py +++ b/faker/providers/company/fa_IR/__init__.py @@ -1110,5 +1110,5 @@ class Provider(CompanyProvider): 'الک تیک', ] - def company(self): + def company(self) -> str: return self.random_element(self.company_names) diff --git a/faker/providers/company/fi_FI/__init__.py b/faker/providers/company/fi_FI/__init__.py index f7b010f2cf..ec9887de1a 100644 --- a/faker/providers/company/fi_FI/__init__.py +++ b/faker/providers/company/fi_FI/__init__.py @@ -13,7 +13,7 @@ class Provider(CompanyProvider): 'As Oy', 'Tmi', 'Oy', 'Oyj', 'Ky', 'Osk', 'ry', ) - def company_business_id(self): + def company_business_id(self) -> str: """ Returns Finnish company Business Identity Code (y-tunnus). Format is 8 digits - e.g. FI99999999,[8] last digit is a check @@ -21,7 +21,7 @@ def company_business_id(self): organizations. This function provides current codes starting with non-zero. """ - def calculate_checksum(number): + def calculate_checksum(number: str) -> str: """Calculate the checksum using mod 11,2 method""" factors = [7, 9, 10, 5, 8, 4, 2] sum_ = 0 @@ -43,13 +43,13 @@ def calculate_checksum(number): continue return body + '-' + str(cs) - def company_vat(self): + def company_vat(self) -> str: """ Returns Finnish VAT identification number (Arvonlisaveronumero). This can be calculated from company business identity code by adding prefix "FI" and removing dash before checksum. """ - def convert_to_vat(business_id): + def convert_to_vat(business_id: str) -> str: """ Convert business id to VATIN """ diff --git a/faker/providers/company/fil_PH/__init__.py b/faker/providers/company/fil_PH/__init__.py index 9a09f07115..0e3be3804b 100644 --- a/faker/providers/company/fil_PH/__init__.py +++ b/faker/providers/company/fil_PH/__init__.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from typing import Sequence from ..en_PH import Provider as EnPhProvider @@ -65,21 +66,21 @@ class Provider(EnPhProvider): 'tahanan', ] - def random_noun_ish_good_trait(self): + def random_noun_ish_good_trait(self) -> str: return self.random_element(self.noun_ish_good_traits) - def random_good_service_adjective(self): + def random_good_service_adjective(self) -> str: return self.random_element(self.good_service_adjectives) - def random_good_service_adjective_chain(self): - adjectives = self.random_elements(self.good_service_adjectives, length=2, unique=True) + def random_good_service_adjective_chain(self) -> str: + adjectives: Sequence[str] = self.random_elements(self.good_service_adjectives, length=2, unique=True) return ' at '.join(adjectives) - def random_object_of_concern(self): + def random_object_of_concern(self) -> str: return self.random_element(self.objects_of_concern) - def english_catch_phrase(self): + def english_catch_phrase(self) -> str: return super().catch_phrase() - def catch_phrase(self): + def catch_phrase(self) -> str: return self.random_element(self.catch_phrase_formats) diff --git a/faker/providers/company/fr_CH/__init__.py b/faker/providers/company/fr_CH/__init__.py index 224ec87302..5391bb5d6f 100644 --- a/faker/providers/company/fr_CH/__init__.py +++ b/faker/providers/company/fr_CH/__init__.py @@ -1,15 +1,17 @@ +from typing import List + from ..fr_FR import Provider as CompanyProvider class Provider(CompanyProvider): company_suffixes = ('SA', 'Sàrl.') - def ide(self): + 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 _checksum(digits): + def _checksum(digits: List[int]) -> int: factors = (5, 4, 3, 2, 7, 6, 5, 4) sum_ = 0 for i in range(len(digits)): diff --git a/faker/providers/company/fr_FR/__init__.py b/faker/providers/company/fr_FR/__init__.py index 448f3c7a47..7124ebc372 100644 --- a/faker/providers/company/fr_FR/__init__.py +++ b/faker/providers/company/fr_FR/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as CompanyProvider @@ -51,36 +53,36 @@ class Provider(CompanyProvider): 'de manière sûre', 'en toute sécurité') - company_suffixes = ('SA', 'S.A.', 'SARL', 'S.A.R.L.', 'S.A.S.', 'et Fils') + company_suffixes: Tuple[str, ...] = ('SA', 'S.A.', 'SARL', 'S.A.R.L.', 'S.A.S.', 'et Fils') siren_format = "### ### ###" - def catch_phrase_noun(self): + def catch_phrase_noun(self) -> str: """ Returns a random catch phrase noun. """ return self.random_element(self.nouns) - def catch_phrase_attribute(self): + def catch_phrase_attribute(self) -> str: """ Returns a random catch phrase attribute. """ return self.random_element(self.attributes) - def catch_phrase_verb(self): + def catch_phrase_verb(self) -> str: """ Returns a random catch phrase verb. """ return self.random_element(self.verbs) - def catch_phrase(self): + def catch_phrase(self) -> str: """ :example 'integrate extensible convergence' """ catch_phrase = "" while True: - pattern = self.random_element(self.catch_phrase_formats) + pattern: str = self.random_element(self.catch_phrase_formats) catch_phrase = self.generator.parse(pattern) catch_phrase = catch_phrase[0].upper() + catch_phrase[1:] @@ -92,7 +94,7 @@ def catch_phrase(self): # An array containing string which should not appear twice in a catch phrase words_which_should_not_appear_twice = ('sécurité', 'simpl') - def _is_catch_phrase_valid(self, catch_phrase): + def _is_catch_phrase_valid(self, catch_phrase: str) -> bool: """ Validates a french catch phrase. @@ -108,13 +110,13 @@ def _is_catch_phrase_valid(self, catch_phrase): return True - def siren(self): + def siren(self) -> str: """ Generates a siren number (9 digits). """ return self.numerify(self.siren_format) - def siret(self, max_sequential_digits=2): + def siret(self, max_sequential_digits: int = 2) -> str: """ Generates a siret number (14 digits). It is in fact the result of the concatenation of a siren number (9 digits), diff --git a/faker/providers/company/hu_HU/__init__.py b/faker/providers/company/hu_HU/__init__.py index 5d6649e17f..b11a702ccb 100644 --- a/faker/providers/company/hu_HU/__init__.py +++ b/faker/providers/company/hu_HU/__init__.py @@ -11,5 +11,5 @@ class Provider(CompanyProvider): company_suffixes = ('Kft.', 'Kht.', 'Zrt.', 'Bt.', 'Nyrt.', 'Kkt.') - def company_suffix(self): + def company_suffix(self) -> str: return self.random_element(self.company_suffixes) diff --git a/faker/providers/company/id_ID/__init__.py b/faker/providers/company/id_ID/__init__.py index 7ec5d37023..ced5cdc3c0 100644 --- a/faker/providers/company/id_ID/__init__.py +++ b/faker/providers/company/id_ID/__init__.py @@ -23,5 +23,5 @@ class Provider(CompanyProvider): '(Persero) Tbk', 'Tbk', ) - def company_prefix(self): + def company_prefix(self) -> str: return self.random_element(self.company_prefixes) diff --git a/faker/providers/company/it_IT/__init__.py b/faker/providers/company/it_IT/__init__.py index 0acc22530a..adf0d1df39 100644 --- a/faker/providers/company/it_IT/__init__.py +++ b/faker/providers/company/it_IT/__init__.py @@ -332,27 +332,7 @@ class Provider(CompanyProvider): company_suffixes = ('SPA', 'e figli', 'Group', 's.r.l.') - def catch_phrase(self): - """ - :example 'Robust full-range hub' - """ - result = [] - for word_list in self.catch_phrase_words: - result.append(self.random_element(word_list)) - - return " ".join(result) - - def bs(self): - """ - :example 'integrate extensible convergence' - """ - result = [] - for word_list in self.bsWords: - result.append(self.random_element(word_list)) - - return " ".join(result) - - def _random_vat_office(self): + def _random_vat_office(self) -> int: """ Returns a random code identifying the VAT office needed to build a valid VAT with company_vat. @@ -372,10 +352,10 @@ def _random_vat_office(self): # else: between 1 and 100 are all valid return val - def company_vat(self): + def company_vat(self) -> str: """ Returns Italian VAT identification number (Partita IVA). """ code = self.bothify('#######') + str(self._random_vat_office()).zfill(3) - luhn_checksum = str(calculate_luhn(code)) + luhn_checksum = str(calculate_luhn(int(code))) return f'IT{code}{luhn_checksum}' diff --git a/faker/providers/company/ja_JP/__init__.py b/faker/providers/company/ja_JP/__init__.py index 3968950e50..db68f6ce95 100644 --- a/faker/providers/company/ja_JP/__init__.py +++ b/faker/providers/company/ja_JP/__init__.py @@ -10,8 +10,8 @@ class Provider(CompanyProvider): company_prefixes = ('株式会社', '有限会社', '合同会社') company_categories = ('水産', '農林', '鉱業', '建設', '食品', '印刷', '電気', 'ガス', '情報', '通信', '運輸', '銀行', '保険') - def company_prefix(self): + def company_prefix(self) -> str: return self.random_element(self.company_prefixes) - def company_category(self): + def company_category(self) -> str: return self.random_element(self.company_categories) diff --git a/faker/providers/company/ko_KR/__init__.py b/faker/providers/company/ko_KR/__init__.py index 38229ffaa5..69456c6a4a 100644 --- a/faker/providers/company/ko_KR/__init__.py +++ b/faker/providers/company/ko_KR/__init__.py @@ -356,23 +356,3 @@ class Provider(CompanyProvider): '방법론')) company_suffixes = ('(주)', '주식회사', '(유)', '유한회사') - - def catch_phrase(self): - """ - :example 'Robust full-range hub' - """ - result = [] - for word_list in self.catch_phrase_words: - result.append(self.random_element(word_list)) - - return " ".join(result) - - def bs(self): - """ - :example 'integrate extensible convergence' - """ - result = [] - for word_list in self.bsWords: - result.append(self.random_element(word_list)) - - return " ".join(result) diff --git a/faker/providers/company/nl_NL/__init__.py b/faker/providers/company/nl_NL/__init__.py index 4b70b274f3..a0fb4b91e5 100644 --- a/faker/providers/company/nl_NL/__init__.py +++ b/faker/providers/company/nl_NL/__init__.py @@ -93,13 +93,13 @@ class Provider(CompanyProvider): 'DKG Groep', 'Bruynzeel Keukens', 'Janssen de Jong Groep', 'ProRail', 'Solid Professionals', 'Hermes Partners', ) - def large_company(self): + def large_company(self) -> str: """ :example: 'Bol.com' """ return self.random_element(self.large_companies) - def company_prefix(self): + def company_prefix(self) -> str: """ :example 'Stichting' """ diff --git a/faker/providers/company/pl_PL/__init__.py b/faker/providers/company/pl_PL/__init__.py index 23e222357d..f0a2aaa41a 100644 --- a/faker/providers/company/pl_PL/__init__.py +++ b/faker/providers/company/pl_PL/__init__.py @@ -1,7 +1,9 @@ +from typing import List + from .. import Provider as CompanyProvider -def regon_checksum(digits): +def regon_checksum(digits: List[int]) -> int: """ Calculates and returns a control digit for given list of digits basing on REGON standard. """ @@ -19,7 +21,7 @@ def regon_checksum(digits): return check_digit -def local_regon_checksum(digits): +def local_regon_checksum(digits: List[int]) -> int: """ Calculates and returns a control digit for given list of digits basing on local REGON standard. """ @@ -37,7 +39,7 @@ def local_regon_checksum(digits): return check_digit -def company_vat_checksum(digits): +def company_vat_checksum(digits: List[int]) -> int: """ Calculates and returns a control digit for given list of digits basing on NIP standard. """ @@ -66,13 +68,13 @@ class Provider(CompanyProvider): company_suffixes = ('Sp. z o.o.', 'S.A.', 'Sp. z o.o. Sp.k.', 'Sp.j.', 's.c.', 'Sp.k.', 'i syn s.c.') - def company_prefix(self): + def company_prefix(self) -> str: """ :example 'Grupa' """ return self.random_element(self.company_prefixes) - def regon(self): + def regon(self) -> str: """ Returns 9 character Polish National Business Registry Number, Polish: Rejestr Gospodarki Narodowej - REGON. @@ -89,7 +91,7 @@ def regon(self): return ''.join(str(digit) for digit in regon_digits) - def local_regon(self): + def local_regon(self) -> str: """ Returns 14 character Polish National Business Registry Number, local entity number. @@ -105,7 +107,7 @@ def local_regon(self): return ''.join(str(digit) for digit in regon_digits) - def company_vat(self): + def company_vat(self) -> str: """ Returns 10 character tax identification number, Polish: Numer identyfikacji podatkowej. diff --git a/faker/providers/company/pt_BR/__init__.py b/faker/providers/company/pt_BR/__init__.py index 608381c850..755d026aaa 100644 --- a/faker/providers/company/pt_BR/__init__.py +++ b/faker/providers/company/pt_BR/__init__.py @@ -1,7 +1,9 @@ +from typing import List + from .. import Provider as CompanyProvider -def company_id_checksum(digits): +def company_id_checksum(digits: List[int]) -> List[int]: digits = list(digits) weights = 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 @@ -69,38 +71,39 @@ class Provider(CompanyProvider): company_suffixes = ('S/A', 'S.A.', 'Ltda.', '- ME', '- EI', 'e Filhos') - def catch_phrase_noun(self): + def catch_phrase_noun(self) -> str: """ Returns a random catch phrase noun. """ return self.random_element(self.nouns) - def catch_phrase_attribute(self): + def catch_phrase_attribute(self) -> str: """ Returns a random catch phrase attribute. """ return self.random_element(self.attributes) - def catch_phrase_verb(self): + def catch_phrase_verb(self) -> str: """ Returns a random catch phrase verb. """ return self.random_element(self.verbs) - def catch_phrase(self): + def catch_phrase(self) -> str: """ :example 'a segurança de evoluir sem preocupação' """ - pattern = self.random_element(self.catch_phrase_formats) + pattern: str = self.random_element(self.catch_phrase_formats) catch_phrase = self.generator.parse(pattern) catch_phrase = catch_phrase[0].upper() + catch_phrase[1:] return catch_phrase - def company_id(self): - digits = self.random_sample(range(10), 8) + [0, 0, 0, 1] + def company_id(self) -> str: + digits: List[int] = list(self.random_sample(range(10), 8)) + digits += [0, 0, 0, 1] digits += company_id_checksum(digits) return ''.join(str(d) for d in digits) - def cnpj(self): + def cnpj(self) -> str: digits = self.company_id() return f'{digits[:2]}.{digits[2:5]}.{digits[5:8]}/{digits[8:12]}-{digits[12:]}' diff --git a/faker/providers/company/ro_RO/__init__.py b/faker/providers/company/ro_RO/__init__.py index 9075913c57..89ce1d403d 100644 --- a/faker/providers/company/ro_RO/__init__.py +++ b/faker/providers/company/ro_RO/__init__.py @@ -14,5 +14,5 @@ class Provider(CompanyProvider): 'LOC', 'OC1', 'OC2', 'OC3', 'PFA', 'RA', 'SCS', 'SPI', 'URL', ) - def company_suffix(self): + def company_suffix(self) -> str: return self.random_element(self.company_suffixes) diff --git a/faker/providers/company/ru_RU/__init__.py b/faker/providers/company/ru_RU/__init__.py index 4cc65e3ffe..a9c489f5ed 100644 --- a/faker/providers/company/ru_RU/__init__.py +++ b/faker/providers/company/ru_RU/__init__.py @@ -3,7 +3,7 @@ from .. import Provider as CompanyProvider -def calculate_checksum(value): +def calculate_checksum(value: str) -> str: factors = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8][-len(value):] check_sum = 0 for number, factor in zip(value, factors): @@ -233,14 +233,14 @@ class Provider(CompanyProvider): 'отношений', 'парадигм', 'партнерств', 'платформ', 'пользователей', 'порталов', 'приложений', 'результатов', 'решений', 'рынков', 'сетей', 'систем', 'систем снабжения', 'сообществ', 'схем', 'технологий', 'функций')) - def catch_phrase(self): + def catch_phrase(self) -> str: """ :example: 'Адаптивный и масштабируемый графический интерфейс' """ - noun = self.random_element(self.catch_phrase_nouns_masc + self.catch_phrase_nouns_fem + - self.catch_phrase_nouns_neu) - adj_first = self.random_element(self.catch_phrase_adj[0]) - adj_second = self.random_element(self.catch_phrase_adj[1]) + noun: str = self.random_element(self.catch_phrase_nouns_masc + self.catch_phrase_nouns_fem + + self.catch_phrase_nouns_neu) + adj_first: str = self.random_element(self.catch_phrase_adj[0]) + adj_second: str = self.random_element(self.catch_phrase_adj[1]) if noun in self.catch_phrase_nouns_fem: adj_first = adj_first[:-2] + 'ая' adj_second = adj_second[:-2] + 'ая' @@ -249,75 +249,75 @@ def catch_phrase(self): adj_second = adj_second[:-2] + 'ое' return adj_first + ' и ' + adj_second + ' ' + noun - def large_company(self): + def large_company(self) -> str: """ :example: 'АвтоВАЗ' """ return self.random_element(self.large_companies) - def company_prefix(self): + def company_prefix(self) -> str: """ :example: 'ООО' """ return self.random_element(self.company_prefixes) - def businesses_inn(self): + def businesses_inn(self) -> str: """ Returns tax identification number for businesses (ru. идентификационный номер налогоплательщика, ИНН). """ - region = '%02d' % self.random_int(min=1, max=92) - inspection = '%02d' % self.random_int(min=1, max=99) - tail = '%05d' % self.random_int(min=1, max=99999) - result = region + inspection + tail + region: str = '%02d' % self.random_int(min=1, max=92) + inspection: str = '%02d' % self.random_int(min=1, max=99) + tail: str = '%05d' % self.random_int(min=1, max=99999) + result: str = region + inspection + tail return result + calculate_checksum(result) - def individuals_inn(self): + def individuals_inn(self) -> str: """ Returns tax identification number for individuals (ru. идентификационный номер налогоплательщика, ИНН). """ - region = '%02d' % self.random_int(min=1, max=92) - inspection = '%02d' % self.random_int(min=1, max=99) - tail = '%06d' % self.random_int(min=1, max=999999) - result = region + inspection + tail + region: str = '%02d' % self.random_int(min=1, max=92) + inspection: str = '%02d' % self.random_int(min=1, max=99) + tail: str = '%06d' % self.random_int(min=1, max=999999) + result: str = region + inspection + tail result += calculate_checksum(result) return result + calculate_checksum(result) - def businesses_ogrn(self): + def businesses_ogrn(self) -> str: """ Returns primary state registration number for businesses (ru. основной государственный регистрационный номер, ОГРН). """ - sign = self.random_element(('1', '5')) - year = '%02d' % self.random_int(min=1, max=datetime.now().year - 2000) - region = '%02d' % self.random_int(min=1, max=92) - tail = '%07d' % self.random_int(min=1, max=9999999) + sign: str = self.random_element(('1', '5')) + year: str = '%02d' % self.random_int(min=1, max=datetime.now().year - 2000) + region: str = '%02d' % self.random_int(min=1, max=92) + tail: str = '%07d' % self.random_int(min=1, max=9999999) - result = sign + year + region + tail + result: str = sign + year + region + tail return result + str((int(result) % 11) % 10) - def individuals_ogrn(self): + def individuals_ogrn(self) -> str: """ Returns primary state registration number for individuals (ru. основной государственный регистрационный номер, ОГРН). """ - year = '%02d' % self.random_int(min=1, max=datetime.now().year - 2000) - region = '%02d' % self.random_int(min=1, max=92) - tail = '%09d' % self.random_int(min=1, max=999999999) + year: str = '%02d' % self.random_int(min=1, max=datetime.now().year - 2000) + region: str = '%02d' % self.random_int(min=1, max=92) + tail: str = '%09d' % self.random_int(min=1, max=999999999) - result = '3' + year + region + tail + result: str = '3' + year + region + tail return result + str((int(result) % 13) % 10) - def kpp(self): + def kpp(self) -> str: """ Returns tax registration reason code (ru. код причины постановки на учет, КПП). """ - region = '%02d' % self.random_int(min=1, max=92) - inspection = '%02d' % self.random_int(min=1, max=99) - reason = self.random_element(('01', '43', '44', '45')) - tail = '%03d' % self.random_int(min=1, max=999) + region: str = '%02d' % self.random_int(min=1, max=92) + inspection: str = '%02d' % self.random_int(min=1, max=99) + reason: str = self.random_element(('01', '43', '44', '45')) + tail: str = '%03d' % self.random_int(min=1, max=999) return region + inspection + reason + tail diff --git a/faker/providers/company/th_TH/__init__.py b/faker/providers/company/th_TH/__init__.py index 9065385a53..1c26501dc7 100644 --- a/faker/providers/company/th_TH/__init__.py +++ b/faker/providers/company/th_TH/__init__.py @@ -88,25 +88,25 @@ class Provider(CompanyProvider): ("จำกัด (มหาชน)", 0.15), )) - def company_prefix(self): + def company_prefix(self) -> str: """ :example 'ห้างหุ้นส่วนจำกัด' """ return self.random_element(self.company_prefixes) - def company_limited_prefix(self): + def company_limited_prefix(self) -> str: """ :example 'บริษัท' """ return self.random_element(self.company_limited_prefixes) - def company_limited_suffix(self): + def company_limited_suffix(self) -> str: """ :example 'จำกัด' """ return self.random_element(self.company_limited_suffixes) - def nonprofit_prefix(self): + def nonprofit_prefix(self) -> str: """ :example 'มูลนิธิ' """ diff --git a/faker/providers/company/tr_TR/__init__.py b/faker/providers/company/tr_TR/__init__.py index e6866f45ad..7ace5aeff4 100644 --- a/faker/providers/company/tr_TR/__init__.py +++ b/faker/providers/company/tr_TR/__init__.py @@ -18,7 +18,7 @@ class Provider(CompanyProvider): 'A.Ş.', 'Ltd.', 'Şti.', ) - def large_company(self): + def large_company(self) -> str: """ :example: 'Peak Games' """ diff --git a/faker/providers/company/zh_CN/__init__.py b/faker/providers/company/zh_CN/__init__.py index 9eb404765e..fd60c36553 100644 --- a/faker/providers/company/zh_CN/__init__.py +++ b/faker/providers/company/zh_CN/__init__.py @@ -20,5 +20,5 @@ class Provider(CompanyProvider): "东方峻景", "华成育卓", "趋势", "维涛", "通际名联"] company_suffixes = [n + "有限公司" for n in ["科技", "网络", "信息", "传媒"]] - def company_prefix(self): + def company_prefix(self) -> str: return self.random_element(self.company_prefixes) diff --git a/faker/providers/company/zh_TW/__init__.py b/faker/providers/company/zh_TW/__init__.py index 15a09ff5d2..701c7c7694 100644 --- a/faker/providers/company/zh_TW/__init__.py +++ b/faker/providers/company/zh_TW/__init__.py @@ -33,5 +33,5 @@ class Provider(CompanyProvider): company_suffixes = ("", "有限公司", "股份有限公司", "資訊有限公司") - def company_prefix(self): + def company_prefix(self) -> str: return self.random_element(self.company_prefixes) diff --git a/faker/providers/credit_card/__init__.py b/faker/providers/credit_card/__init__.py index 025b01fa97..9939a639fe 100644 --- a/faker/providers/credit_card/__init__.py +++ b/faker/providers/credit_card/__init__.py @@ -1,19 +1,23 @@ from collections import OrderedDict +from typing import Dict, List, Optional, TypeVar +from ...typing import DateParseType from .. import BaseProvider localized = True +CardType = TypeVar('CardType', 'CreditCard', str) + class CreditCard: def __init__( self, - name, - prefixes, - length=16, - security_code='CVC', - security_code_length=3): + name: str, + prefixes: List[str], + length: int = 16, + security_code: str = 'CVC', + security_code_length: int = 3) -> None: self.name = name self.prefixes = prefixes self.length = length @@ -37,28 +41,25 @@ class Provider(BaseProvider): - https://creditcardjs.com/credit-card-type-detection """ - prefix_maestro = ['5018', '5020', '5038', '56##', '57##', '58##', - '6304', '6759', '6761', '6762', '6763', '0604', '6390'] - prefix_mastercard = ['51', '52', '53', '54', '55', '222%', '223', '224', - '225', '226', '227', '228', '229', '23', '24', '25', - '26', '270', '271', '2720'] - prefix_visa = ['4'] - prefix_amex = ['34', '37'] - prefix_discover = ['6011', '65'] - prefix_diners = ['300', '301', '302', '303', '304', '305', '36', '38'] - prefix_jcb16 = ['35'] - prefix_jcb15 = ['2131', '1800'] - - credit_card_types = OrderedDict(( - ('maestro', CreditCard('Maestro', - prefix_maestro, 12, security_code='CVV')), - ('mastercard', CreditCard('Mastercard', - prefix_mastercard, 16, security_code='CVV')), + prefix_maestro: List[str] = ['5018', '5020', '5038', '56##', '57##', '58##', + '6304', '6759', '6761', '6762', '6763', '0604', '6390'] + prefix_mastercard: List[str] = ['51', '52', '53', '54', '55', '222%', '223', '224', + '225', '226', '227', '228', '229', '23', '24', '25', + '26', '270', '271', '2720'] + prefix_visa: List[str] = ['4'] + prefix_amex: List[str] = ['34', '37'] + prefix_discover: List[str] = ['6011', '65'] + prefix_diners: List[str] = ['300', '301', '302', '303', '304', '305', '36', '38'] + prefix_jcb16: List[str] = ['35'] + prefix_jcb15: List[str] = ['2131', '1800'] + + credit_card_types: Dict[str, CreditCard] = OrderedDict(( + ('maestro', CreditCard('Maestro', prefix_maestro, 12, security_code='CVV')), + ('mastercard', CreditCard('Mastercard', prefix_mastercard, 16, security_code='CVV')), ('visa16', CreditCard('VISA 16 digit', prefix_visa)), ('visa13', CreditCard('VISA 13 digit', prefix_visa, 13)), ('visa19', CreditCard('VISA 19 digit', prefix_visa, 19)), - ('amex', CreditCard('American Express', prefix_amex, - 15, security_code='CID', security_code_length=4)), + ('amex', CreditCard('American Express', prefix_amex, 15, security_code='CID', security_code_length=4)), ('discover', CreditCard('Discover', prefix_discover)), ('diners', CreditCard('Diners Club / Carte Blanche', prefix_diners, 14)), ('jcb15', CreditCard('JCB 15 digit', prefix_jcb15, 15)), @@ -70,20 +71,23 @@ class Provider(BaseProvider): luhn_lookup = {'0': 0, '1': 2, '2': 4, '3': 6, '4': 8, '5': 1, '6': 3, '7': 5, '8': 7, '9': 9} - def credit_card_provider(self, card_type=None): + def credit_card_provider(self, card_type: Optional[CardType] = None) -> str: """Generate a credit card provider name.""" if card_type is None: card_type = self.random_element(self.credit_card_types.keys()) return self._credit_card_type(card_type).name - def credit_card_number(self, card_type=None): + def credit_card_number(self, card_type: Optional[CardType] = None) -> str: """Generate a valid credit card number.""" card = self._credit_card_type(card_type) - prefix = self.random_element(card.prefixes) + prefix: str = self.random_element(card.prefixes) number = self._generate_number(self.numerify(prefix), card.length) return number - def credit_card_expire(self, start='now', end='+10y', date_format='%m/%y'): + def credit_card_expire(self, + start: DateParseType = 'now', + end: DateParseType = '+10y', + date_format: str = '%m/%y') -> str: """Generate a credit card expiry date. This method uses |date_time_between| under the hood to generate the @@ -95,7 +99,7 @@ def credit_card_expire(self, start='now', end='+10y', date_format='%m/%y'): expire_date = self.generator.date_time_between(start, end) return expire_date.strftime(date_format) - def credit_card_full(self, card_type=None): + def credit_card_full(self, card_type: Optional[CardType] = None) -> str: """Generate a set of credit card details.""" card = self._credit_card_type(card_type) @@ -114,12 +118,12 @@ def credit_card_full(self, card_type=None): return self.generator.parse(tpl) - def credit_card_security_code(self, card_type=None): + def credit_card_security_code(self, card_type: Optional[CardType] = None) -> str: """Generate a credit card security code.""" sec_len = self._credit_card_type(card_type).security_code_length return self.numerify('#' * sec_len) - def _credit_card_type(self, card_type=None): + def _credit_card_type(self, card_type: Optional[CardType] = None) -> CreditCard: """Generate a random CreditCard instance of the specified card type.""" if card_type is None: card_type = self.random_element(self.credit_card_types.keys()) @@ -127,7 +131,7 @@ def _credit_card_type(self, card_type=None): return card_type return self.credit_card_types[card_type] - def _generate_number(self, prefix, length): + def _generate_number(self, prefix: str, length: int) -> str: """Generate a credit card number. The ``prefix`` argument is the start of the CC number as a string which diff --git a/faker/providers/credit_card/fa_IR/__init__.py b/faker/providers/credit_card/fa_IR/__init__.py index b393798afc..dd8037642c 100644 --- a/faker/providers/credit_card/fa_IR/__init__.py +++ b/faker/providers/credit_card/fa_IR/__init__.py @@ -83,15 +83,3 @@ class Provider(CreditCardProvider): ('parsian', CreditCard('پارسیان', prefix_parsian, 16, security_code='CVV2')), ('bim', CreditCard('صنعت و معدن', prefix_bim, 16, security_code='CVV2')), )) - - def credit_card_expire(self, start='now', end='+3y', date_format='%y/%m'): - """Generate a credit card expiry date. - - This method uses |date_time_between| under the hood to generate the - expiry date, so the ``start`` and ``end`` arguments work in the same way - here as it would in that method. For the actual formatting of the expiry - date, |strftime| is used and ``date_format`` is simply passed - to that method. - """ - expire_date = self.generator.date_time_between(start, end) - return expire_date.strftime(date_format) diff --git a/faker/providers/credit_card/pt_PT/__init__.py b/faker/providers/credit_card/pt_PT/__init__.py index 57f2e74f38..c7d0519e1d 100644 --- a/faker/providers/credit_card/pt_PT/__init__.py +++ b/faker/providers/credit_card/pt_PT/__init__.py @@ -53,16 +53,3 @@ class Provider(CreditCardProvider): ('mastercard', CreditCard('Mastercard', prefix_mastercard, 16, security_code='CVV2')), ('visa', CreditCard('Visa', prefix_visa, 16, security_code='CVV2')), )) - - def credit_card_expire(self, start='now', end='+4y', date_format='%m/%y'): - """Generate a credit card expiry date. - - This method uses |date_time_between| under the hood to generate the - expiry date, so the ``start`` and ``end`` arguments work in the same way - here as it would in that method. For the actual formatting of the expiry - date, |strftime| is used and ``date_format`` is simply passed - to that method. - """ - - expire_date = self.generator.date_time_between(start, end) - return expire_date.strftime(date_format) diff --git a/faker/providers/credit_card/ru_RU/__init__.py b/faker/providers/credit_card/ru_RU/__init__.py index 8826f9ec29..7f099bb5bb 100644 --- a/faker/providers/credit_card/ru_RU/__init__.py +++ b/faker/providers/credit_card/ru_RU/__init__.py @@ -1,8 +1,9 @@ from collections import OrderedDict +from typing import Optional from faker.providers.person.ru_RU import translit -from .. import CreditCard +from .. import CardType, CreditCard from .. import Provider as CreditCardProvider @@ -36,19 +37,7 @@ class Provider(CreditCardProvider): ('unionpay', CreditCard('Union Pay', prefix_unionpay)), )) - def credit_card_expire(self, start='now', end='+4y', date_format='%m/%y'): - """Generate a credit card expiry date. - - This method uses |date_time_between| under the hood to generate the - expiry date, so the ``start`` and ``end`` arguments work in the same way - here as it would in that method. For the actual formatting of the expiry - date, |strftime| is used and ``date_format`` is simply passed - to that method. - """ - expire_date = self.generator.date_time_between(start, end) - return expire_date.strftime(date_format) - - def credit_card_full(self, card_type=None): + def credit_card_full(self, card_type: Optional[CardType] = None) -> str: """Generate a set of credit card details.""" card = self._credit_card_type(card_type) diff --git a/faker/providers/currency/__init__.py b/faker/providers/currency/__init__.py index bce353ffa9..2907b20538 100644 --- a/faker/providers/currency/__init__.py +++ b/faker/providers/currency/__init__.py @@ -1,11 +1,13 @@ -from .. import BaseProvider +from typing import Dict, Optional, Tuple + +from .. import BaseProvider, ElementsType localized = True class Provider(BaseProvider): # Format: (code, name) - currencies = ( + currencies: ElementsType[Tuple[str, str]] = ( ("AED", "United Arab Emirates dirham"), ("AFN", "Afghan afghani"), ("ALL", "Albanian lek"), @@ -173,7 +175,7 @@ class Provider(BaseProvider): ) # Source: https://en.wikipedia.org/wiki/List_of_cryptocurrencies - cryptocurrencies = ( + cryptocurrencies: ElementsType[Tuple[str, str]] = ( ('AMP', "AMP"), ('AUR', "Auroracoin"), ('BC', "BlackCoin"), @@ -220,7 +222,7 @@ class Provider(BaseProvider): ) # List of currency symbols in Unicode, source: https://www.unicode.org/charts/beta/nameslist/n_20A0.html - currency_symbols = { + currency_symbols: Dict[str, str] = { 'AFN': '\u060B', 'ANG': '\u0192', 'ARS': '\u0024', 'AUD': '\u0024', 'AWG': '\u0192', 'BBD': '\u0024', 'BDT': '\u09F3', 'BMD': '\u0024', 'BND': '\u0024', 'BOB': '\u0024', 'BRL': '\u0024', 'BSD': '\u0024', 'BZD': '\u0024', 'CAD': '\u0024', 'CLP': '\u0024', 'CNY': '\u00A5', 'COP': '\u0024', 'CRC': '\u20A1', @@ -237,18 +239,18 @@ class Provider(BaseProvider): 'XCD': '\u0024', 'YER': '\uFDFC', 'ZWD': '\u0024', } - price_formats = ["#.##", "%#.##", "%##.##", "%,###.##", "%#,###.##"] + price_formats: ElementsType = ["#.##", "%#.##", "%##.##", "%,###.##", "%#,###.##"] - def currency(self): + def currency(self) -> Tuple[str, str]: return self.random_element(self.currencies) - def currency_code(self): + def currency_code(self) -> str: return self.currency()[0] - def currency_name(self): + def currency_name(self) -> str: return self.currency()[1] - def currency_symbol(self, code=None): + def currency_symbol(self, code: Optional[str] = None) -> str: """ :example: $ """ @@ -256,18 +258,19 @@ def currency_symbol(self, code=None): code = self.random_element(self.currency_symbols.keys()) return self.currency_symbols[code] - def cryptocurrency(self): + def cryptocurrency(self) -> Tuple[str, str]: return self.random_element(self.cryptocurrencies) - def cryptocurrency_code(self): + def cryptocurrency_code(self) -> str: return self.cryptocurrency()[0] - def cryptocurrency_name(self): + def cryptocurrency_name(self) -> str: return self.cryptocurrency()[1] - def pricetag(self): + def pricetag(self) -> str: + currency: Tuple[str, str] = self.random_element(self.currencies) return ( - self.random_element(self.currencies)[0] + currency[0] + "\N{no-break space}" + self.numerify(self.random_element(self.price_formats)) ) diff --git a/faker/providers/currency/cs_CZ/__init__.py b/faker/providers/currency/cs_CZ/__init__.py index 50646d1b58..b38f311fa3 100644 --- a/faker/providers/currency/cs_CZ/__init__.py +++ b/faker/providers/currency/cs_CZ/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#,#0", "%#,#0", "%##,#0", "%.###,#0", "%#.###,#0"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}Kč" diff --git a/faker/providers/currency/de_AT/__init__.py b/faker/providers/currency/de_AT/__init__.py index 556de53562..a510e63629 100644 --- a/faker/providers/currency/de_AT/__init__.py +++ b/faker/providers/currency/de_AT/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}\N{euro sign}" diff --git a/faker/providers/currency/en_AU/__init__.py b/faker/providers/currency/en_AU/__init__.py index 767844a259..2954781459 100644 --- a/faker/providers/currency/en_AU/__init__.py +++ b/faker/providers/currency/en_AU/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#.##", "%#.##", "%##.##", "%,###.##", "%#,###.##"] - def pricetag(self): + def pricetag(self) -> str: return ( "$\N{no-break space}" + self.numerify(self.random_element(self.price_formats)) diff --git a/faker/providers/currency/en_US/__init__.py b/faker/providers/currency/en_US/__init__.py index 4a7dd84088..853871d34f 100644 --- a/faker/providers/currency/en_US/__init__.py +++ b/faker/providers/currency/en_US/__init__.py @@ -5,5 +5,5 @@ class Provider(CurrencyProvider): price_formats = ["#.##", "%#.##", "%##.##", "%,###.##", "%#,###.##"] - def pricetag(self): + def pricetag(self) -> str: return ("$" + self.numerify(self.random_element(self.price_formats))) diff --git a/faker/providers/currency/es_ES/__init__.py b/faker/providers/currency/es_ES/__init__.py index e2864b9c14..c1aa47f678 100644 --- a/faker/providers/currency/es_ES/__init__.py +++ b/faker/providers/currency/es_ES/__init__.py @@ -172,7 +172,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}\N{euro sign}" diff --git a/faker/providers/currency/fr_CA/__init__.py b/faker/providers/currency/fr_CA/__init__.py index 702102d675..8dcb804325 100644 --- a/faker/providers/currency/fr_CA/__init__.py +++ b/faker/providers/currency/fr_CA/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}$" diff --git a/faker/providers/currency/nl_NL/__init__.py b/faker/providers/currency/nl_NL/__init__.py index 63094d133d..009d277cc2 100644 --- a/faker/providers/currency/nl_NL/__init__.py +++ b/faker/providers/currency/nl_NL/__init__.py @@ -5,5 +5,5 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return "\N{euro sign}" + self.numerify(self.random_element(self.price_formats)) diff --git a/faker/providers/currency/pl_PL/__init__.py b/faker/providers/currency/pl_PL/__init__.py index 6d2f0c6640..d24c4569e2 100644 --- a/faker/providers/currency/pl_PL/__init__.py +++ b/faker/providers/currency/pl_PL/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}zł" diff --git a/faker/providers/currency/pt_BR/__init__.py b/faker/providers/currency/pt_BR/__init__.py index 17ee8e3f6d..d0754ec2f0 100644 --- a/faker/providers/currency/pt_BR/__init__.py +++ b/faker/providers/currency/pt_BR/__init__.py @@ -5,5 +5,5 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ("R$" + self.numerify(self.random_element(self.price_formats))) diff --git a/faker/providers/currency/ro_RO/__init__.py b/faker/providers/currency/ro_RO/__init__.py index c0e268c896..6e95ab547c 100644 --- a/faker/providers/currency/ro_RO/__init__.py +++ b/faker/providers/currency/ro_RO/__init__.py @@ -5,7 +5,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}Lei" diff --git a/faker/providers/currency/ru_RU/__init__.py b/faker/providers/currency/ru_RU/__init__.py index 840b1d69ec..cb0997b0ee 100644 --- a/faker/providers/currency/ru_RU/__init__.py +++ b/faker/providers/currency/ru_RU/__init__.py @@ -173,7 +173,7 @@ class Provider(CurrencyProvider): price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"] - def pricetag(self): + def pricetag(self) -> str: return ( self.numerify(self.random_element(self.price_formats)) + "\N{no-break space}\N{cyrillic small letter er}." diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py index ba4b3bb6eb..8ce7c89056 100644 --- a/faker/providers/date_time/__init__.py +++ b/faker/providers/date_time/__init__.py @@ -3,33 +3,35 @@ from calendar import timegm from datetime import MAXYEAR from datetime import date as dtdate -from datetime import datetime, timedelta +from datetime import datetime +from datetime import time as dttime +from datetime import timedelta +from datetime import tzinfo as TzInfo +from typing import Any, Callable, Dict, Iterator, Optional, Tuple, Union from dateutil import relativedelta from dateutil.tz import gettz, tzlocal, tzutc -from .. import BaseProvider +from ...typing import DateParseType +from .. import BaseProvider, ElementsType localized = True -def datetime_to_timestamp(dt): - if getattr(dt, 'tzinfo', None) is not None: +def datetime_to_timestamp(dt: Union[dtdate, datetime]) -> int: + if isinstance(dt, datetime) and getattr(dt, 'tzinfo', None) is not None: dt = dt.astimezone(tzutc()) return timegm(dt.timetuple()) -def timestamp_to_datetime(timestamp, tzinfo): +def timestamp_to_datetime(timestamp: Union[int, float], tzinfo: Optional[TzInfo]) -> datetime: if tzinfo is None: pick = convert_timestamp_to_datetime(timestamp, tzlocal()) - pick = pick.astimezone(tzutc()).replace(tzinfo=None) - else: - pick = convert_timestamp_to_datetime(timestamp, tzinfo) - - return pick + return pick.astimezone(tzutc()).replace(tzinfo=None) + return convert_timestamp_to_datetime(timestamp, tzinfo) -def change_year(current_date, year_diff): +def change_year(current_date: dtdate, year_diff: int) -> dtdate: """ Unless the current_date is February 29th, it is fine to just subtract years. If it is a leap day, and we are rolling back to a non-leap year, it will @@ -56,14 +58,14 @@ class ParseError(ValueError): pass -timedelta_pattern = r'' +timedelta_pattern: str = r'' for name, sym in [('years', 'y'), ('months', 'M'), ('weeks', 'w'), ('days', 'd'), ('hours', 'h'), ('minutes', 'm'), ('seconds', 's')]: timedelta_pattern += r'((?P<{}>(?:\+|-)\d+?){})?'.format(name, sym) class Provider(BaseProvider): - centuries = [ + centuries: ElementsType = [ 'I', 'II', 'III', @@ -1394,7 +1396,9 @@ class Provider(BaseProvider): regex = re.compile(timedelta_pattern) - def unix_time(self, end_datetime=None, start_datetime=None): + def unix_time(self, + end_datetime: Optional[DateParseType] = None, + start_datetime: Optional[DateParseType] = None) -> int: """ Get a timestamp between January 1, 1970 and now, unless passed explicit start_datetime or end_datetime values. @@ -1404,7 +1408,7 @@ def unix_time(self, end_datetime=None, start_datetime=None): end_datetime = self._parse_end_datetime(end_datetime) return self.generator.random.randint(start_datetime, end_datetime) - def time_delta(self, end_datetime=None): + def time_delta(self, end_datetime: Optional[DateParseType] = None) -> timedelta: """ Get a timedelta object """ @@ -1415,11 +1419,11 @@ def time_delta(self, end_datetime=None): ts = self.generator.random.randint(*sorted([0, seconds])) return timedelta(seconds=ts) - def date_time(self, tzinfo=None, end_datetime=None): + def date_time(self, tzinfo: Optional[TzInfo] = None, end_datetime: Optional[DateParseType] = None) -> datetime: """ Get a datetime object for a date between January 1, 1970 and now :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2005-08-16 20:39:21') + :example datetime('2005-08-16 20:39:21') :return datetime """ # NOTE: On windows, the lowest value you can get from windows is 86400 @@ -1428,11 +1432,14 @@ def date_time(self, tzinfo=None, end_datetime=None): return datetime(1970, 1, 1, tzinfo=tzinfo) + \ timedelta(seconds=self.unix_time(end_datetime=end_datetime)) - def date_time_ad(self, tzinfo=None, end_datetime=None, start_datetime=None): + def date_time_ad(self, + tzinfo: Optional[TzInfo] = None, + end_datetime: Optional[DateParseType] = None, + start_datetime: Optional[DateParseType] = None) -> datetime: """ Get a datetime object for a date between January 1, 001 and now :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1265-03-22 21:15:52') + :example datetime('1265-03-22 21:15:52') :return datetime """ @@ -1455,14 +1462,14 @@ def date_time_ad(self, tzinfo=None, end_datetime=None, start_datetime=None): # https://bugs.python.org/issue30684 return datetime(1970, 1, 1, tzinfo=tzinfo) + timedelta(seconds=ts) - def iso8601(self, tzinfo=None, end_datetime=None): + def iso8601(self, tzinfo: Optional[TzInfo] = None, end_datetime: Optional[DateParseType] = None) -> str: """ :param tzinfo: timezone, instance of datetime.tzinfo subclass :example '2003-10-21T16:05:52+0000' """ return self.date_time(tzinfo, end_datetime=end_datetime).isoformat() - def date(self, pattern='%Y-%m-%d', end_datetime=None): + def date(self, pattern: str = '%Y-%m-%d', end_datetime: Optional[DateParseType] = None) -> str: """ Get a date string between January 1, 1970 and now :param pattern format @@ -1470,14 +1477,14 @@ def date(self, pattern='%Y-%m-%d', end_datetime=None): """ return self.date_time(end_datetime=end_datetime).strftime(pattern) - def date_object(self, end_datetime=None): + def date_object(self, end_datetime: datetime = None) -> dtdate: """ Get a date object between January 1, 1970 and now :example datetime.date(2016, 9, 20) """ return self.date_time(end_datetime=end_datetime).date() - def time(self, pattern='%H:%M:%S', end_datetime=None): + def time(self, pattern: str = '%H:%M:%S', end_datetime: Optional[DateParseType] = None) -> str: """ Get a time string (24h format by default) :param pattern format @@ -1486,7 +1493,7 @@ def time(self, pattern='%H:%M:%S', end_datetime=None): return self.date_time( end_datetime=end_datetime).time().strftime(pattern) - def time_object(self, end_datetime=None): + def time_object(self, end_datetime: Optional[DateParseType] = None) -> dttime: """ Get a time object :example datetime.time(15, 56, 56, 772876) @@ -1494,26 +1501,26 @@ def time_object(self, end_datetime=None): return self.date_time(end_datetime=end_datetime).time() @classmethod - def _parse_start_datetime(cls, value): + def _parse_start_datetime(cls, value: Optional[DateParseType]) -> int: if value is None: return 0 return cls._parse_date_time(value) @classmethod - def _parse_end_datetime(cls, value): + def _parse_end_datetime(cls, value: Optional[DateParseType]) -> int: if value is None: return datetime_to_timestamp(datetime.now()) return cls._parse_date_time(value) @classmethod - def _parse_date_string(cls, value): + def _parse_date_string(cls, value: str) -> Dict[str, float]: parts = cls.regex.match(value) if not parts: raise ParseError(f"Can't parse date string `{value}`") parts = parts.groupdict() - time_params = {} + time_params: Dict[str, float] = {} for (name_, param_) in parts.items(): if param_: time_params[name_] = int(param_) @@ -1532,18 +1539,18 @@ def _parse_date_string(cls, value): return time_params @classmethod - def _parse_timedelta(cls, value): + def _parse_timedelta(cls, value: Union[timedelta, str, float]) -> Union[float, int]: if isinstance(value, timedelta): return value.total_seconds() if isinstance(value, str): time_params = cls._parse_date_string(value) - return timedelta(**time_params).total_seconds() + return timedelta(**time_params).total_seconds() # type: ignore if isinstance(value, (int, float)): return value raise ParseError(f"Invalid format for timedelta {value!r}") @classmethod - def _parse_date_time(cls, value, tzinfo=None): + def _parse_date_time(cls, value: DateParseType, tzinfo: Optional[TzInfo] = None) -> int: if isinstance(value, (datetime, dtdate)): return datetime_to_timestamp(value) now = datetime.now(tzinfo) @@ -1553,13 +1560,13 @@ def _parse_date_time(cls, value, tzinfo=None): if value == 'now': return datetime_to_timestamp(datetime.now(tzinfo)) time_params = cls._parse_date_string(value) - return datetime_to_timestamp(now + timedelta(**time_params)) + return datetime_to_timestamp(now + timedelta(**time_params)) # type: ignore if isinstance(value, int): return datetime_to_timestamp(now + timedelta(value)) raise ParseError(f"Invalid format for date {value!r}") @classmethod - def _parse_date(cls, value): + def _parse_date(cls, value: DateParseType) -> dtdate: if isinstance(value, datetime): return value.date() elif isinstance(value, dtdate): @@ -1571,21 +1578,24 @@ def _parse_date(cls, value): if value in ('today', 'now'): return today time_params = cls._parse_date_string(value) - return today + timedelta(**time_params) + return today + timedelta(**time_params) # type: ignore if isinstance(value, int): return today + timedelta(value) raise ParseError(f"Invalid format for date {value!r}") - def date_time_between(self, start_date='-30y', end_date='now', tzinfo=None): + def date_time_between(self, + start_date: DateParseType = '-30y', + end_date: DateParseType = 'now', + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Get a DateTime object based on a random date between two given dates. + Get a datetime object based on a random date between two given dates. Accepts date strings that can be recognized by strtotime(). :param start_date Defaults to 30 years ago :param end_date Defaults to "now" :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example datetime('1999-02-02 11:42:52') + :return datetime """ start_date = self._parse_date_time(start_date, tzinfo=tzinfo) end_date = self._parse_date_time(end_date, tzinfo=tzinfo) @@ -1600,7 +1610,7 @@ def date_time_between(self, start_date='-30y', end_date='now', tzinfo=None): datetime(1970, 1, 1, tzinfo=tzutc()) + timedelta(seconds=ts) ).astimezone(tzinfo) - def date_between(self, start_date='-30y', end_date='today'): + def date_between(self, start_date: DateParseType = '-30y', end_date: DateParseType = 'today') -> dtdate: """ Get a Date object based on a random date between two given dates. Accepts date strings that can be recognized by strtotime(). @@ -1615,22 +1625,20 @@ def date_between(self, start_date='-30y', end_date='today'): end_date = self._parse_date(end_date) return self.date_between_dates(date_start=start_date, date_end=end_date) - def future_datetime(self, end_date='+30d', tzinfo=None): + def future_datetime(self, end_date: DateParseType = '+30d', tzinfo: Optional[TzInfo] = None) -> datetime: """ - Get a DateTime object based on a random date between 1 second form now + Get a datetime object based on a random date between 1 second form now and a given date. Accepts date strings that can be recognized by strtotime(). :param end_date Defaults to "+30d" :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example datetime('1999-02-02 11:42:52') + :return datetime """ - return self.date_time_between( - start_date='+1s', end_date=end_date, tzinfo=tzinfo, - ) + return self.date_time_between(start_date='+1s', end_date=end_date, tzinfo=tzinfo) - def future_date(self, end_date='+30d', tzinfo=None): + def future_date(self, end_date: DateParseType = '+30d', tzinfo: Optional[TzInfo] = None) -> dtdate: """ Get a Date object based on a random date between 1 day from now and a given date. @@ -1638,27 +1646,25 @@ def future_date(self, end_date='+30d', tzinfo=None): :param end_date Defaults to "+30d" :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example dtdate('2030-01-01') + :return dtdate """ return self.date_between(start_date='+1d', end_date=end_date) - def past_datetime(self, start_date='-30d', tzinfo=None): + def past_datetime(self, start_date: DateParseType = '-30d', tzinfo: Optional[TzInfo] = None) -> datetime: """ - Get a DateTime object based on a random date between a given date and 1 + Get a datetime object based on a random date between a given date and 1 second ago. Accepts date strings that can be recognized by strtotime(). :param start_date Defaults to "-30d" :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example datetime('1999-02-02 11:42:52') + :return datetime """ - return self.date_time_between( - start_date=start_date, end_date='-1s', tzinfo=tzinfo, - ) + return self.date_time_between(start_date=start_date, end_date='-1s', tzinfo=tzinfo) - def past_date(self, start_date='-30d', tzinfo=None): + def past_date(self, start_date: DateParseType = '-30d', tzinfo: Optional[TzInfo] = None) -> dtdate: """ Get a Date object based on a random date between a given date and 1 day ago. @@ -1666,37 +1672,33 @@ def past_date(self, start_date='-30d', tzinfo=None): :param start_date Defaults to "-30d" :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example dtdate('1999-02-02') + :return dtdate """ return self.date_between(start_date=start_date, end_date='-1d') def date_time_between_dates( self, - datetime_start=None, - datetime_end=None, - tzinfo=None): + datetime_start: Optional[DateParseType] = None, + datetime_end: Optional[DateParseType] = None, + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Takes two DateTime objects and returns a random datetime between the two + Takes two datetime objects and returns a random datetime between the two given datetimes. - Accepts DateTime objects. + Accepts datetime objects. - :param datetime_start: DateTime - :param datetime_end: DateTime + :param datetime_start: datetime + :param datetime_end: datetime :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('1999-02-02 11:42:52') - :return DateTime + :example datetime('1999-02-02 11:42:52') + :return datetime """ - if datetime_start is None: - datetime_start = datetime.now(tzinfo) - - if datetime_end is None: - datetime_end = datetime.now(tzinfo) + datetime_start_ = datetime_to_timestamp(datetime.now(tzinfo)) if datetime_start is None \ + else self._parse_date_time(datetime_start) + datetime_end_ = datetime_to_timestamp(datetime.now(tzinfo)) if datetime_end is None \ + else self._parse_date_time(datetime_end) - timestamp = self.generator.random.randint( - datetime_to_timestamp(datetime_start), - datetime_to_timestamp(datetime_end), - ) + timestamp = self.generator.random.randint(datetime_start_, datetime_end_) try: if tzinfo is None: pick = convert_timestamp_to_datetime(timestamp, tzlocal()) @@ -1713,10 +1715,12 @@ def date_time_between_dates( ) return pick - def date_between_dates(self, date_start=None, date_end=None): + def date_between_dates(self, + date_start: Optional[DateParseType] = None, + date_end: Optional[DateParseType] = None) -> dtdate: """ Takes two Date objects and returns a random date between the two given dates. - Accepts Date or Datetime objects + Accepts Date or datetime objects :param date_start: Date :param date_end: Date @@ -1724,19 +1728,18 @@ def date_between_dates(self, date_start=None, date_end=None): """ return self.date_time_between_dates(date_start, date_end).date() - def date_time_this_century( - self, - before_now=True, - after_now=False, - tzinfo=None): + def date_time_this_century(self, + before_now: bool = True, + after_now: bool = False, + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Gets a DateTime object for the current century. + Gets a datetime object for the current century. :param before_now: include days in current century before today :param after_now: include days in current century after today :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2012-04-04 11:02:02') - :return DateTime + :example datetime('2012-04-04 11:02:02') + :return datetime """ now = datetime.now(tzinfo) this_century_start = datetime( @@ -1754,19 +1757,18 @@ def date_time_this_century( else: return now - def date_time_this_decade( - self, - before_now=True, - after_now=False, - tzinfo=None): + def date_time_this_decade(self, + before_now: bool = True, + after_now: bool = False, + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Gets a DateTime object for the decade year. + Gets a datetime object for the decade year. :param before_now: include days in current decade before today :param after_now: include days in current decade after today :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2012-04-04 11:02:02') - :return DateTime + :example datetime('2012-04-04 11:02:02') + :return datetime """ now = datetime.now(tzinfo) this_decade_start = datetime( @@ -1784,19 +1786,18 @@ def date_time_this_decade( else: return now - def date_time_this_year( - self, - before_now=True, - after_now=False, - tzinfo=None): + def date_time_this_year(self, + before_now: bool = True, + after_now: bool = False, + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Gets a DateTime object for the current year. + Gets a datetime object for the current year. :param before_now: include days in current year before today :param after_now: include days in current year after today :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2012-04-04 11:02:02') - :return DateTime + :example datetime('2012-04-04 11:02:02') + :return datetime """ now = datetime.now(tzinfo) this_year_start = now.replace( @@ -1813,19 +1814,18 @@ def date_time_this_year( else: return now - def date_time_this_month( - self, - before_now=True, - after_now=False, - tzinfo=None): + def date_time_this_month(self, + before_now: bool = True, + after_now: bool = False, + tzinfo: Optional[TzInfo] = None) -> datetime: """ - Gets a DateTime object for the current month. + Gets a datetime object for the current month. :param before_now: include days in current month before today :param after_now: include days in current month after today :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2012-04-04 11:02:02') - :return DateTime + :example datetime('2012-04-04 11:02:02') + :return datetime """ now = datetime.now(tzinfo) this_month_start = now.replace( @@ -1843,7 +1843,7 @@ def date_time_this_month( else: return now - def date_this_century(self, before_today=True, after_today=False): + def date_this_century(self, before_today: bool = True, after_today: bool = False) -> dtdate: """ Gets a Date object for the current century. @@ -1866,7 +1866,7 @@ def date_this_century(self, before_today=True, after_today=False): else: return today - def date_this_decade(self, before_today=True, after_today=False): + def date_this_decade(self, before_today: bool = True, after_today: bool = False) -> dtdate: """ Gets a Date object for the decade year. @@ -1888,7 +1888,7 @@ def date_this_decade(self, before_today=True, after_today=False): else: return today - def date_this_year(self, before_today=True, after_today=False): + def date_this_year(self, before_today: bool = True, after_today: bool = False) -> dtdate: """ Gets a Date object for the current year. @@ -1910,15 +1910,14 @@ def date_this_year(self, before_today=True, after_today=False): else: return today - def date_this_month(self, before_today=True, after_today=False): + def date_this_month(self, before_today: bool = True, after_today: bool = False) -> dtdate: """ Gets a Date object for the current month. :param before_today: include days in current month before today :param after_today: include days in current month after today - :param tzinfo: timezone, instance of datetime.tzinfo subclass - :example DateTime('2012-04-04 11:02:02') - :return DateTime + :example dtdate('2012-04-04') + :return dtdate """ today = dtdate.today() this_month_start = today.replace(day=1) @@ -1936,11 +1935,11 @@ def date_this_month(self, before_today=True, after_today=False): def time_series( self, - start_date='-30d', - end_date='now', - precision=None, - distrib=None, - tzinfo=None): + start_date: DateParseType = '-30d', + end_date: DateParseType = 'now', + precision: Optional[float] = None, + distrib: Optional[Callable[[datetime], float]] = None, + tzinfo: Optional[TzInfo] = None) -> Iterator[Tuple[datetime, Any]]: """ Returns a generator yielding tuples of ``(, )``. @@ -1949,57 +1948,54 @@ def time_series( ``distrib`` is a callable that accepts ```` and returns ```` """ - start_date = self._parse_date_time(start_date, tzinfo=tzinfo) - end_date = self._parse_date_time(end_date, tzinfo=tzinfo) + start_date_ = self._parse_date_time(start_date, tzinfo=tzinfo) + end_date_ = self._parse_date_time(end_date, tzinfo=tzinfo) - if end_date < start_date: + if end_date_ < start_date_: raise ValueError("`end_date` must be greater than `start_date`.") - if precision is None: - precision = (end_date - start_date) / 30 - - precision = self._parse_timedelta(precision) + precision_ = self._parse_timedelta((end_date_ - start_date_) / 30 if precision is None else precision) if distrib is None: - def distrib(dt): return self.generator.random.uniform(0, precision) # noqa + def distrib(dt): return self.generator.random.uniform(0, precision_) # noqa if not callable(distrib): raise ValueError(f"`distrib` must be a callable. Got {distrib} instead.") - datapoint = start_date - while datapoint < end_date: + datapoint: Union[float, int] = start_date_ + while datapoint < end_date_: dt = timestamp_to_datetime(datapoint, tzinfo) - datapoint += precision + datapoint += precision_ yield (dt, distrib(dt)) - def am_pm(self): + def am_pm(self) -> str: return self.date('%p') - def day_of_month(self): + def day_of_month(self) -> str: return self.date('%d') - def day_of_week(self): + def day_of_week(self) -> str: return self.date('%A') - def month(self): + def month(self) -> str: return self.date('%m') - def month_name(self): + def month_name(self) -> str: return self.date('%B') - def year(self): + def year(self) -> str: return self.date('%Y') - def century(self): + def century(self) -> str: """ :example 'XVII' """ return self.random_element(self.centuries) - def timezone(self): + def timezone(self) -> str: return self.generator.random.choice( - self.random_element(self.countries)['timezones']) + self.random_element(self.countries)['timezones']) # type: ignore - def pytimezone(self, *args, **kwargs): + def pytimezone(self, *args: Any, **kwargs: Any) -> Optional[TzInfo]: """ Generate a random timezone (see `faker.timezone` for any args) and return as a python object usable as a `tzinfo` to `datetime` @@ -2008,9 +2004,9 @@ def pytimezone(self, *args, **kwargs): :example faker.pytimezone() :return dateutil.tz.tz.tzfile """ - return gettz(self.timezone(*args, **kwargs)) + return gettz(self.timezone(*args, **kwargs)) # type: ignore - def date_of_birth(self, tzinfo=None, minimum_age=0, maximum_age=115): + def date_of_birth(self, tzinfo: Optional[TzInfo] = None, minimum_age: int = 0, maximum_age: int = 115) -> dtdate: """ Generate a random date of birth represented as a Date object, constrained by optional miminimum_age and maximum_age @@ -2052,7 +2048,7 @@ def date_of_birth(self, tzinfo=None, minimum_age=0, maximum_age=115): return dob if dob != start_date else dob + timedelta(days=1) -def convert_timestamp_to_datetime(timestamp, tzinfo): +def convert_timestamp_to_datetime(timestamp: Union[int, float], tzinfo: TzInfo) -> datetime: import datetime as dt if timestamp >= 0: return dt.datetime.fromtimestamp(timestamp, tzinfo) diff --git a/faker/providers/date_time/ar_AA/__init__.py b/faker/providers/date_time/ar_AA/__init__.py index 19d32938d2..98506f6d51 100644 --- a/faker/providers/date_time/ar_AA/__init__.py +++ b/faker/providers/date_time/ar_AA/__init__.py @@ -1141,14 +1141,14 @@ class Provider(DateTimeProvider): 'PM': 'م', } - def month_name(self): + def month_name(self) -> str: month = self.date('%m') return self.MONTH_NAMES[month] - def am_pm(self): + def am_pm(self) -> str: date = self.date('%p') return self.AM_PM[date] - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') return self.DAY_NAMES[day] diff --git a/faker/providers/date_time/bn_BD/__init__.py b/faker/providers/date_time/bn_BD/__init__.py index 888e4f1e8e..db020c9c47 100644 --- a/faker/providers/date_time/bn_BD/__init__.py +++ b/faker/providers/date_time/bn_BD/__init__.py @@ -28,10 +28,10 @@ class Provider(DateTimeProvider): "12": "ডিসেম্বর", } - def day_of_week(self): + def day_of_week(self) -> str: day = self.date("%w") return self.DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() return self.MONTH_NAMES[month] diff --git a/faker/providers/date_time/fr_FR/__init__.py b/faker/providers/date_time/fr_FR/__init__.py index 67d51fb803..a0b3c51d30 100644 --- a/faker/providers/date_time/fr_FR/__init__.py +++ b/faker/providers/date_time/fr_FR/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "Dimanche", @@ -16,7 +16,7 @@ def day_of_week(self): } return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "Janvier", diff --git a/faker/providers/date_time/hi_IN/__init__.py b/faker/providers/date_time/hi_IN/__init__.py index 93ddf52d2d..072b88fe01 100644 --- a/faker/providers/date_time/hi_IN/__init__.py +++ b/faker/providers/date_time/hi_IN/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "सोमवार", @@ -17,7 +17,7 @@ def day_of_week(self): return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "जनवरी", diff --git a/faker/providers/date_time/hr_HR/__init__.py b/faker/providers/date_time/hr_HR/__init__.py index f885a2f464..4ce90dda5a 100644 --- a/faker/providers/date_time/hr_HR/__init__.py +++ b/faker/providers/date_time/hr_HR/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "Nedjelja", @@ -16,7 +16,7 @@ def day_of_week(self): } return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "Siječanj", diff --git a/faker/providers/date_time/hu_HU/__init__.py b/faker/providers/date_time/hu_HU/__init__.py index 7b579af620..59c4c5bab8 100644 --- a/faker/providers/date_time/hu_HU/__init__.py +++ b/faker/providers/date_time/hu_HU/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "hétfő", @@ -17,7 +17,7 @@ def day_of_week(self): return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "január", diff --git a/faker/providers/date_time/id_ID/__init__.py b/faker/providers/date_time/id_ID/__init__.py index 943d2cf5b6..87f36f29a2 100644 --- a/faker/providers/date_time/id_ID/__init__.py +++ b/faker/providers/date_time/id_ID/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "Senin", @@ -17,7 +17,7 @@ def day_of_week(self): return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "Januari", diff --git a/faker/providers/date_time/ko_KR/__init__.py b/faker/providers/date_time/ko_KR/__init__.py index 8d2dbc623e..d3a0d339ad 100644 --- a/faker/providers/date_time/ko_KR/__init__.py +++ b/faker/providers/date_time/ko_KR/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "일요일", @@ -16,7 +16,7 @@ def day_of_week(self): } return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "1월", diff --git a/faker/providers/date_time/ru_RU/__init__.py b/faker/providers/date_time/ru_RU/__init__.py index 8618c5086b..a4bf3855c2 100644 --- a/faker/providers/date_time/ru_RU/__init__.py +++ b/faker/providers/date_time/ru_RU/__init__.py @@ -1236,10 +1236,10 @@ class Provider(DateTimeProvider): 'capital': 'Лондон'}, ] - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') return self.DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() return self.MONTH_NAMES[month] diff --git a/faker/providers/date_time/sl_SI/__init__.py b/faker/providers/date_time/sl_SI/__init__.py index 7ead297252..025936217d 100644 --- a/faker/providers/date_time/sl_SI/__init__.py +++ b/faker/providers/date_time/sl_SI/__init__.py @@ -3,7 +3,7 @@ class Provider(DateTimeProvider): - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') DAY_NAMES = { "0": "Nedelja", @@ -16,7 +16,7 @@ def day_of_week(self): } return DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() MONTH_NAMES = { "01": "Januar", diff --git a/faker/providers/date_time/ta_IN/__init__.py b/faker/providers/date_time/ta_IN/__init__.py index daf61f4a0d..df77379a02 100644 --- a/faker/providers/date_time/ta_IN/__init__.py +++ b/faker/providers/date_time/ta_IN/__init__.py @@ -29,10 +29,10 @@ class Provider(DateTimeProvider): "12": "டிசம்பர்", } - def day_of_week(self): + def day_of_week(self) -> str: day = self.date('%w') return self.DAY_NAMES[day] - def month_name(self): + def month_name(self) -> str: month = self.month() return self.MONTH_NAMES[month] diff --git a/faker/providers/date_time/th_TH/__init__.py b/faker/providers/date_time/th_TH/__init__.py index 888888757c..007b2dc1c1 100644 --- a/faker/providers/date_time/th_TH/__init__.py +++ b/faker/providers/date_time/th_TH/__init__.py @@ -1,8 +1,10 @@ import warnings from datetime import datetime +from typing import Optional -from .. import Provider as DateTimeProvider +from ....typing import DateParseType +from .. import Provider as DateParseTypeProvider # thai_strftime() code adapted from # https://gist.github.com/bact/b8afe49cb1ae62913e6c1e899dcddbdb @@ -273,14 +275,14 @@ def thai_strftime( return thaidate_text -class Provider(DateTimeProvider): +class Provider(DateParseTypeProvider): def date( self, pattern: str = "%-d %b %Y", - end_datetime=None, + end_datetime: Optional[DateParseType] = None, thai_digit: bool = False, buddhist_era: bool = True, - ): + ) -> str: """ Get a date string between January 1, 1970 and now :param pattern format @@ -289,7 +291,7 @@ def date( :param buddhist_era use Buddist era or not (default: True) :example '08 พ.ย. 2563' :example '๐๘ พ.ย. 2563' (thai_digit = True) - :example '8 พฤศิจกายน 2020' (pattern = "%-d %B %Y", buddhist_era = False) + :example '8 พฤศิจกายน 2020' (pattern: str = "%-d %B %Y", buddhist_era = False) """ return thai_strftime( self.date_time(end_datetime=end_datetime), @@ -299,8 +301,8 @@ def date( ) def time( - self, pattern="%H:%M:%S", end_datetime=None, thai_digit: bool = False, - ): + self, pattern: str = "%H:%M:%S", end_datetime: Optional[DateParseType] = None, thai_digit: bool = False, + ) -> str: """ Get a time string (24h format by default) :param pattern format @@ -310,12 +312,12 @@ def time( :example '๑๕:๐๒:๓๔' (thai_digit = True) """ return thai_strftime( - self.date_time(end_datetime=end_datetime).time(), + self.date_time(end_datetime=end_datetime), pattern, thai_digit, ) - def century(self, thai_digit: bool = False, buddhist_era: bool = True): + def century(self, thai_digit: bool = False, buddhist_era: bool = True) -> str: """ :param thai_digit use Thai digit or not (default: False) :param buddhist_era use Buddist era or not (default: True) diff --git a/faker/providers/file/__init__.py b/faker/providers/file/__init__.py index 2fb04bf860..a8beae8406 100644 --- a/faker/providers/file/__init__.py +++ b/faker/providers/file/__init__.py @@ -1,14 +1,15 @@ import string from collections import OrderedDict +from typing import Dict, Optional -from .. import BaseProvider +from .. import BaseProvider, ElementsType class Provider(BaseProvider): """Implement default file provider for Faker.""" - application_mime_types = ( + application_mime_types: ElementsType = ( "application/atom+xml", # Atom feeds "application/ecmascript", @@ -49,7 +50,7 @@ class Provider(BaseProvider): "application/gzip", # Gzip, Defined in RFC 6713 ) - audio_mime_types = ( + audio_mime_types: ElementsType = ( "audio/basic", # mulaw audio at 8 kHz, 1 channel; Defined in RFC 2046 "audio/L24", # 24bit Linear PCM audio at 8-48 kHz, 1-N channels; Defined in RFC 3190 "audio/mp4", # MP4 audio @@ -62,7 +63,7 @@ class Provider(BaseProvider): "audio/webm", # WebM open media format ) - image_mime_types = ( + image_mime_types: ElementsType = ( "image/gif", # GIF image; Defined in RFC 2045 and RFC 2046 "image/jpeg", # JPEG JFIF image; Defined in RFC 2045 and RFC 2046 "image/pjpeg", @@ -76,7 +77,7 @@ class Provider(BaseProvider): "image/vnd.microsoft.icon", # ICO image; Registered[11] ) - message_mime_types = ( + message_mime_types: ElementsType = ( "message/http", # Defined in RFC 2616 "message/imdn+xml", # IMDN Instant Message Disposition Notification; Defined in RFC 5438 "message/partial", # Email; Defined in RFC 2045 and RFC 2046 @@ -85,7 +86,7 @@ class Provider(BaseProvider): "message/rfc822", ) - model_mime_types = ( + model_mime_types: ElementsType = ( "model/example", # Defined in RFC 4735 "model/iges", # IGS files, IGES files; Defined in RFC 2077 "model/mesh", # MSH files, MESH files; Defined in RFC 2077, SILO files @@ -97,7 +98,7 @@ class Provider(BaseProvider): "model/x3d+xml", # X3D ISO standard for representing 3D computer graphics, X3D XML files ) - multipart_mime_types = ( + multipart_mime_types: ElementsType = ( "multipart/mixed", # MIME Email; Defined in RFC 2045 and RFC 2046 "multipart/alternative", # MIME Email; Defined in RFC 2045 and RFC 2046 # MIME Email; Defined in RFC 2387 and used by MHTML (HTML mail) @@ -107,7 +108,7 @@ class Provider(BaseProvider): "multipart/encrypted", # Defined in RFC 1847 ) - text_mime_types = ( + text_mime_types: ElementsType = ( "text/cmd", # commands; subtype resident in Gecko browsers like Firefox 3.5 "text/css", # Cascading Style Sheets; Defined in RFC 2318 "text/csv", # Comma-separated values; Defined in RFC 4180 @@ -123,7 +124,7 @@ class Provider(BaseProvider): "text/xml", # Extensible Markup Language; Defined in RFC 3023 ) - video_mime_types = ( + video_mime_types: ElementsType = ( "video/mpeg", # MPEG-1 video with multiplexed audio; Defined in RFC 2045 and RFC 2046 "video/mp4", # MP4 video; Defined in RFC 4337 # Ogg Theora or other video (with audio); Defined in RFC 5334 @@ -135,7 +136,7 @@ class Provider(BaseProvider): "video/x-flv", # Flash video (FLV files) ) - mime_types = OrderedDict(( + mime_types: Dict[str, ElementsType] = OrderedDict(( ('application', application_mime_types), ('audio', audio_mime_types), ('image', image_mime_types), @@ -146,13 +147,13 @@ class Provider(BaseProvider): ('video', video_mime_types), )) - audio_file_extensions = ( + audio_file_extensions: ElementsType = ( "flac", "mp3", "wav", ) - image_file_extensions = ( + image_file_extensions: ElementsType = ( "bmp", "gif", "jpeg", @@ -161,7 +162,7 @@ class Provider(BaseProvider): "tiff", ) - text_file_extensions = ( + text_file_extensions: ElementsType = ( "css", "csv", "html", @@ -170,14 +171,14 @@ class Provider(BaseProvider): "txt", ) - video_file_extensions = ( + video_file_extensions: ElementsType = ( "mp4", "avi", "mov", "webm", ) - office_file_extensions = ( + office_file_extensions: ElementsType = ( "doc", # legacy MS Word "docx", # MS Word "xls", # legacy MS Excel @@ -193,16 +194,16 @@ class Provider(BaseProvider): "pdf", # Portable Document Format ) - file_extensions = OrderedDict(( + file_extensions: Dict[str, ElementsType] = OrderedDict(( ("audio", audio_file_extensions), ("image", image_file_extensions), ("office", office_file_extensions), ("text", text_file_extensions), ("video", video_file_extensions), )) - unix_device_prefixes = ('sd', 'vd', 'xvd') + unix_device_prefixes: ElementsType = ('sd', 'vd', 'xvd') - def mime_type(self, category=None): + def mime_type(self, category: Optional[str] = None) -> str: """Generate a mime type under the specified ``category``. If ``category`` is ``None``, a random category will be used. The list of @@ -217,7 +218,7 @@ def mime_type(self, category=None): list(self.mime_types.keys())) return self.random_element(self.mime_types[category]) - def file_name(self, category=None, extension=None): + def file_name(self, category: Optional[str] = None, extension: Optional[str] = None) -> str: """Generate a random file name with extension. If ``extension`` is ``None``, a random extension will be created under @@ -231,11 +232,12 @@ def file_name(self, category=None, extension=None): :sample: extension='abcdef' :sample: category='audio', extension='abcdef' """ - extension = extension if extension else self.file_extension(category) - filename = self.generator.word() + if extension is None: + extension = self.file_extension(category) + filename: str = self.generator.word() return f'{filename}.{extension}' - def file_extension(self, category=None): + def file_extension(self, category: Optional[str] = None) -> str: """Generate a file extension under the specified ``category``. If ``category`` is ``None``, a random category will be used. The list of @@ -245,11 +247,11 @@ def file_extension(self, category=None): :sample: :sample: category='image' """ - category = category if category else self.random_element( - list(self.file_extensions.keys())) + if category is None: + category = self.random_element(list(self.file_extensions.keys())) return self.random_element(self.file_extensions[category]) - def file_path(self, depth=1, category=None, extension=None): + def file_path(self, depth: int = 1, category: Optional[str] = None, extension: Optional[str] = None) -> str: """Generate an absolute pathname to a file. This method uses |file_name| under the hood to generate the file name @@ -261,13 +263,13 @@ def file_path(self, depth=1, category=None, extension=None): :sample: depth=5, category='video' :sample: depth=5, category='video', extension='abcdef' """ - file = self.file_name(category, extension) - path = f'/{file}' + file: str = self.file_name(category, extension) + path: str = f'/{file}' for _ in range(0, depth): path = f'/{self.generator.word()}{path}' return path - def unix_device(self, prefix=None): + def unix_device(self, prefix: Optional[str] = None) -> str: """Generate a Unix device file name. If ``prefix`` is ``None``, a random prefix will be used. The list of @@ -276,12 +278,13 @@ def unix_device(self, prefix=None): :sample: :sample: prefix='mmcblk' """ - prefix = prefix or self.random_element(self.unix_device_prefixes) - suffix = self.random_element(string.ascii_lowercase) + if prefix is None: + prefix = self.random_element(self.unix_device_prefixes) + suffix: str = self.random_element(string.ascii_lowercase) path = '/dev/%s%s' % (prefix, suffix) return path - def unix_partition(self, prefix=None): + def unix_partition(self, prefix: Optional[str] = None) -> str: """Generate a Unix partition name. This method uses |unix_device| under the hood to create a device file @@ -290,6 +293,6 @@ def unix_partition(self, prefix=None): :sample: :sample: prefix='mmcblk' """ - path = self.unix_device(prefix=prefix) + path: str = self.unix_device(prefix=prefix) path += str(self.random_digit()) return path diff --git a/faker/providers/geo/__init__.py b/faker/providers/geo/__init__.py index 028b65b035..ada769a4af 100644 --- a/faker/providers/geo/__init__.py +++ b/faker/providers/geo/__init__.py @@ -1,9 +1,12 @@ from decimal import Decimal +from typing import Optional, Tuple, Union from .. import BaseProvider localized = True +PlaceType = Tuple[str, str, str, str, str] + class Provider(BaseProvider): """ @@ -13,7 +16,7 @@ class Provider(BaseProvider): Timezones are canonical (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). """ - land_coords = ( + land_coords: Tuple[PlaceType, ...] = ( ("42.50729", "1.53414", "les Escaldes", "AD", "Europe/Andorra"), ("36.21544", "65.93249", "Sar-e Pul", "AF", "Asia/Kabul"), ("40.49748", "44.7662", "Hrazdan", "AM", "Asia/Yerevan"), @@ -974,7 +977,7 @@ class Provider(BaseProvider): ("-24.19436", "29.00974", "Mokopane", "ZA", "Africa/Johannesburg"), ) - def coordinate(self, center=None, radius=0.001): + def coordinate(self, center: Optional[float] = None, radius: Union[float, int] = 0.001) -> Decimal: """ Optionally center the coord and pick a point within radius. """ @@ -988,29 +991,33 @@ def coordinate(self, center=None, radius=0.001): geo = self.generator.random.uniform(center - radius, center + radius) return Decimal(str(geo)).quantize(Decimal(".000001")) - def latitude(self): + def latitude(self) -> Decimal: # Latitude has a range of -90 to 90, so divide by two. return self.coordinate() / 2 - def longitude(self): + def longitude(self) -> Decimal: return self.coordinate() - def latlng(self): + def latlng(self) -> Tuple[Decimal, Decimal]: return (self.latitude(), self.longitude()) - def local_latlng(self, country_code='US', coords_only=False): + def local_latlng(self, + country_code: str = 'US', + coords_only: bool = False, + ) -> Optional[Tuple[str, ...]]: """Returns a location known to exist on land in a country specified by `country_code`. Defaults to 'en_US'. See the `land_coords` list for available locations/countries. """ results = [loc for loc in self.land_coords if loc[3] == country_code] if results: - place = self.random_element(results) + place: PlaceType = self.random_element(results) return (place[0], place[1]) if coords_only else place + return None - def location_on_land(self, coords_only=False): + def location_on_land(self, coords_only: bool = False) -> Tuple[str, ...]: """Returns a random tuple specifying a coordinate set guaranteed to exist on land. Format is `(latitude, longitude, place name, two-letter country code, timezone)` Pass `coords_only` to return coordinates without metadata. """ - place = self.random_element(self.land_coords) + place: PlaceType = self.random_element(self.land_coords) return (place[0], place[1]) if coords_only else place diff --git a/faker/providers/geo/de_AT/__init__.py b/faker/providers/geo/de_AT/__init__.py index 0277ca8414..9aeed5f80f 100644 --- a/faker/providers/geo/de_AT/__init__.py +++ b/faker/providers/geo/de_AT/__init__.py @@ -1,10 +1,12 @@ +from decimal import Decimal + from .. import Provider as GeoProvider class Provider(GeoProvider): - def local_latitude(self): + def local_latitude(self) -> Decimal: return self.coordinate(center=47.60707, radius=1) - def local_longitude(self): + def local_longitude(self) -> Decimal: return self.coordinate(center=13.37208, radius=2) diff --git a/faker/providers/geo/el_GR/__init__.py b/faker/providers/geo/el_GR/__init__.py index 291990fa55..f2811701e4 100644 --- a/faker/providers/geo/el_GR/__init__.py +++ b/faker/providers/geo/el_GR/__init__.py @@ -1,4 +1,5 @@ from decimal import Decimal +from typing import Any, Tuple from .. import Provider as GeoProvider @@ -6,21 +7,21 @@ class Provider(GeoProvider): poly = ( - (40.34026, 19.15120), - (42.21670, 26.13934), - (35.55680, 29.38280), - (34.15370, 22.58810), + ('40.34026', '19.15120'), + ('42.21670', '26.13934'), + ('35.55680', '29.38280'), + ('34.15370', '22.58810'), ) - def local_latlng(self): - return float(self.local_latitude()), float(self.local_longitude()) + def local_latlng(self, *args: Any, **kwargs: Any) -> Tuple[str, str]: + return str(self.local_latitude()), str(self.local_longitude()) - def local_latitude(self): - latitudes = list(map(lambda t: int(t[0] * 10000000), self.poly)) + def local_latitude(self) -> Decimal: + latitudes = list(map(lambda t: int(Decimal(t[0]) * 10000000), self.poly)) return Decimal(str(self.generator.random.randint( min(latitudes), max(latitudes)) / 10000000)).quantize(Decimal('.000001')) - def local_longitude(self): - longitudes = list(map(lambda t: int(t[1] * 10000000), self.poly)) + def local_longitude(self) -> Decimal: + longitudes = list(map(lambda t: int(Decimal(t[1]) * 10000000), self.poly)) return Decimal(str(self.generator.random.randint( min(longitudes), max(longitudes)) / 10000000)).quantize(Decimal('.000001')) diff --git a/faker/providers/geo/pt_PT/__init__.py b/faker/providers/geo/pt_PT/__init__.py index 0d5691e70b..f95dc1ad11 100644 --- a/faker/providers/geo/pt_PT/__init__.py +++ b/faker/providers/geo/pt_PT/__init__.py @@ -20,7 +20,7 @@ class Provider(GeoProvider): "Monegasca", "Maliana", "Mongol", "Mauritana", "Malaia", "Panamiana", "Saudita", "Singapurense", "Togolesa", ) - def nationality(self): + def nationality(self) -> str: """ :example 'Portuguesa' """ diff --git a/faker/providers/geo/tr_TR/__init__.py b/faker/providers/geo/tr_TR/__init__.py index 56ff1ad921..5b6c3147da 100644 --- a/faker/providers/geo/tr_TR/__init__.py +++ b/faker/providers/geo/tr_TR/__init__.py @@ -85,4 +85,4 @@ class Provider(GeoProvider): ('38.415342100000004', '27.144474', 'İzmir', 'TR', 'Europe/Istanbul'), ('37.2595198', '39.0408174', 'Şanlıurfa', 'TR', 'Europe/Istanbul'), ('37.455253000000006', '42.5212049', 'Şırnak', 'TR', 'Europe/Istanbul'), - ) + ) diff --git a/faker/providers/internet/__init__.py b/faker/providers/internet/__init__.py index e1b4f921f8..562d66011b 100644 --- a/faker/providers/internet/__init__.py +++ b/faker/providers/internet/__init__.py @@ -1,13 +1,11 @@ -from ipaddress import IPV4LENGTH, IPV6LENGTH, ip_address, ip_network +from ipaddress import IPV4LENGTH, IPV6LENGTH, IPv4Network, ip_address, ip_network +from typing import Dict, List, Optional, Tuple from text_unidecode import unidecode -# from faker.generator import random -# from faker.providers.lorem.la import Provider as Lorem -from faker.utils.decorators import lowercase, slugify, slugify_unicode -from faker.utils.distribution import choices_distribution - -from .. import BaseProvider +from ...utils.decorators import lowercase, slugify, slugify_unicode +from ...utils.distribution import choices_distribution +from .. import BaseProvider, ElementsType localized = True @@ -20,7 +18,7 @@ class _IPv4Constants: Excluded network list is updated to comply with current IANA list of private and reserved networks. """ - _network_classes = { + _network_classes: Dict[str, IPv4Network] = { 'a': ip_network('0.0.0.0/1'), 'b': ip_network('128.0.0.0/2'), 'c': ip_network('192.0.0.0/3'), @@ -28,7 +26,7 @@ class _IPv4Constants: # Three common private networks from class A, B and CIDR # to generate private addresses from. - _private_networks = [ + _private_networks: List[IPv4Network] = [ ip_network('10.0.0.0/8'), ip_network('172.16.0.0/12'), ip_network('192.168.0.0/16'), @@ -37,7 +35,7 @@ class _IPv4Constants: # List of networks from which IP addresses will never be generated, # includes other private IANA and reserved networks from # ttps://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml - _excluded_networks = [ + _excluded_networks: List[IPv4Network] = [ ip_network('0.0.0.0/8'), ip_network('100.64.0.0/10'), ip_network('127.0.0.0/8'), # loopback network @@ -58,60 +56,60 @@ class _IPv4Constants: class Provider(BaseProvider): - safe_domain_names = ('example.org', 'example.com', 'example.net') - free_email_domains = ('gmail.com', 'yahoo.com', 'hotmail.com') - tlds = ( + safe_domain_names: ElementsType = ('example.org', 'example.com', 'example.net') + free_email_domains: ElementsType = ('gmail.com', 'yahoo.com', 'hotmail.com') + tlds: ElementsType = ( 'com', 'com', 'com', 'com', 'com', 'com', 'biz', 'info', 'net', 'org', ) - hostname_prefixes = ('db', 'srv', 'desktop', 'laptop', 'lt', 'email', 'web') - uri_pages = ( + hostname_prefixes: ElementsType = ('db', 'srv', 'desktop', 'laptop', 'lt', 'email', 'web') + uri_pages: ElementsType = ( 'index', 'home', 'search', 'main', 'post', 'homepage', 'category', 'register', 'login', 'faq', 'about', 'terms', 'privacy', 'author', ) - uri_paths = ( + uri_paths: ElementsType = ( 'app', 'main', 'wp-content', 'search', 'category', 'tag', 'categories', 'tags', 'blog', 'posts', 'list', 'explore', ) - uri_extensions = ( + uri_extensions: ElementsType = ( '.html', '.html', '.html', '.htm', '.htm', '.php', '.php', '.jsp', '.asp', ) - http_methods = ( + http_methods: ElementsType = ( 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH', ) - user_name_formats = ( + user_name_formats: ElementsType = ( '{{last_name}}.{{first_name}}', '{{first_name}}.{{last_name}}', '{{first_name}}##', '?{{last_name}}', ) - email_formats = ( + email_formats: ElementsType = ( '{{user_name}}@{{domain_name}}', '{{user_name}}@{{free_email_domain}}', ) - url_formats = ( + url_formats: ElementsType = ( 'www.{{domain_name}}/', '{{domain_name}}/', ) - uri_formats = ( + uri_formats: ElementsType = ( '{{url}}', '{{url}}{{uri_page}}/', '{{url}}{{uri_page}}{{uri_extension}}', '{{url}}{{uri_path}}/{{uri_page}}/', '{{url}}{{uri_path}}/{{uri_page}}{{uri_extension}}', ) - image_placeholder_services = ( + image_placeholder_services: ElementsType = ( 'https://www.lorempixel.com/{width}/{height}', 'https://dummyimage.com/{width}x{height}', 'https://placekitten.com/{width}/{height}', 'https://placeimg.com/{width}/{height}/any', ) - replacements = () + replacements: Tuple[Tuple[str, str], ...] = () - def _to_ascii(self, string): + def _to_ascii(self, string: str) -> str: for search, replace in self.replacements: string = string.replace(search, replace) @@ -119,69 +117,66 @@ def _to_ascii(self, string): return string @lowercase - def email(self, safe=True, domain=None): + def email(self, safe: bool = True, domain: Optional[str] = None) -> str: if domain: email = f'{self.user_name()}@{domain}' elif safe: email = f'{self.user_name()}@{self.safe_domain_name()}' else: - pattern = self.random_element(self.email_formats) + pattern: str = self.random_element(self.email_formats) email = "".join(self.generator.parse(pattern).split(" ")) return email @lowercase - def safe_domain_name(self): + def safe_domain_name(self) -> str: return self.random_element(self.safe_domain_names) @lowercase - def safe_email(self): + def safe_email(self) -> str: return self.user_name() + '@' + self.safe_domain_name() @lowercase - def free_email(self): + def free_email(self) -> str: return self.user_name() + '@' + self.free_email_domain() @lowercase - def company_email(self): + def company_email(self) -> str: return self.user_name() + '@' + self.domain_name() @lowercase - def free_email_domain(self): + def free_email_domain(self) -> str: return self.random_element(self.free_email_domains) @lowercase - def ascii_email(self): - pattern = self.random_element(self.email_formats) + def ascii_email(self) -> str: + pattern: str = self.random_element(self.email_formats) return self._to_ascii( "".join(self.generator.parse(pattern).split(" ")), ) @lowercase - def ascii_safe_email(self): + def ascii_safe_email(self) -> str: return self._to_ascii(self.user_name() + '@' + self.safe_domain_name()) @lowercase - def ascii_free_email(self): + def ascii_free_email(self) -> str: return self._to_ascii( self.user_name() + '@' + self.free_email_domain(), ) @lowercase - def ascii_company_email(self): + def ascii_company_email(self) -> str: return self._to_ascii( self.user_name() + '@' + self.domain_name(), ) @slugify_unicode - def user_name(self): - pattern = self.random_element(self.user_name_formats) - username = self._to_ascii( - self.bothify(self.generator.parse(pattern)).lower(), - ) - return username + def user_name(self) -> str: + pattern: str = self.random_element(self.user_name_formats) + return self._to_ascii(self.bothify(self.generator.parse(pattern)).lower()) @lowercase - def hostname(self, levels=1): + def hostname(self, levels: int = 1) -> str: """ Produce a hostname with specified number of subdomain levels. @@ -192,12 +187,13 @@ def hostname(self, levels=1): >>> hostname(2) web-12.williamson-hopkins.jackson.com """ - if levels < 1: - return self.random_element(self.hostname_prefixes) + '-' + self.numerify('##') - return self.random_element(self.hostname_prefixes) + '-' + self.numerify('##') + '.' + self.domain_name(levels) + hostname_prefix: str = self.random_element(self.hostname_prefixes) + hostname_prefix_first_level: str = hostname_prefix + '-' + self.numerify('##') + return hostname_prefix_first_level if levels < 1 \ + else hostname_prefix_first_level + '.' + self.domain_name(levels) @lowercase - def domain_name(self, levels=1): + def domain_name(self, levels: int = 1) -> str: """ Produce an Internet domain name with the specified number of subdomain levels. @@ -211,18 +207,21 @@ def domain_name(self, levels=1): raise ValueError("levels must be greater than or equal to 1") if levels == 1: return self.domain_word() + '.' + self.tld() - else: - return self.domain_word() + '.' + self.domain_name(levels - 1) + return self.domain_word() + '.' + self.domain_name(levels - 1) @lowercase @slugify_unicode - def domain_word(self): - company = self.generator.format('company') - company_elements = company.split(' ') - company = self._to_ascii(company_elements.pop(0)) - return company - - def dga(self, year=None, month=None, day=None, tld=None, length=None): + def domain_word(self) -> str: + company: str = self.generator.format('company') + company_elements: List[str] = company.split(' ') + return self._to_ascii(company_elements.pop(0)) + + def dga(self, + year: Optional[int] = None, + month: Optional[int] = None, + day: Optional[int] = None, + tld: Optional[str] = None, + length: Optional[int] = None) -> str: """Generates a domain name by given date https://en.wikipedia.org/wiki/Domain_generation_algorithm @@ -249,10 +248,10 @@ def dga(self, year=None, month=None, day=None, tld=None, length=None): return domain + '.' + tld - def tld(self): + def tld(self) -> str: return self.random_element(self.tlds) - def http_method(self): + def http_method(self) -> str: """Returns random HTTP method https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods @@ -261,7 +260,7 @@ def http_method(self): return self.random_element(self.http_methods) - def url(self, schemes=None): + def url(self, schemes: Optional[List[str]] = None) -> str: """ :param schemes: a list of strings to use as schemes, one will chosen randomly. If None, it will generate http and https urls. @@ -272,11 +271,12 @@ def url(self, schemes=None): if schemes is None: schemes = ['http', 'https'] - pattern = f'{self.random_element(schemes) if schemes else ""}://{self.random_element(self.url_formats)}' + pattern: str = f'{self.random_element(schemes) if schemes else ""}://{self.random_element(self.url_formats)}' return self.generator.parse(pattern) - def _get_all_networks_and_weights(self, address_class=None): + def _get_all_networks_and_weights(self, + address_class: Optional[str] = None) -> Tuple[List[IPv4Network], List[int]]: """ Produces a 2-tuple of valid IPv4 networks and corresponding relative weights @@ -285,7 +285,7 @@ def _get_all_networks_and_weights(self, address_class=None): # If `address_class` has an unexpected value, use the whole IPv4 pool if address_class in _IPv4Constants._network_classes.keys(): networks_attr = f'_cached_all_class_{address_class}_networks' - all_networks = [_IPv4Constants._network_classes[address_class]] + all_networks = [_IPv4Constants._network_classes[address_class]] # type: ignore else: networks_attr = '_cached_all_networks' all_networks = [ip_network('0.0.0.0/0')] @@ -309,14 +309,16 @@ def _get_all_networks_and_weights(self, address_class=None): setattr(self, weights_attr, weights) return all_networks, weights - def _get_private_networks_and_weights(self, address_class=None): + def _get_private_networks_and_weights(self, + address_class: Optional[str] = None, + ) -> Tuple[List[IPv4Network], List[int]]: """ Produces an OrderedDict of valid private IPv4 networks and corresponding relative weights :param address_class: IPv4 address class (a, b, or c) """ # If `address_class` has an unexpected value, choose a valid value at random - if address_class not in _IPv4Constants._network_classes.keys(): + if not address_class or address_class not in _IPv4Constants._network_classes.keys(): address_class = self.ipv4_network_class() # Return cached network and weight data if available for a specific address class @@ -344,7 +346,9 @@ def _get_private_networks_and_weights(self, address_class=None): setattr(self, weights_attr, weights) return private_networks, weights - def _get_public_networks_and_weights(self, address_class=None): + def _get_public_networks_and_weights(self, + address_class: Optional[str] = None, + ) -> Tuple[List[IPv4Network], List[int]]: """ Produces a 2-tuple of valid public IPv4 networks and corresponding relative weights @@ -361,7 +365,7 @@ def _get_public_networks_and_weights(self, address_class=None): return getattr(self, networks_attr), getattr(self, weights_attr) # Otherwise, compute for list of public networks (excluding private and special networks) - public_networks = [_IPv4Constants._network_classes[address_class]] + public_networks = [_IPv4Constants._network_classes[address_class]] # type: ignore public_networks = self._exclude_ipv4_networks( public_networks, _IPv4Constants._private_networks + @@ -376,7 +380,10 @@ def _get_public_networks_and_weights(self, address_class=None): setattr(self, weights_attr, weights) return public_networks, weights - def _random_ipv4_address_from_subnets(self, subnets, weights=None, network=False): + def _random_ipv4_address_from_subnets(self, + subnets: List[IPv4Network], + weights: Optional[List[int]] = None, + network: bool = False) -> str: """ Produces a random IPv4 address or network with a valid CIDR from within the given subnets using a distribution described @@ -387,10 +394,16 @@ def _random_ipv4_address_from_subnets(self, subnets, weights=None, network=False :param network: Return a network address, and not an IP address :return: """ + if not subnets: + raise ValueError('No subnets to choose from') + # If the weights argument has an invalid value, default to equal distribution - try: - subnet = choices_distribution(subnets, weights, random=self.generator.random, length=1)[0] - except (AssertionError, TypeError): + if (isinstance(weights, list) and len(subnets) == len(weights) and + all(isinstance(w, (float, int)) for w in weights)): + subnet = choices_distribution(subnets, + [float(w) for w in weights], + random=self.generator.random, length=1)[0] + else: subnet = self.generator.random.choice(subnets) address = str( @@ -408,7 +421,9 @@ def _random_ipv4_address_from_subnets(self, subnets, weights=None, network=False return address - def _exclude_ipv4_networks(self, networks, networks_to_exclude): + def _exclude_ipv4_networks(self, + networks: List[IPv4Network], + networks_to_exclude: List[IPv4Network]) -> List[IPv4Network]: """ Exclude the list of networks from another list of networks and return a flat list of new networks. @@ -443,16 +458,12 @@ def _exclude_ipv4_network(network): else: return [network] - networks = list(map(_exclude_ipv4_network, networks)) - - # flatten list of lists - networks = [ - item for nested in networks for item in nested - ] + nested_networks = list(map(_exclude_ipv4_network, networks)) + networks = [item for nested in nested_networks for item in nested] return networks - def ipv4_network_class(self): + def ipv4_network_class(self) -> str: """ Returns a IPv4 network class 'a', 'b' or 'c'. @@ -460,7 +471,7 @@ def ipv4_network_class(self): """ return self.random_element('abc') - def ipv4(self, network=False, address_class=None, private=None): + def ipv4(self, network: bool = False, address_class: Optional[str] = None, private: Optional[str] = None) -> str: """ Returns a random IPv4 address or network with a valid CIDR. @@ -479,7 +490,7 @@ def ipv4(self, network=False, address_class=None, private=None): all_networks, weights = self._get_all_networks_and_weights(address_class=address_class) return self._random_ipv4_address_from_subnets(all_networks, weights=weights, network=network) - def ipv4_private(self, network=False, address_class=None): + def ipv4_private(self, network: bool = False, address_class: Optional[str] = None) -> str: """ Returns a private IPv4. @@ -490,7 +501,7 @@ def ipv4_private(self, network=False, address_class=None): private_networks, weights = self._get_private_networks_and_weights(address_class=address_class) return self._random_ipv4_address_from_subnets(private_networks, weights=weights, network=network) - def ipv4_public(self, network=False, address_class=None): + def ipv4_public(self, network: bool = False, address_class: Optional[str] = None) -> str: """ Returns a public IPv4 excluding private blocks. @@ -501,7 +512,7 @@ def ipv4_public(self, network=False, address_class=None): public_networks, weights = self._get_public_networks_and_weights(address_class=address_class) return self._random_ipv4_address_from_subnets(public_networks, weights=weights, network=network) - def ipv6(self, network=False): + def ipv6(self, network: bool = False) -> str: """Produce a random IPv6 address or network with a valid CIDR""" address = str(ip_address(self.generator.random.randint( 2 ** IPV4LENGTH, (2 ** IPV6LENGTH) - 1))) @@ -510,11 +521,11 @@ def ipv6(self, network=False): address = str(ip_network(address, strict=False)) return address - def mac_address(self): + def mac_address(self) -> str: mac = [self.generator.random.randint(0x00, 0xff) for _ in range(0, 6)] return ":".join(map(lambda x: "%02x" % x, mac)) - def port_number(self, is_system=False, is_user=False, is_dynamic=False): + def port_number(self, is_system: bool = False, is_user: bool = False, is_dynamic: bool = False) -> int: """Returns a network port number https://tools.ietf.org/html/rfc6335 @@ -533,40 +544,40 @@ def port_number(self, is_system=False, is_user=False, is_dynamic=False): return self.random_int(min=0, max=65535) - def uri_page(self): + def uri_page(self) -> str: return self.random_element(self.uri_pages) - def uri_path(self, deep=None): + def uri_path(self, deep: Optional[int] = None) -> str: deep = deep if deep else self.generator.random.randint(1, 3) return "/".join( self.random_elements(self.uri_paths, length=deep), ) - def uri_extension(self): + def uri_extension(self) -> str: return self.random_element(self.uri_extensions) - def uri(self): - pattern = self.random_element(self.uri_formats) + def uri(self) -> str: + pattern: str = self.random_element(self.uri_formats) return self.generator.parse(pattern) @slugify - def slug(self, value=None): + def slug(self, value: Optional[str] = None) -> str: """Django algorithm""" if value is None: value = self.generator.text(20) return value - def image_url(self, width=None, height=None): + def image_url(self, width: Optional[int] = None, height: Optional[int] = None) -> str: """ Returns URL to placeholder image Example: http://placehold.it/640x480 """ width_ = width or self.random_int(max=1024) height_ = height or self.random_int(max=1024) - placeholder_url = self.random_element(self.image_placeholder_services) + placeholder_url: str = self.random_element(self.image_placeholder_services) return placeholder_url.format(width=width_, height=height_) - def iana_id(self): + def iana_id(self) -> str: """Returns IANA Registrar ID https://www.iana.org/assignments/registrar-ids/registrar-ids.xhtml @@ -575,7 +586,7 @@ def iana_id(self): return str(self.random_int(min=1, max=8888888)) - def ripe_id(self): + def ripe_id(self) -> str: """Returns RIPE Organization ID https://www.ripe.net/manage-ips-and-asns/db/support/organisation-object-in-the-ripe-database @@ -586,7 +597,7 @@ def ripe_id(self): num = '%' * self.random_int(min=1, max=5) return self.bothify(f'ORG-{lex}{num}-RIPE').upper() - def nic_handle(self, suffix='FAKE'): + def nic_handle(self, suffix: str = 'FAKE') -> str: """Returns NIC Handle ID https://www.apnic.net/manage-ip/using-whois/guide/person/ @@ -600,7 +611,7 @@ def nic_handle(self, suffix='FAKE'): num = '%' * self.random_int(min=1, max=5) return self.bothify(f'{lex}{num}-{suffix}').upper() - def nic_handles(self, count=1, suffix='????'): + def nic_handles(self, count: int = 1, suffix: str = '????') -> List[str]: """Returns NIC Handle ID list :rtype: list[str] diff --git a/faker/providers/internet/el_GR/__init__.py b/faker/providers/internet/el_GR/__init__.py index ae87321b88..f7a7bc822d 100644 --- a/faker/providers/internet/el_GR/__init__.py +++ b/faker/providers/internet/el_GR/__init__.py @@ -14,12 +14,12 @@ class Provider(InternetProvider): tlds = ('com', 'com', 'com', 'net', 'org', 'gr', 'gr', 'gr') @slugify_domain - def user_name(self): - pattern = self.random_element(self.user_name_formats) + def user_name(self) -> str: + pattern: str = self.random_element(self.user_name_formats) return latinize(self.bothify(self.generator.parse(pattern))) @slugify_domain - def domain_word(self): + def domain_word(self) -> str: company = self.generator.format('company') company_elements = company.split(' ') company = latinize(company_elements.pop(0)) @@ -28,7 +28,7 @@ def domain_word(self): # ``slugify`` doesn't replace greek glyphs. -def remove_accents(value): +def remove_accents(value: str) -> str: """ Remove accents from characters in the given string. """ @@ -44,7 +44,7 @@ def replace_accented_character(match): return re.sub(r'[{}]+'.format(search), replace_accented_character, value) -def latinize(value): +def latinize(value: str) -> str: """ Converts (transliterates) greek letters to latin equivalents. """ diff --git a/faker/providers/internet/en_PH/__init__.py b/faker/providers/internet/en_PH/__init__.py index ad024c8911..8ce2d6f37a 100644 --- a/faker/providers/internet/en_PH/__init__.py +++ b/faker/providers/internet/en_PH/__init__.py @@ -33,7 +33,7 @@ class Provider(InternetProvider): @lowercase @slugify - def domain_word(self): + def domain_word(self) -> str: check = self.random_int(0, 99) if check % 100 < 40: company_acronym = self.generator.format('random_company_acronym') diff --git a/faker/providers/internet/ja_JP/__init__.py b/faker/providers/internet/ja_JP/__init__.py index 0933bab4fb..2db1ad00e0 100644 --- a/faker/providers/internet/ja_JP/__init__.py +++ b/faker/providers/internet/ja_JP/__init__.py @@ -13,5 +13,5 @@ class Provider(InternetProvider): tlds = ('com', 'com', 'com', 'net', 'org', 'jp', 'jp', 'jp') @slugify - def domain_word(self): + def domain_word(self) -> str: return self.generator.format('last_romanized_name') diff --git a/faker/providers/internet/zh_CN/__init__.py b/faker/providers/internet/zh_CN/__init__.py index 9fea88bcd6..562f5ad736 100644 --- a/faker/providers/internet/zh_CN/__init__.py +++ b/faker/providers/internet/zh_CN/__init__.py @@ -36,14 +36,14 @@ class Provider(InternetProvider): ) @slugify - def domain_word(self): - pattern = self.random_element(self.domain_formats) + def domain_word(self) -> str: + pattern: str = self.random_element(self.domain_formats) if '#' in pattern or '?' in pattern: return self.bothify(pattern) else: return self.generator.parse(pattern) - def domain_name(self, levels=1): + def domain_name(self, levels: int = 1) -> str: if levels < 1: raise ValueError("levels must be greater than or equal to 1") if levels == 1: @@ -55,7 +55,7 @@ def domain_name(self, levels=1): elif levels == 2: my_tld = self.tld() if my_tld == 'cn': - my_second_level = self.random_element(self.second_level_domains) + my_second_level: str = self.random_element(self.second_level_domains) else: my_second_level = self.domain_word() return self.domain_word() + '.' + my_second_level + '.' + my_tld diff --git a/faker/providers/isbn/__init__.py b/faker/providers/isbn/__init__.py index 1353055306..977a1b20d6 100644 --- a/faker/providers/isbn/__init__.py +++ b/faker/providers/isbn/__init__.py @@ -1,3 +1,7 @@ +from typing import List, Tuple + +from faker.providers.isbn.rules import RegistrantRule + from .. import BaseProvider from .isbn import ISBN, ISBN10, ISBN13 from .rules import RULES @@ -17,29 +21,29 @@ class Provider(BaseProvider): list of rules pertaining to each prefix/registration group. """ - def _body(self): + def _body(self) -> List[str]: """ Generate the information required to create an ISBN-10 or ISBN-13. """ - ean = self.random_element(RULES.keys()) - reg_group = self.random_element(RULES[ean].keys()) + ean: str = self.random_element(RULES.keys()) + reg_group: str = self.random_element(RULES[ean].keys()) # Given the chosen ean/group, decide how long the # registrant/publication string may be. # We must allocate for the calculated check digit, so # subtract 1 - reg_pub_len = ISBN.MAX_LENGTH - len(ean) - len(reg_group) - 1 + reg_pub_len: int = ISBN.MAX_LENGTH - len(ean) - len(reg_group) - 1 # Generate a registrant/publication combination - reg_pub = self.numerify('#' * reg_pub_len) + reg_pub: str = self.numerify('#' * reg_pub_len) # Use rules to separate the registrant from the publication - rules = RULES[ean][reg_group] + rules: List[RegistrantRule] = RULES[ean][reg_group] registrant, publication = self._registrant_publication(reg_pub, rules) return [ean, reg_group, registrant, publication] @staticmethod - def _registrant_publication(reg_pub, rules): + def _registrant_publication(reg_pub: str, rules: List[RegistrantRule]) -> Tuple[str, str]: """ Separate the registration from the publication in a given string. :param reg_pub: A string of digits representing a registration @@ -58,12 +62,12 @@ def _registrant_publication(reg_pub, rules): registrant, publication = reg_pub[:reg_len], reg_pub[reg_len:] return registrant, publication - def isbn13(self, separator='-'): + def isbn13(self, separator: str = '-') -> str: ean, group, registrant, publication = self._body() isbn = ISBN13(ean, group, registrant, publication) return isbn.format(separator) - def isbn10(self, separator='-'): + def isbn10(self, separator: str = '-') -> str: ean, group, registrant, publication = self._body() isbn = ISBN10(ean, group, registrant, publication) return isbn.format(separator) diff --git a/faker/providers/isbn/isbn.py b/faker/providers/isbn/isbn.py index 2083dc88c4..b49551e810 100644 --- a/faker/providers/isbn/isbn.py +++ b/faker/providers/isbn/isbn.py @@ -2,13 +2,18 @@ This module is responsible for generating the check digit and formatting ISBN numbers. """ +from typing import Any, Optional class ISBN: MAX_LENGTH = 13 - def __init__(self, ean=None, group=None, registrant=None, publication=None): + def __init__(self, + ean: Optional[str] = None, + group: Optional[str] = None, + registrant: Optional[str] = None, + publication: Optional[str] = None) -> None: self.ean = ean self.group = group self.registrant = registrant @@ -17,45 +22,46 @@ def __init__(self, ean=None, group=None, registrant=None, publication=None): class ISBN13(ISBN): - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self.check_digit = self._check_digit() - def _check_digit(self): + def _check_digit(self) -> str: """ Calculate the check digit for ISBN-13. See https://en.wikipedia.org/wiki/International_Standard_Book_Number for calculation. """ weights = (1 if x % 2 == 0 else 3 for x in range(12)) - body = ''.join([self.ean, self.group, self.registrant, - self.publication]) + body = ''.join([part for part in [self.ean, self.group, self.registrant, self.publication] if part is not None]) remainder = sum(int(b) * w for b, w in zip(body, weights)) % 10 diff = 10 - remainder check_digit = 0 if diff == 10 else diff return str(check_digit) - def format(self, separator=''): - return separator.join([self.ean, self.group, self.registrant, - self.publication, self.check_digit]) + def format(self, separator: str = '') -> str: + return separator.join([part for part in + [self.ean, self.group, self.registrant, self.publication, self.check_digit] + if part is not None]) class ISBN10(ISBN): - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self.check_digit = self._check_digit() - def _check_digit(self): + def _check_digit(self) -> str: """ Calculate the check digit for ISBN-10. See https://en.wikipedia.org/wiki/International_Standard_Book_Number for calculation. """ weights = range(1, 10) - body = ''.join([self.group, self.registrant, self.publication]) + body = ''.join([part for part in [self.group, self.registrant, self.publication] if part is not None]) remainder = sum(int(b) * w for b, w in zip(body, weights)) % 11 check_digit = 'X' if remainder == 10 else str(remainder) return str(check_digit) - def format(self, separator=''): - return separator.join([self.group, self.registrant, self.publication, - self.check_digit]) + def format(self, separator: str = '') -> str: + return separator.join([part for part in + [self.group, self.registrant, self.publication, self.check_digit] + if part is not None]) diff --git a/faker/providers/isbn/rules.py b/faker/providers/isbn/rules.py index 280f85a709..9e4d4a36ff 100644 --- a/faker/providers/isbn/rules.py +++ b/faker/providers/isbn/rules.py @@ -10,12 +10,13 @@ """ from collections import namedtuple +from typing import Dict, List RegistrantRule = namedtuple( 'RegistrantRule', ['min', 'max', 'registrant_length']) # Structure: RULES[`EAN Prefix`][`Registration Group`] = [Rule1, Rule2, ...] -RULES = { +RULES: Dict[str, Dict[str, List[RegistrantRule]]] = { '978': { '0': [ RegistrantRule('0000000', '1999999', 2), diff --git a/faker/providers/job/__init__.py b/faker/providers/job/__init__.py index 90db45020c..c97a9fc2bf 100644 --- a/faker/providers/job/__init__.py +++ b/faker/providers/job/__init__.py @@ -1,10 +1,10 @@ -from .. import BaseProvider +from .. import BaseProvider, ElementsType localized = True class Provider(BaseProvider): - jobs = ( + jobs: ElementsType = ( "Academic librarian", "Accommodation manager", "Accountant, chartered", @@ -646,5 +646,5 @@ class Provider(BaseProvider): "Youth worker", ) - def job(self): + def job(self) -> str: return self.random_element(self.jobs) diff --git a/faker/providers/job/hu_HU/__init__.py b/faker/providers/job/hu_HU/__init__.py index b233c7e32f..f219633e9e 100644 --- a/faker/providers/job/hu_HU/__init__.py +++ b/faker/providers/job/hu_HU/__init__.py @@ -1,4 +1,4 @@ -from .. import BaseProvider +from .. import Provider as BaseProvider class Provider(BaseProvider): @@ -413,5 +413,5 @@ class Provider(BaseProvider): 'Szerszámköszörűs', 'Építőipari szakmai irányító') - def job(self): + def job(self) -> str: return self.random_element(self.jobs) diff --git a/faker/providers/job/sk_SK/__init__.py b/faker/providers/job/sk_SK/__init__.py index 4fb402b5dd..c5b6938772 100644 --- a/faker/providers/job/sk_SK/__init__.py +++ b/faker/providers/job/sk_SK/__init__.py @@ -509,5 +509,5 @@ class Provider(JobProvider): 'Špeditér', 'Šľachtiteľ rastlín / genetik') - def job(self): + 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 42c4030f93..be4198a766 100644 --- a/faker/providers/lorem/__init__.py +++ b/faker/providers/lorem/__init__.py @@ -1,3 +1,5 @@ +from typing import List, Optional, Sequence, cast + from .. import BaseProvider localized = True @@ -21,7 +23,7 @@ class Provider(BaseProvider): word_connector = ' ' sentence_punctuation = '.' - def words(self, nb=3, ext_word_list=None, unique=False): + def words(self, nb: int = 3, ext_word_list: Optional[Sequence[str]] = None, unique: bool = False) -> List[str]: """Generate a tuple of words. The ``nb`` argument controls the number of words in the resulting list, @@ -43,12 +45,14 @@ def words(self, nb=3, ext_word_list=None, unique=False): :sample: nb=5, ext_word_list=['abc', 'def', 'ghi', 'jkl'] :sample: nb=4, ext_word_list=['abc', 'def', 'ghi', 'jkl'], unique=True """ - word_list = ext_word_list if ext_word_list else self.word_list + word_list = ext_word_list if ext_word_list else self.word_list # type: ignore[attr-defined] if unique: - return self.random_sample(word_list, length=nb) - return self.random_choices(word_list, length=nb) + unique_samples = cast(List[str], self.random_sample(word_list, length=nb)) + return unique_samples + samples = cast(List[str], self.random_choices(word_list, length=nb)) + return samples - def word(self, ext_word_list=None): + def word(self, ext_word_list: Optional[Sequence[str]] = None) -> str: """Generate a word. This method uses |words| under the hood with the ``nb`` argument set to @@ -59,7 +63,10 @@ def word(self, ext_word_list=None): """ return self.words(1, ext_word_list)[0] - def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None): + def sentence(self, + nb_words: int = 6, + variable_nb_words: bool = True, + ext_word_list: Optional[Sequence[str]] = None) -> str: """Generate a sentence. The ``nb_words`` argument controls how many words the sentence will @@ -87,7 +94,7 @@ def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None): return self.word_connector.join(words) + self.sentence_punctuation - def sentences(self, nb=3, ext_word_list=None): + def sentences(self, nb: int = 3, ext_word_list: Optional[Sequence[str]] = None) -> List[str]: """Generate a list of sentences. This method uses |sentence| under the hood to generate sentences, and @@ -104,9 +111,9 @@ def sentences(self, nb=3, ext_word_list=None): def paragraph( self, - nb_sentences=3, - variable_nb_sentences=True, - ext_word_list=None): + nb_sentences: int = 3, + variable_nb_sentences: bool = True, + ext_word_list: Optional[Sequence[str]] = None) -> str: """Generate a paragraph. The ``nb_sentences`` argument controls how many sentences the paragraph @@ -137,7 +144,7 @@ def paragraph( return para - def paragraphs(self, nb=3, ext_word_list=None): + def paragraphs(self, nb: int = 3, ext_word_list: Optional[Sequence[str]] = None) -> List[str]: """Generate a list of paragraphs. This method uses |paragraph| under the hood to generate paragraphs, and @@ -151,7 +158,7 @@ def paragraphs(self, nb=3, ext_word_list=None): return [self.paragraph(ext_word_list=ext_word_list) for _ in range(0, nb)] - def text(self, max_nb_chars=200, ext_word_list=None): + def text(self, max_nb_chars: int = 200, ext_word_list: Optional[Sequence[str]] = None) -> str: """Generate a text string. The ``max_nb_chars`` argument controls the approximate number of @@ -165,7 +172,7 @@ def text(self, max_nb_chars=200, ext_word_list=None): :sample: max_nb_chars=160 :sample: ext_word_list=['abc', 'def', 'ghi', 'jkl'] """ - text = [] + text: List[str] = [] if max_nb_chars < 5: raise ValueError( 'text() can only generate text of at least 5 characters') @@ -212,7 +219,10 @@ def text(self, max_nb_chars=200, ext_word_list=None): return "".join(text) - def texts(self, nb_texts=3, max_nb_chars=200, ext_word_list=None): + def texts(self, + nb_texts: int = 3, + max_nb_chars: int = 200, + ext_word_list: Optional[Sequence[str]] = None) -> List[str]: """Generate a list of text strings. The ``nb_texts`` argument controls how many text strings the list will diff --git a/faker/providers/lorem/en_PH/__init__.py b/faker/providers/lorem/en_PH/__init__.py index 47457721b3..f0fa7c42d1 100644 --- a/faker/providers/lorem/en_PH/__init__.py +++ b/faker/providers/lorem/en_PH/__init__.py @@ -1,3 +1,5 @@ +from typing import List + from ..en_US import Provider as EnUsProvider from ..la import Provider as LoremProvider @@ -20,11 +22,11 @@ class Provider(LoremProvider): english_word_list = EnUsProvider.word_list - def english_word(self): + def english_word(self) -> str: """Generate an English word.""" return self.word(self.english_word_list) - def english_words(self, nb=3, unique=False): + def english_words(self, nb: int = 3, unique: bool = False) -> List[str]: """Generate a list of English words. :sample: nb=5 @@ -32,7 +34,7 @@ def english_words(self, nb=3, unique=False): """ return self.words(nb, self.english_word_list, unique) - def english_sentence(self, nb_words=6, variable_nb_words=True): + def english_sentence(self, nb_words: int = 6, variable_nb_words: bool = True) -> str: """Generate a sentence in English. :sample: nb_words=10 @@ -40,14 +42,14 @@ def english_sentence(self, nb_words=6, variable_nb_words=True): """ return self.sentence(nb_words, variable_nb_words, self.english_word_list) - def english_sentences(self, nb=3): + def english_sentences(self, nb: int = 3) -> List[str]: """Generate a list of sentences in English. :sample: nb=5 """ return self.sentences(nb, self.english_word_list) - def english_paragraph(self, nb_sentences=3, variable_nb_sentences=True): + def english_paragraph(self, nb_sentences: int = 3, variable_nb_sentences: bool = True) -> str: """Generate a paragraph in English. :sample: nb_sentences=5 @@ -55,14 +57,14 @@ def english_paragraph(self, nb_sentences=3, variable_nb_sentences=True): """ return self.paragraph(nb_sentences, variable_nb_sentences, self.english_word_list) - def english_paragraphs(self, nb=3): + def english_paragraphs(self, nb: int = 3) -> List[str]: """Generate a list of paragraphs in English. :sample: nb=5 """ return self.paragraphs(nb, self.english_word_list) - def english_text(self, max_nb_chars=200): + def english_text(self, max_nb_chars: int = 200) -> str: """Generate a text string in English. :sample: max_nb_chars=20 @@ -71,7 +73,7 @@ def english_text(self, max_nb_chars=200): """ return self.text(max_nb_chars, self.english_word_list) - def english_texts(self, nb_texts=3, max_nb_chars=200): + def english_texts(self, nb_texts: int = 3, max_nb_chars: int = 200) -> List[str]: """Generate a list of text strings in English. :sample: nb_texts=5 diff --git a/faker/providers/misc/__init__.py b/faker/providers/misc/__init__.py index d657208000..c86d67bc11 100644 --- a/faker/providers/misc/__init__.py +++ b/faker/providers/misc/__init__.py @@ -8,6 +8,8 @@ import uuid import zipfile +from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Union + from faker.exceptions import UnsupportedFeature from .. import BaseProvider @@ -19,7 +21,7 @@ class Provider(BaseProvider): - def boolean(self, chance_of_getting_true=50): + def boolean(self, chance_of_getting_true: int = 50) -> bool: """Generate a random boolean value based on ``chance_of_getting_true``. :sample size=10: chance_of_getting_true=25 @@ -28,7 +30,7 @@ def boolean(self, chance_of_getting_true=50): """ return self.generator.random.randint(1, 100) <= chance_of_getting_true - def null_boolean(self): + def null_boolean(self) -> Optional[bool]: """Generate ``None``, ``True``, or ``False``, each with equal probability. :sample size=15: @@ -39,7 +41,7 @@ def null_boolean(self): -1: False, }[self.generator.random.randint(-1, 1)] - def binary(self, length=(1 * 1024 * 1024)): + def binary(self, length: int = (1 * 1024 * 1024)) -> bytes: """Generate a random binary blob of ``length`` bytes. :sample: length=64 @@ -47,7 +49,7 @@ def binary(self, length=(1 * 1024 * 1024)): blob = [self.generator.random.randrange(256) for _ in range(length)] return bytes(blob) - def md5(self, raw_output=False): + def md5(self, raw_output: bool = False) -> Union[bytes, str]: """Generate a random MD5 hash. If ``raw_output`` is ``False`` (default), a hexadecimal string representation of the MD5 hash @@ -56,12 +58,12 @@ def md5(self, raw_output=False): :sample: raw_output=False :sample: raw_output=True """ - res = hashlib.md5(str(self.generator.random.random()).encode()) + res: hashlib._Hash = hashlib.md5(str(self.generator.random.random()).encode()) if raw_output: return res.digest() return res.hexdigest() - def sha1(self, raw_output=False): + def sha1(self, raw_output: bool = False) -> Union[bytes, str]: """Generate a random SHA1 hash. If ``raw_output`` is ``False`` (default), a hexadecimal string representation of the SHA1 hash @@ -70,12 +72,12 @@ def sha1(self, raw_output=False): :sample: raw_output=False :sample: raw_output=True """ - res = hashlib.sha1(str(self.generator.random.random()).encode()) + res: hashlib._Hash = hashlib.sha1(str(self.generator.random.random()).encode()) if raw_output: return res.digest() return res.hexdigest() - def sha256(self, raw_output=False): + def sha256(self, raw_output: bool = False) -> Union[bytes, str]: """Generate a random SHA256 hash. If ``raw_output`` is ``False`` (default), a hexadecimal string representation of the SHA56 hash @@ -84,13 +86,14 @@ def sha256(self, raw_output=False): :sample: raw_output=False :sample: raw_output=True """ - res = hashlib.sha256( - str(self.generator.random.random()).encode()) + res: hashlib._Hash = hashlib.sha256(str(self.generator.random.random()).encode()) if raw_output: return res.digest() return res.hexdigest() - def uuid4(self, cast_to=str): + def uuid4(self, + cast_to: Optional[Union[Callable[[uuid.UUID], str], Callable[[uuid.UUID], bytes]]] = str, + ) -> Union[bytes, str, uuid.UUID]: """Generate a random UUID4 object and cast it to another type if specified using a callable ``cast_to``. By default, ``cast_to`` is set to ``str``. @@ -101,18 +104,17 @@ def uuid4(self, cast_to=str): :sample: cast_to=None """ # Based on http://stackoverflow.com/q/41186818 - generated_uuid = uuid.UUID(int=self.generator.random.getrandbits(128), version=4) + generated_uuid: uuid.UUID = uuid.UUID(int=self.generator.random.getrandbits(128), version=4) if cast_to is not None: - generated_uuid = cast_to(generated_uuid) + return cast_to(generated_uuid) return generated_uuid - def password( - self, - length=10, - special_chars=True, - digits=True, - upper_case=True, - lower_case=True): + def password(self, + length: int = 10, + special_chars: bool = True, + digits: bool = True, + upper_case: bool = True, + lower_case: bool = True) -> str: """Generate a random password of the specified ``length``. The arguments ``special_chars``, ``digits``, ``upper_case``, and ``lower_case`` control @@ -147,21 +149,25 @@ def password( required_tokens) <= length, "Required length is shorter than required characters" # Generate a first version of the password - chars = self.random_choices(choices, length=length) + chars: str = self.random_choices(choices, length=length) # type: ignore # Pick some unique locations - random_indexes = set() + random_indexes: Set[int] = set() while len(random_indexes) < len(required_tokens): random_indexes.add( self.generator.random.randint(0, len(chars) - 1)) # Replace them with the required characters for i, index in enumerate(random_indexes): - chars[index] = required_tokens[i] + chars[index] = required_tokens[i] # type: ignore return ''.join(chars) - def zip(self, uncompressed_size=65536, num_files=1, min_file_size=4096, compression=None): + def zip(self, + uncompressed_size: int = 65536, + num_files: int = 1, + min_file_size: int = 4096, + compression: Optional[str] = None) -> bytes: """Generate a bytes object containing a random valid zip archive file. The number and sizes of files contained inside the resulting archive can be controlled @@ -194,17 +200,17 @@ def zip(self, uncompressed_size=65536, num_files=1, min_file_size=4096, compress '`uncompressed_size` is smaller than the calculated minimum required size', ) if compression in ['bzip2', 'bz2']: - compression = zipfile.ZIP_BZIP2 + compression_ = zipfile.ZIP_BZIP2 elif compression in ['lzma', 'xz']: - compression = zipfile.ZIP_LZMA + compression_ = zipfile.ZIP_LZMA elif compression in ['deflate', 'gzip', 'gz']: - compression = zipfile.ZIP_DEFLATED + compression_ = zipfile.ZIP_DEFLATED else: - compression = zipfile.ZIP_STORED + compression_ = zipfile.ZIP_STORED zip_buffer = io.BytesIO() remaining_size = uncompressed_size - with zipfile.ZipFile(zip_buffer, mode='w', compression=compression) as zip_handle: + with zipfile.ZipFile(zip_buffer, mode='w', compression=compression_) as zip_handle: for file_number in range(1, num_files + 1): filename = self.generator.pystr() + str(file_number) @@ -219,7 +225,11 @@ def zip(self, uncompressed_size=65536, num_files=1, min_file_size=4096, compress zip_handle.writestr(filename, data) return zip_buffer.getvalue() - def tar(self, uncompressed_size=65536, num_files=1, min_file_size=4096, compression=None): + def tar(self, + uncompressed_size: int = 65536, + num_files: int = 1, + min_file_size: int = 4096, + compression: Optional[str] = None) -> bytes: """Generate a bytes object containing a random valid tar file. The number and sizes of files contained inside the resulting archive can be controlled @@ -283,7 +293,11 @@ def tar(self, uncompressed_size=65536, num_files=1, min_file_size=4096, compress file_buffer.close() return tar_buffer.getvalue() - def image(self, size=(256, 256), image_format='png', hue=None, luminosity=None): + def image(self, + size: Tuple[int, int] = (256, 256), + image_format: str = 'png', + hue: Optional[Union[int, Sequence[int], str]] = None, + luminosity: Optional[str] = None) -> bytes: """Generate an image and draw a random polygon on it using the Python Image Library. Without it installed, this provider won't be functional. Returns the bytes representing the image in a given format. @@ -323,9 +337,13 @@ def image(self, size=(256, 256), image_format='png', hue=None, luminosity=None): fobj.seek(0) return fobj.read() - def dsv(self, dialect='faker-csv', header=None, - data_columns=('{{name}}', '{{address}}'), - num_rows=10, include_row_ids=False, **fmtparams): + def dsv(self, + dialect: str = 'faker-csv', + header: Optional[Sequence[str]] = None, + data_columns: Tuple[str, str] = ('{{name}}', '{{address}}'), + num_rows: int = 10, + include_row_ids: bool = False, + **fmtparams: Any) -> str: """Generate random delimiter-separated values. This method's behavior share some similarities with ``csv.writer``. The ``dialect`` and @@ -382,7 +400,11 @@ def dsv(self, dialect='faker-csv', header=None, return dsv_buffer.getvalue() - def csv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10, include_row_ids=False): + def csv(self, + header: Optional[Sequence[str]] = None, + data_columns: Tuple[str, str] = ('{{name}}', '{{address}}'), + num_rows: int = 10, + include_row_ids: bool = False) -> str: """Generate random comma-separated values. For more information on the different arguments of this method, please refer to @@ -398,7 +420,11 @@ def csv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10 include_row_ids=include_row_ids, delimiter=',', ) - def tsv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10, include_row_ids=False): + def tsv(self, + header: Optional[Sequence[str]] = None, + data_columns: Tuple[str, str] = ('{{name}}', '{{address}}'), + num_rows: int = 10, + include_row_ids: bool = False) -> str: """Generate random tab-separated values. For more information on the different arguments of this method, please refer to @@ -414,7 +440,11 @@ def tsv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10 include_row_ids=include_row_ids, delimiter='\t', ) - def psv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10, include_row_ids=False): + def psv(self, + header: Optional[Sequence[str]] = None, + data_columns: Tuple[str, str] = ('{{name}}', '{{address}}'), + num_rows: int = 10, + include_row_ids: bool = False) -> str: """Generate random pipe-separated values. For more information on the different arguments of this method, please refer to @@ -431,7 +461,7 @@ def psv(self, header=None, data_columns=('{{name}}', '{{address}}'), num_rows=10 ) def json(self, - data_columns: list = None, + data_columns: List = None, num_rows: int = 10, indent: int = None) -> str: """ @@ -480,10 +510,10 @@ def json(self, 'name': '{{name}}', 'residency': '{{address}}', } - data_columns = data_columns if data_columns else default_data_columns + data_columns: Union[List, Dict] = data_columns if data_columns else default_data_columns - def process_list_structure(data: list) -> dict: - entry = {} + def process_list_structure(data: Sequence[Any]) -> Any: + entry: Dict[str, Any] = {} for name, definition, *arguments in data: kwargs = arguments[0] if arguments else {} @@ -503,8 +533,8 @@ def process_list_structure(data: list) -> dict: entry[name] = self._value_format_selection(definition, **kwargs) return entry - def process_dict_structure(data: dict) -> dict: - entry = {} + def process_dict_structure(data: Union[int, float, bool, Dict[str, Any]]) -> Any: + entry: Dict[str, Any] = {} if isinstance(data, str): return self._value_format_selection(data) @@ -522,7 +552,7 @@ def process_dict_structure(data: dict) -> dict: return data - def create_json_structure(data_columns) -> dict: + def create_json_structure(data_columns: Union[Dict, List]) -> dict: if isinstance(data_columns, dict): return process_dict_structure(data_columns) @@ -603,7 +633,7 @@ def fixed_width(self, data.append(''.join(row)) return '\n'.join(data) - def _value_format_selection(self, definition, **kwargs): + def _value_format_selection(self, definition: str, **kwargs: Any) -> Union[int, str]: """ Formats the string in different ways depending on it's contents. diff --git a/faker/providers/misc/en_PH/__init__.py b/faker/providers/misc/en_PH/__init__.py index a7115fe5fb..196577adf7 100644 --- a/faker/providers/misc/en_PH/__init__.py +++ b/faker/providers/misc/en_PH/__init__.py @@ -38,17 +38,17 @@ class Provider(MiscProvider): ) random_object_names = gemstone_names + mountain_names + plant_names + space_object_names - def gemstone_name(self): + def gemstone_name(self) -> str: return self.random_element(self.gemstone_names) - def mountain_name(self): + def mountain_name(self) -> str: return self.random_element(self.mountain_names) - def plant_name(self): + def plant_name(self) -> str: return self.random_element(self.plant_names) - def space_object_name(self): + def space_object_name(self) -> str: return self.random_element(self.space_object_names) - def random_object_name(self): + def random_object_name(self) -> str: return self.random_element(self.random_object_names) diff --git a/faker/providers/person/__init__.py b/faker/providers/person/__init__.py index cfb53278cc..aba3e99189 100644 --- a/faker/providers/person/__init__.py +++ b/faker/providers/person/__init__.py @@ -1,17 +1,19 @@ -from .. import BaseProvider +from typing import Sequence + +from .. import BaseProvider, ElementsType localized = True class Provider(BaseProvider): - formats = ['{{first_name}} {{last_name}}'] + formats: ElementsType = ['{{first_name}} {{last_name}}'] - first_names = ['John', 'Jane'] + first_names: ElementsType = ['John', 'Jane'] - last_names = ['Doe'] + last_names: ElementsType = ['Doe'] # https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes - language_names = [ + language_names: ElementsType = [ 'Afar', 'Abkhazian', 'Avestan', 'Afrikaans', 'Akan', 'Amharic', 'Aragonese', 'Arabic', 'Assamese', 'Avaric', 'Aymara', 'Azerbaijani', 'Bashkir', 'Belarusian', 'Bulgarian', 'Bihari languages', 'Bislama', @@ -46,129 +48,129 @@ class Provider(BaseProvider): 'Yoruba', 'Zhuang', 'Chinese', 'Zulu', ] - def name(self): + def name(self) -> str: """ :example 'John Doe' """ - pattern = self.random_element(self.formats) + pattern: str = self.random_element(self.formats) return self.generator.parse(pattern) - def first_name(self): + def first_name(self) -> str: return self.random_element(self.first_names) - def last_name(self): + def last_name(self) -> str: return self.random_element(self.last_names) - def name_male(self): + def name_male(self) -> str: if hasattr(self, 'formats_male'): - formats = self.formats_male + formats = self.formats_male # type: ignore[attr-defined] else: formats = self.formats - pattern = self.random_element(formats) + pattern: str = self.random_element(formats) return self.generator.parse(pattern) - def name_nonbinary(self): + def name_nonbinary(self) -> str: if hasattr(self, 'formats_nonbinary'): - formats = self.formats_nonbinary + formats = self.formats_nonbinary # type: ignore[attr-defined] else: formats = self.formats - pattern = self.random_element(formats) + pattern: str = self.random_element(formats) return self.generator.parse(pattern) - def name_female(self): + def name_female(self) -> str: if hasattr(self, 'formats_female'): - formats = self.formats_female + formats = self.formats_female # type: ignore[attr-defined] else: formats = self.formats - pattern = self.random_element(formats) + pattern: str = self.random_element(formats) return self.generator.parse(pattern) - def first_name_male(self): + def first_name_male(self) -> str: if hasattr(self, 'first_names_male'): - return self.random_element(self.first_names_male) + return self.random_element(self.first_names_male) # type: ignore[attr-defined] return self.first_name() - def first_name_nonbinary(self): + def first_name_nonbinary(self) -> str: if hasattr(self, 'first_names_nonbinary'): - return self.random_element(self.first_names_nonbinary) + return self.random_element(self.first_names_nonbinary) # type: ignore[attr-defined] return self.first_name() - def first_name_female(self): + def first_name_female(self) -> str: if hasattr(self, 'first_names_female'): - return self.random_element(self.first_names_female) + return self.random_element(self.first_names_female) # type: ignore[attr-defined] return self.first_name() - def last_name_male(self): + def last_name_male(self) -> str: if hasattr(self, 'last_names_male'): - return self.random_element(self.last_names_male) + return self.random_element(self.last_names_male) # type: ignore[attr-defined] return self.last_name() - def last_name_nonbinary(self): + def last_name_nonbinary(self) -> str: if hasattr(self, 'last_names_nonbinary'): - return self.random_element(self.last_names_nonbinary) + return self.random_element(self.last_names_nonbinary) # type: ignore[attr-defined] return self.last_name() - def last_name_female(self): + def last_name_female(self) -> str: if hasattr(self, 'last_names_female'): - return self.random_element(self.last_names_female) + return self.random_element(self.last_names_female) # type: ignore[attr-defined] return self.last_name() - def prefix(self): + def prefix(self) -> str: if hasattr(self, 'prefixes'): - return self.random_element(self.prefixes) + return self.random_element(self.prefixes) # type: ignore[attr-defined] if hasattr(self, 'prefixes_male') and hasattr(self, 'prefixes_female') and hasattr(self, 'prefixes_nonbinary'): - prefixes = self.random_element( - (self.prefixes_male, self.prefixes_female, self.prefixes_nonbinary)) + prefixes: Sequence[ElementsType] = self.random_element( + (self.prefixes_male, self.prefixes_female, self.prefixes_nonbinary)) # type: ignore[attr-defined] return self.random_element(prefixes) if hasattr(self, 'prefixes_male') and hasattr(self, 'prefixes_female'): prefixes = self.random_element( - (self.prefixes_male, self.prefixes_female)) + (self.prefixes_male, self.prefixes_female)) # type: ignore[attr-defined] return self.random_element(prefixes) return '' - def prefix_male(self): + def prefix_male(self) -> str: if hasattr(self, 'prefixes_male'): - return self.random_element(self.prefixes_male) + return self.random_element(self.prefixes_male) # type: ignore[attr-defined] return self.prefix() - def prefix_nonbinary(self): + def prefix_nonbinary(self) -> str: if hasattr(self, 'prefixes_nonbinary'): - return self.random_element(self.prefixes_nonbinary) + return self.random_element(self.prefixes_nonbinary) # type: ignore[attr-defined] return self.prefix() - def prefix_female(self): + def prefix_female(self) -> str: if hasattr(self, 'prefixes_female'): - return self.random_element(self.prefixes_female) + return self.random_element(self.prefixes_female) # type: ignore[attr-defined] return self.prefix() - def suffix(self): + def suffix(self) -> str: if hasattr(self, 'suffixes'): - return self.random_element(self.suffixes) + return self.random_element(self.suffixes) # type: ignore[attr-defined] if hasattr(self, 'suffixes_male') and hasattr(self, 'suffixes_female') and hasattr(self, 'suffixes_nonbinary'): - suffixes = self.random_element( - (self.suffixes_male, self.suffixes_female, self.suffixes_nonbinary)) + suffixes: Sequence[ElementsType] = self.random_element( + (self.suffixes_male, self.suffixes_female, self.suffixes_nonbinary)) # type: ignore[attr-defined] return self.random_element(suffixes) if hasattr(self, 'suffixes_male') and hasattr(self, 'suffixes_female'): suffixes = self.random_element( - (self.suffixes_male, self.suffixes_female)) + (self.suffixes_male, self.suffixes_female)) # type: ignore[attr-defined] return self.random_element(suffixes) return '' - def suffix_male(self): + def suffix_male(self) -> str: if hasattr(self, 'suffixes_male'): - return self.random_element(self.suffixes_male) + return self.random_element(self.suffixes_male) # type: ignore[attr-defined] return self.suffix() - def suffix_nonbinary(self): + def suffix_nonbinary(self) -> str: if hasattr(self, 'suffixes_nonbinary'): - return self.random_element(self.suffixes_nonbinary) + return self.random_element(self.suffixes_nonbinary) # type: ignore[attr-defined] return self.suffix() - def suffix_female(self): + def suffix_female(self) -> str: if hasattr(self, 'suffixes_female'): - return self.random_element(self.suffixes_female) + return self.random_element(self.suffixes_female) # type: ignore[attr-defined] return self.suffix() - def language_name(self): + def language_name(self) -> str: """Generate a random i18n language name (e.g. English).""" return self.random_element(self.language_names) diff --git a/faker/providers/person/ar_AA/__init__.py b/faker/providers/person/ar_AA/__init__.py index 0b2cfd2933..5151413627 100644 --- a/faker/providers/person/ar_AA/__init__.py +++ b/faker/providers/person/ar_AA/__init__.py @@ -1,20 +1,22 @@ +from typing import Tuple + from .. import Provider as PersonProvider class Provider(PersonProvider): - formats_female = ( + formats_female: Tuple[str, ...] = ( '{{first_name_female}} {{last_name}}', '{{prefix_female}} {{first_name_female}} {{last_name}}', ) - formats_male = ( + formats_male: Tuple[str, ...] = ( '{{first_name_male}} {{last_name}}', '{{prefix_male}} {{first_name_male}} {{last_name}}', ) formats = formats_male + formats_female - first_names_female = ( + first_names_female: Tuple[str, ...] = ( 'اصيل', 'آلاء', 'آيات', 'ايمان', 'بهجة', 'تمام', 'بشري', 'حياة', 'خاشعة', 'دانية', 'دعاء', 'زكية', 'نغم', 'لارا', 'زهرة', 'سبأ', 'ضحى', 'ضياء', 'عالية', 'مريم', 'فداء', 'فرات', 'فردوس', @@ -41,7 +43,7 @@ class Provider(PersonProvider): 'ريف', 'بارعة', 'باسمة', 'باهرة', 'بتول', 'بثينة', 'أحمد', ) - first_names_male = ( + first_names_male: Tuple[str, ...] = ( 'تاج', 'تامر', 'تحسين', 'تقي', 'تمّام', 'تميم', 'توفيق', 'ترف', 'تاج الدّين', 'تقيّ الدّين', 'ثائر', 'ثابت', 'ثامر', 'ثروت', 'ثقيف', 'ثاقب', 'جابر', 'جاد', 'جاسم', 'جرير', 'جسور', @@ -134,7 +136,7 @@ class Provider(PersonProvider): first_names = first_names_male + first_names_female - last_names = ( + last_names: Tuple[str, ...] = ( 'الخالدي', 'البديري', 'الشهابي', 'العفيفي', 'جزار', 'الخطيب بني جماعة الكناني', 'الدجاني', 'الغوانمة', 'جار الله', 'السروري', 'الامام', 'النقيب', 'المفتي', 'ابو السعود', @@ -190,7 +192,7 @@ class Provider(PersonProvider): 'بنو يعلى', 'يافع', 'يشكر', ) - prefixes_female = ( + prefixes_female: Tuple[str, ...] = ( 'السيدة', 'الآنسة', 'الدكتورة', 'الأستاذة', 'المهندسة', ) - prefixes_male = ('السيد', 'المهندس', 'الدكتور', 'الأستاذ') + prefixes_male: Tuple[str, ...] = ('السيد', 'المهندس', 'الدكتور', 'الأستاذ') diff --git a/faker/providers/person/en_NZ/__init__.py b/faker/providers/person/en_NZ/__init__.py index c9a6d511a9..d54f1faf72 100644 --- a/faker/providers/person/en_NZ/__init__.py +++ b/faker/providers/person/en_NZ/__init__.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from typing import Dict from .. import Provider as PersonProvider @@ -21,8 +22,8 @@ class Provider(PersonProvider): # # https://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Services-Births-Deaths-and-Marriages-Most-Popular-Male-and-Female-First-Names - first_names_male = OrderedDict(( - ("Aaron", 9912), + first_names_male: Dict[str, float] = OrderedDict(( + ("Aaron", 9912.), ("Adam", 7639), ("Adrian", 2420), ("Aidan", 1521), @@ -373,8 +374,8 @@ class Provider(PersonProvider): ("Wiremu", 1923), )) - first_names_female = OrderedDict(( - ("Aaliyah", 1042), + first_names_female: Dict[str, float] = OrderedDict(( + ("Aaliyah", 1042.), ("Abbey", 40), ("Abby", 503), ("Abigail", 2017), @@ -803,7 +804,7 @@ class Provider(PersonProvider): ("Wikitoria", 583), )) - first_names = first_names_male.copy() + first_names: Dict[str, float] = first_names_male.copy() first_names.update(first_names_female) # New Zealand surnames compiled (and cleaned up) from the following sources: @@ -812,7 +813,7 @@ class Provider(PersonProvider): # https://catalogue.data.govt.nz/dataset?q=cemetery+plots last_names = OrderedDict(( - ("Smith", 948), + ("Smith", 948.), ("Anderson", 394), ("Jones", 386), ("Taylor", 364), diff --git a/faker/providers/person/es_ES/__init__.py b/faker/providers/person/es_ES/__init__.py index e3b3843c07..1c0058c661 100644 --- a/faker/providers/person/es_ES/__init__.py +++ b/faker/providers/person/es_ES/__init__.py @@ -1,8 +1,10 @@ +from typing import Tuple + from .. import Provider as PersonProvider class Provider(PersonProvider): - formats_male = ( + formats_male: Tuple[str, ...] = ( '{{first_name_male}} {{last_name}} {{last_name}}', '{{first_name_male}} {{last_name}} {{last_name}}', '{{first_name_male}} {{last_name}} {{last_name}}', @@ -15,7 +17,7 @@ class Provider(PersonProvider): '{{first_name_male}} {{first_name_male}} {{last_name}} {{last_name}}', ) - formats_female = ( + formats_female: Tuple[str, ...] = ( '{{first_name_female}} {{last_name}} {{last_name}}', '{{first_name_female}} {{last_name}} {{last_name}}', '{{first_name_female}} {{last_name}} {{last_name}}', @@ -28,11 +30,11 @@ class Provider(PersonProvider): '{{first_name_female}} {{first_name_female}} {{last_name}} {{last_name}}', ) - formats = formats_male + formats_female + formats: Tuple[str, ...] = formats_male + formats_female # 477 male first names, alphabetically. # Source: Álvaro Mondéjar Rubio - first_names_male = ( + first_names_male: Tuple[str, ...] = ( 'Aarón', 'Abel', 'Abilio', 'Abraham', 'Adalberto', 'Adelardo', 'Adolfo', 'Adrián', 'Adán', 'Agapito', 'Agustín', 'Aitor', 'Albano', 'Albert', 'Alberto', 'Albino', 'Alcides', @@ -122,7 +124,7 @@ class Provider(PersonProvider): # 477 female first names, alphabetically. # Source: Álvaro Mondéjar Rubio - first_names_female = ( + first_names_female: Tuple[str, ...] = ( 'Abigaíl', 'Abril', 'Adela', 'Adelaida', 'Adelia', 'Adelina', 'Adora', 'Adoración', 'Adriana', 'Agustina', 'Ainara', 'Ainoa', 'Aitana', 'Alba', 'Albina', 'Ale', 'Alejandra', diff --git a/faker/providers/person/et_EE/__init__.py b/faker/providers/person/et_EE/__init__.py index eb12f294f3..1fd30e53f8 100644 --- a/faker/providers/person/et_EE/__init__.py +++ b/faker/providers/person/et_EE/__init__.py @@ -27,7 +27,7 @@ class Provider(PersonProvider): prefixes_neutral = ('doktor', 'dr', 'prof') prefixes_male = ('härra', 'hr') + prefixes_neutral prefixes_female = ('proua', 'pr') + prefixes_neutral - prefixes = set(prefixes_male + prefixes_female) + prefixes = list(set(prefixes_male + prefixes_female)) suffixes = ('PhD', 'MSc', 'BSc') @@ -64,9 +64,9 @@ class Provider(PersonProvider): first_names_rus = first_names_male_rus + first_names_female_rus - first_names_male = set(first_names_male_est + first_names_male_rus) - first_names_female = set(first_names_female_est + first_names_female_rus) - first_names = first_names_male | first_names_female + first_names_male = list(set(first_names_male_est + first_names_male_rus)) + first_names_female = list(set(first_names_female_est + first_names_female_rus)) + first_names = list(set(first_names_male) | set(first_names_female)) # http://ekspress.delfi.ee/kuum/\ # top-500-eesti-koige-levinumad-perekonnanimed?id=27677149 @@ -162,28 +162,28 @@ class Provider(PersonProvider): 'Vlassov', 'Volkov', 'Vorobjov', 'Voronin', 'Zahharov', 'Zaitsev', 'Zujev', 'Ševtšenko', 'Štšerbakov', 'Štšerbakov', 'Žukov', 'Žuravljov') - last_names = set(last_names_est + last_names_rus) + last_names = list(set(last_names_est + last_names_rus)) - def first_name_male_est(self): + def first_name_male_est(self) -> str: return self.random_element(self.first_names_male_est) - def first_name_female_est(self): + def first_name_female_est(self) -> str: return self.random_element(self.first_names_female_est) - def first_name_male_rus(self): + def first_name_male_rus(self) -> str: return self.random_element(self.first_names_male_rus) - def first_name_female_rus(self): + def first_name_female_rus(self) -> str: return self.random_element(self.first_names_female_rus) - def first_name_est(self): + def first_name_est(self) -> str: return self.random_element(self.first_names_est) - def first_name_rus(self): + def first_name_rus(self) -> str: return self.random_element(self.first_names_rus) - def last_name_est(self): + def last_name_est(self) -> str: return self.random_element(self.last_names_est) - def last_name_rus(self): + def last_name_rus(self) -> str: return self.random_element(self.last_names_rus) diff --git a/faker/providers/person/fa_IR/__init__.py b/faker/providers/person/fa_IR/__init__.py index 3eae8f37ae..5adfe6627c 100644 --- a/faker/providers/person/fa_IR/__init__.py +++ b/faker/providers/person/fa_IR/__init__.py @@ -85,5 +85,5 @@ class Provider(PersonProvider): prefixes_male = ('جناب آقای', 'جناب آقای دکتر') prefixes_female = ('سرکار خانم', 'سرکار خانم دکتر') - def suffix(self): + def suffix(self) -> str: return '' diff --git a/faker/providers/person/fr_QC/__init__.py b/faker/providers/person/fr_QC/__init__.py index 71a8be663b..fdbb90d99a 100644 --- a/faker/providers/person/fr_QC/__init__.py +++ b/faker/providers/person/fr_QC/__init__.py @@ -1,9 +1,11 @@ import warnings +from typing import Any + from ..fr_CA import Provider as FRCAProvider class Provider(FRCAProvider): - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: warnings.warn("fr_QC locale is deprecated. Please use fr_CA.") super().__init__(*args, **kwargs) diff --git a/faker/providers/person/hu_HU/__init__.py b/faker/providers/person/hu_HU/__init__.py index 295fea6223..3f35bdf9c7 100644 --- a/faker/providers/person/hu_HU/__init__.py +++ b/faker/providers/person/hu_HU/__init__.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from typing import Dict from .. import Provider as PersonProvider @@ -25,7 +26,7 @@ class Provider(PersonProvider): - formats_male = OrderedDict(( + formats_male: Dict[str, float] = OrderedDict(( ('{{last_name}} {{first_name_male}}', 0.1), ('{{last_name}} {{last_name}} {{first_name_male}}', 0.1), ('{{last_name}} {{first_name_male}} {{first_name_male}}', 0.1), @@ -38,7 +39,7 @@ class Provider(PersonProvider): ('{{prefix}} {{last_name}} {{first_name_male_abbreviated}} {{first_name_male}}', 0.05), )) - formats_female = OrderedDict(( + formats_female: Dict[str, float] = OrderedDict(( ('{{last_name}} {{first_name_female}}', 0.1), ('{{last_name}} {{last_name}} {{first_name_female}}', 0.1), ('{{last_name}} {{first_name_female}} {{first_name_female}}', 0.1), @@ -63,7 +64,7 @@ class Provider(PersonProvider): ('{{last_name}}né {{prefix}} {{last_name}} {{first_name_female}} {{first_name_female}}', 0.05), )) - formats = formats_male.copy() + formats: Dict[str, float] = formats_male.copy() formats.update(formats_female) last_names = OrderedDict(( @@ -103,7 +104,7 @@ class Provider(PersonProvider): ("Sárközi", 0.00298), )) - first_names_male = OrderedDict(( + first_names_male: Dict[str, float] = OrderedDict(( ("László", 0.06640477), ("István", 0.060906051), ("József", 0.054476881), ("János", 0.047506017), ("Zoltán", 0.045579697), ("Sándor", 0.037170944), @@ -156,7 +157,7 @@ class Provider(PersonProvider): ("Tivadar", 0.000786573), ("Henrik", 0.000758063), )) - first_names_female = OrderedDict(( + first_names_female: Dict[str, float] = OrderedDict(( ("Mária", 0.076200074), ("Erzsébet", 0.058002384), ("Katalin", 0.0429636), ("Éva", 0.039004017), ("Ilona", 0.038027669), ("Anna", 0.030819538), @@ -209,13 +210,13 @@ class Provider(PersonProvider): ("Gréta", 0.002515835), ("Rebeka", 0.002513351), )) - first_names = first_names_male.copy() + first_names: Dict[str, float] = first_names_male.copy() first_names.update(first_names_female) - prefixes = OrderedDict((("Dr.", 0.95), ("Prof. Dr.", 0.05))) + prefixes: Dict[str, float] = OrderedDict((("Dr.", 0.95), ("Prof. Dr.", 0.05))) - def first_name_male_abbreviated(self): - return self.random_element(self.first_names_male)[0] + "." + def first_name_male_abbreviated(self) -> str: + return self.random_element(self.first_names_male)[0] + "." # type: ignore - def first_name_female_abbreviated(self): - return self.random_element(self.first_names_female)[0] + "." + def first_name_female_abbreviated(self) -> str: + return self.random_element(self.first_names_female)[0] + "." # type: ignore diff --git a/faker/providers/person/it_IT/__init__.py b/faker/providers/person/it_IT/__init__.py index 6858fb147a..d0c7fa75c7 100644 --- a/faker/providers/person/it_IT/__init__.py +++ b/faker/providers/person/it_IT/__init__.py @@ -266,7 +266,7 @@ class Provider(PersonProvider): 'Zaccardo', 'Zacchia', 'Zacco', 'Zaguri', 'Zamengo', 'Zamorani', 'Zampa', 'Zanazzo', 'Zanichelli', 'Zanzi', 'Zarlino', 'Zecchini', 'Zeffirelli', 'Zetticci', 'Ziani', 'Zichichi', 'Zito', 'Zola', 'Zoppetti', 'Zoppetto', - ) + ) prefixes_female = ('Dott.', 'Sig.ra') prefixes_male = ('Dott.', 'Sig.') diff --git a/faker/providers/person/ja_JP/__init__.py b/faker/providers/person/ja_JP/__init__.py index 4db952fe3d..db783b7258 100644 --- a/faker/providers/person/ja_JP/__init__.py +++ b/faker/providers/person/ja_JP/__init__.py @@ -1,5 +1,6 @@ from collections import OrderedDict from operator import itemgetter +from typing import Tuple from .. import Provider as PersonProvider @@ -83,7 +84,7 @@ class Provider(PersonProvider): first_name_pairs = first_name_male_pairs + first_name_female_pairs last_name_pairs = OrderedDict(( - (("佐藤", "サトウ", "Sato"), 366803), + (("佐藤", "サトウ", "Sato"), 366803.), (("鈴木", "スズキ", "Suzuki"), 321135), (("高橋", "タカハシ", "Takahashi"), 266782), (("田中", "タナカ", "Tanaka"), 245821), @@ -170,140 +171,140 @@ class Provider(PersonProvider): romanized_formats = romanized_formats_male + romanized_formats_female - def first_name_pair(self): + def first_name_pair(self) -> Tuple[str, str, str]: """ @example ('明美', 'アケミ', 'Akemi') """ return self.random_element(self.first_name_pairs) - def first_name_male_pair(self): + def first_name_male_pair(self) -> Tuple[str, str, str]: """ @example ('晃', 'アキラ', 'Akira') """ return self.random_element(self.first_name_male_pairs) - def first_name_female_pair(self): + def first_name_female_pair(self) -> Tuple[str, str, str]: """ @example ('明美', 'アケミ', 'Akemi') """ return self.random_element(self.first_name_female_pairs) - def last_name_pair(self): + def last_name_pair(self) -> Tuple[str, str, str]: """ @example ('佐藤', 'サトウ', 'Sato') """ return self.random_element(self.last_name_pairs) - def first_name(self): + def first_name(self) -> str: """ @example '明美' """ return self.first_name_pair()[0] - def first_name_male(self): + def first_name_male(self) -> str: """ @example '晃' """ return self.first_name_male_pair()[0] - def first_name_female(self): + def first_name_female(self) -> str: """ @example '明美' """ return self.first_name_female_pair()[0] - def last_name(self): + def last_name(self) -> str: """ @example '佐藤' """ return self.last_name_pair()[0] - def first_kana_name(self): + def first_kana_name(self) -> str: """ @example 'アケミ' """ return self.first_name_pair()[1] - def first_kana_name_male(self): + def first_kana_name_male(self) -> str: """ @example 'アキラ' """ return self.first_name_male_pair()[1] - def first_kana_name_female(self): + def first_kana_name_female(self) -> str: """ @example 'アケミ' """ return self.first_name_female_pair()[1] - def last_kana_name(self): + def last_kana_name(self) -> str: """ @example 'サトウ' """ return self.last_name_pair()[1] - def first_romanized_name(self): + def first_romanized_name(self) -> str: """ @example 'Akemi' """ return self.first_name_pair()[2] - def first_romanized_name_male(self): + def first_romanized_name_male(self) -> str: """ @example 'Akira' """ return self.first_name_male_pair()[2] - def first_romanized_name_female(self): + def first_romanized_name_female(self) -> str: """ @example 'Akemi' """ return self.first_name_female_pair()[2] - def last_romanized_name(self): + def last_romanized_name(self) -> str: """ @example 'Sato' """ return self.last_name_pair()[2] - def kana_name(self): + def kana_name(self) -> str: """ @example 'サトウ アケミ' """ - pattern = self.random_element(self.kana_formats) + pattern: str = self.random_element(self.kana_formats) return self.generator.parse(pattern) - def kana_name_male(self): + def kana_name_male(self) -> str: """ @example 'サトウ アキラ' """ - pattern = self.random_element(self.kana_formats_male) + pattern: str = self.random_element(self.kana_formats_male) return self.generator.parse(pattern) - def kana_name_female(self): + def kana_name_female(self) -> str: """ @example 'サトウ アケミ' """ - pattern = self.random_element(self.kana_formats_female) + pattern: str = self.random_element(self.kana_formats_female) return self.generator.parse(pattern) - def romanized_name(self): + def romanized_name(self) -> str: """ @example 'Akemi Sato' """ - pattern = self.random_element(self.romanized_formats) + pattern: str = self.random_element(self.romanized_formats) return self.generator.parse(pattern) - def romanized_name_male(self): + def romanized_name_male(self) -> str: """ @example 'Akira Sato' """ - pattern = self.random_element(self.romanized_formats_male) + pattern: str = self.random_element(self.romanized_formats_male) return self.generator.parse(pattern) - def romanized_name_female(self): + def romanized_name_female(self) -> str: """ @example 'Akemi Sato' """ - pattern = self.random_element(self.romanized_formats_female) + pattern: str = self.random_element(self.romanized_formats_female) return self.generator.parse(pattern) diff --git a/faker/providers/person/ko_KR/__init__.py b/faker/providers/person/ko_KR/__init__.py index 8fc52cc1cf..32d6e6fd7c 100644 --- a/faker/providers/person/ko_KR/__init__.py +++ b/faker/providers/person/ko_KR/__init__.py @@ -16,7 +16,7 @@ class Provider(PersonProvider): # https://ko.wikipedia.org/wiki/%ED%95%9C%EA%B5%AD%EC%9D%98_%EC%84%B1%EC%94%A8%EC%99%80_%EC%9D%B4%EB%A6%84 first_names_female = OrderedDict(( - ('경숙', 1), + ('경숙', 1.), ('경자', 1), ('경희', 1), ('명숙', 1), @@ -84,7 +84,7 @@ class Provider(PersonProvider): )) first_names_male = OrderedDict(( - ('건우', 1), + ('건우', 1.), ('경수', 1), ('광수', 1), ('도윤', 1), diff --git a/faker/providers/person/or_IN/__init__.py b/faker/providers/person/or_IN/__init__.py index 8050331c68..7ea6376512 100644 --- a/faker/providers/person/or_IN/__init__.py +++ b/faker/providers/person/or_IN/__init__.py @@ -1165,8 +1165,8 @@ class Provider(PersonProvider): 'ଶ୍ରୀଯୁକ୍ତ', ) - def first_name_unisex(self): + def first_name_unisex(self) -> str: return self.random_element(self.first_names_unisex) - def middle_name(self): + def middle_name(self) -> str: return self.random_element(self.middle_names) diff --git a/faker/providers/person/pl_PL/__init__.py b/faker/providers/person/pl_PL/__init__.py index 800f76a2ad..9711772004 100644 --- a/faker/providers/person/pl_PL/__init__.py +++ b/faker/providers/person/pl_PL/__init__.py @@ -1,21 +1,17 @@ +from datetime import datetime +from typing import List, Optional, Sequence, Tuple, Union + from .. import Provider as PersonProvider -def checksum_identity_card_number(characters): +def checksum_identity_card_number(characters: Sequence[Union[str, int]]) -> int: """ Calculates and returns a control digit for given list of characters basing on Identity Card Number standards. """ weights_for_check_digit = [7, 3, 1, 0, 7, 3, 1, 7, 3] - check_digit = 0 - - for i in range(3): - check_digit += weights_for_check_digit[i] * (ord(characters[i]) - 55) - - for i in range(4, 9): - check_digit += weights_for_check_digit[i] * characters[i] - - check_digit %= 10 - + integer_characters = [(ord(character) - 55) if isinstance(character, str) else character + for character in characters] + check_digit = sum(weight * ch for weight, ch in zip(weights_for_check_digit, integer_characters)) % 10 return check_digit @@ -31,7 +27,7 @@ class Provider(PersonProvider): '{{prefix_male}} {{first_name_male}} {{last_name_male}}', ) - first_names_male = ( + first_names_male: Tuple[str, ...] = ( 'Jakub', 'Jan', 'Mateusz', @@ -133,7 +129,7 @@ class Provider(PersonProvider): 'Ernest', 'Tobiasz') - first_names_female = ( + first_names_female: Tuple[str, ...] = ( 'Kamila', 'Ewa', 'Blanka', @@ -188,7 +184,7 @@ class Provider(PersonProvider): 'Tola', 'Gaja') - unisex_last_names = ( + unisex_last_names: Tuple[str, ...] = ( 'Wandzel', 'Pajda', 'Dzienis', 'Borysewicz', 'Szlaga', 'Krzysiek', 'Iwańczyk', 'Cierpisz', 'Borczyk', 'Szymula', 'Pietrasiak', 'Minkiewicz', 'Hojka', 'Goral', 'Staś', 'Smoter', 'Bosek', 'Bitner', 'Kondej', 'Furgał', 'Durlik', 'Kusa', 'Pacewicz', 'Masiak', 'Kucz', @@ -637,7 +633,7 @@ class Provider(PersonProvider): 'Płocharczyk', 'Ostręga', 'Łęgowik', 'Ludwik', 'Kopik', 'Kleinschmidt', 'Karczmarek', 'Gładka', 'Czylok', 'Wawrzynkiewicz', ) - male_last_names = ( + male_last_names: Tuple[str, ...] = ( 'Kowalski', 'Wiśniewski', 'Dąbrowski', 'Lewandowski', 'Wójcik', 'Kamiński', 'Kowalczyk', 'Zieliński', 'Szymański', 'Woźniak', 'Kozłowski', 'Jankowski', 'Wojciechowski', 'Kwiatkowski', 'Kaczmarek', 'Mazur', 'Krawczyk', 'Piotrowski', 'Grabowski', 'Nowakowski', @@ -668,15 +664,15 @@ class Provider(PersonProvider): 'Bukowski', 'Leśniak', ) - prefixes_male = ('pan',) - prefixes_female = ('pani',) + prefixes_male: Tuple[str, ...] = ('pan',) + prefixes_female: Tuple[str, ...] = ('pani',) first_names = first_names_male + first_names_female - def last_name(self): + def last_name(self) -> str: return self.random_element(self.unisex_last_names) - def identity_card_number(self): + def identity_card_number(self) -> str: """ Returns 9 character Polish Identity Card Number, Polish: Numer Dowodu Osobistego. @@ -686,7 +682,7 @@ def identity_card_number(self): https://en.wikipedia.org/wiki/Polish_identity_card """ - identity = [] + identity: List[Union[int, str]] = [] for _ in range(3): identity.append(self.random_letter().upper()) @@ -702,11 +698,11 @@ def identity_card_number(self): return ''.join(str(character) for character in identity) @staticmethod - def pesel_compute_check_digit(pesel): + def pesel_compute_check_digit(pesel: str) -> int: checksum_values = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7] return sum(int(a) * b for a, b in zip(pesel, checksum_values)) % 10 - def pesel(self, date_of_birth=None, sex=None): + def pesel(self, date_of_birth: Optional[datetime] = None, sex: Optional[str] = None) -> str: """ Returns 11 characters of Universal Electronic System for Registration of the Population. Polish: Powszechny Elektroniczny System Ewidencji Ludności. @@ -754,10 +750,10 @@ def pesel(self, date_of_birth=None, sex=None): return pesel @staticmethod - def pwz_doctor_compute_check_digit(x): + def pwz_doctor_compute_check_digit(x: Sequence[int]) -> int: return sum((i + 1) * d for i, d in enumerate(x)) % 11 - def pwz_doctor(self): + def pwz_doctor(self) -> str: """ Function generates an identification number for medical doctors Polish: Prawo Wykonywania Zawodu (PWZ) @@ -773,7 +769,7 @@ def pwz_doctor(self): return f'{check_digit}{"".join(map(str, core))}' - def pwz_nurse(self, kind='nurse'): + def pwz_nurse(self, kind: str = 'nurse') -> str: """ Function generates an identification number for nurses and midwives Polish: Prawo Wykonywania Zawodu (PWZ) @@ -789,7 +785,7 @@ def pwz_nurse(self, kind='nurse'): return f'{region:02d}{"".join(map(str, core))}{kind_char}' - tax_office_codes = ( + tax_office_codes: Tuple[str, ...] = ( '101', '102', '103', '104', '105', '106', '107', '108', '109', '111', '112', '113', '114', '115', '116', '117', '118', '119', '121', '122', '123', '124', '125', '126', '127', '128', '129', '131', '132', '133', '134', '135', '136', '137', '138', '139', '141', '142', '143', '144', '145', '146', '147', '148', '149', '151', '152', '153', @@ -840,7 +836,7 @@ def pwz_nurse(self, kind='nurse'): '987', '988', '989', '991', '992', '993', '994', '995', '996', '997', '998', ) - def nip(self): + def nip(self) -> str: """ Returns 10 digit of Number of tax identification. Polish: Numer identyfikacji podatkowej (NIP). @@ -851,7 +847,7 @@ def nip(self): """ - nip = [int(i) for i in self.random_element(self.tax_office_codes)] + nip = [int(i) for i in self.random_element(self.tax_office_codes)] # type: ignore for _ in range(6): nip.append(self.random_digit()) diff --git a/faker/providers/person/pt_PT/__init__.py b/faker/providers/person/pt_PT/__init__.py index 66709c83f6..117792d0bd 100644 --- a/faker/providers/person/pt_PT/__init__.py +++ b/faker/providers/person/pt_PT/__init__.py @@ -87,5 +87,5 @@ class Provider(PersonProvider): prefixes = ('de', 'da', 'do') - def prefix(self): + def prefix(self) -> str: return self.random_element(self.prefixes) diff --git a/faker/providers/person/ru_RU/__init__.py b/faker/providers/person/ru_RU/__init__.py index 0d430e1a06..fd1a751dda 100644 --- a/faker/providers/person/ru_RU/__init__.py +++ b/faker/providers/person/ru_RU/__init__.py @@ -1,18 +1,19 @@ from collections import OrderedDict +from typing import Dict, Sequence from .. import Provider as PersonProvider # See transliteration table https://en.wikipedia.org/wiki/Romanization_of_Russian#Transliteration_table -def translit(text): - translit_dict = { - 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'y', - 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', - 'х': 'kh', 'ц': 'ts', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch', 'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', - 'я': 'ya', 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'Ye', 'Ë': 'E', 'Ж': 'Zh', 'З': 'Z', 'И': 'I', - 'Й': 'Y', 'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', - 'Ф': 'F', 'Х': 'Kh', 'Ц': 'Ts', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Shch', 'Ы': 'Y', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya', - } +def translit(text: str) -> str: + translit_dict: Dict[str, str] = { + 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'y', + 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', + 'х': 'kh', 'ц': 'ts', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch', 'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', + 'я': 'ya', 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'Ye', 'Ë': 'E', 'Ж': 'Zh', 'З': 'Z', 'И': 'I', + 'Й': 'Y', 'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', + 'Ф': 'F', 'Х': 'Kh', 'Ц': 'Ts', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Shch', 'Ы': 'Y', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya', + } for letter in text: if letter.isalpha(): text = text.replace(letter, translit_dict[letter]) @@ -20,13 +21,13 @@ def translit(text): class Provider(PersonProvider): - formats_male = OrderedDict(( + formats_male: Dict[str, float] = OrderedDict(( ('{{last_name_male}} {{first_name_male}} {{middle_name_male}}', 0.49), ('{{first_name_male}} {{middle_name_male}} {{last_name_male}}', 0.49), ('{{prefix_male}} {{last_name_male}} {{first_name_male}} {{middle_name_male}}', 0.02), )) - formats_female = OrderedDict(( + formats_female: Dict[str, float] = OrderedDict(( ('{{last_name_female}} {{first_name_female}} {{middle_name_female}}', 0.49), ('{{first_name_female}} {{middle_name_female}} {{last_name_female}}', 0.49), ('{{prefix_female}} {{last_name_female}} {{first_name_female}} {{middle_name_female}}', 0.02), @@ -36,7 +37,7 @@ class Provider(PersonProvider): # formats = formats_male + formats_female # has to be replaced with something dict and python 2.x compatible - formats = formats_male.copy() + formats: Dict[str, float] = formats_male.copy() formats.update(formats_female) first_names_male = ( @@ -301,15 +302,15 @@ class Provider(PersonProvider): 'Вьетнамский', 'Идиш', 'Йоруба', 'Китайский', 'Зулу', ) - prefixes_male = ('г-н', 'тов.') + prefixes_male: Sequence[str] = ('г-н', 'тов.') - prefixes_female = ('г-жа', 'тов.') + prefixes_female: Sequence[str] = ('г-жа', 'тов.') - def middle_name(self): + def middle_name(self) -> str: return self.random_element(self.middle_names) - def middle_name_male(self): + def middle_name_male(self) -> str: return self.random_element(self.middle_names_male) - def middle_name_female(self): + def middle_name_female(self) -> str: return self.random_element(self.middle_names_female) diff --git a/faker/providers/person/zh_CN/__init__.py b/faker/providers/person/zh_CN/__init__.py index 84aa2f7d62..b6ef01c60e 100644 --- a/faker/providers/person/zh_CN/__init__.py +++ b/faker/providers/person/zh_CN/__init__.py @@ -475,20 +475,20 @@ class Provider(PersonProvider): 'Zhou', 'Zhu', 'Zou', ) - def romanized_name(self): + def romanized_name(self) -> str: ''' @example 'Chao Bai' ''' - pattern = self.random_element(self.romanized_formats) + pattern: str = self.random_element(self.romanized_formats) return self.generator.parse(pattern) - def first_romanized_name(self): + def first_romanized_name(self) -> str: ''' @example 'Chao' ''' return self.random_element(self.first_romanized_names) - def last_romanized_name(self): + def last_romanized_name(self) -> str: ''' @example 'Chao' ''' diff --git a/faker/providers/person/zh_TW/__init__.py b/faker/providers/person/zh_TW/__init__.py index 73922780fa..d098567c91 100644 --- a/faker/providers/person/zh_TW/__init__.py +++ b/faker/providers/person/zh_TW/__init__.py @@ -473,20 +473,20 @@ class Provider(PersonProvider): 'Zhou', 'Zhu', 'Zou', ) - def romanized_name(self): + def romanized_name(self) -> str: ''' @example 'Chao Bai' ''' - pattern = self.random_element(self.romanized_formats) + pattern: str = self.random_element(self.romanized_formats) return self.generator.parse(pattern) - def first_romanized_name(self): + def first_romanized_name(self) -> str: ''' @example 'Chao' ''' return self.random_element(self.first_romanized_names) - def last_romanized_name(self): + def last_romanized_name(self) -> str: ''' @example 'Chao' ''' diff --git a/faker/providers/phone_number/__init__.py b/faker/providers/phone_number/__init__.py index 6e812435bc..f9d079edca 100644 --- a/faker/providers/phone_number/__init__.py +++ b/faker/providers/phone_number/__init__.py @@ -1,4 +1,4 @@ -from .. import BaseProvider +from .. import BaseProvider, ElementsType # Data source # @@ -13,7 +13,7 @@ class Provider(BaseProvider): - country_calling_codes = ( + country_calling_codes: ElementsType = ( '+93', '+358 18', '+355', '+213', '+1 684', '+376', '+244', '+1 264', '+1 268', '+54', '+374', '+297', '+247', '+61', '+672 1', '+672', '+43', '+994', '+1 242', '+973', '+880', '+1 246', '+1 268', '+375', '+32', @@ -54,18 +54,18 @@ class Provider(BaseProvider): '+260', '+255 24', '+263', ) - formats = ('###-###-###',) + formats: ElementsType = ('###-###-###',) - msisdn_formats = ( + msisdn_formats: ElementsType = ( '#############', ) - def phone_number(self): + def phone_number(self) -> str: return self.numerify(self.random_element(self.formats)) - def country_calling_code(self): + def country_calling_code(self) -> str: return self.random_element(self.country_calling_codes) - def msisdn(self): + def msisdn(self) -> str: """ https://en.wikipedia.org/wiki/MSISDN """ return self.numerify(self.random_element(self.msisdn_formats)) diff --git a/faker/providers/phone_number/ar_AE/__init__.py b/faker/providers/phone_number/ar_AE/__init__.py index 0a3f04b92b..16c9a8ff93 100644 --- a/faker/providers/phone_number/ar_AE/__init__.py +++ b/faker/providers/phone_number/ar_AE/__init__.py @@ -43,7 +43,7 @@ class Provider(PhoneNumberProvider): services_phones_formats + \ toll_formats - def cellphone_provider_code(self): + def cellphone_provider_code(self) -> str: return self.random_element([ '50', '52', @@ -53,7 +53,7 @@ def cellphone_provider_code(self): '58', ]) - def telephone_provider_code(self): + def telephone_provider_code(self) -> str: return self.random_element([ '1', '2', @@ -64,28 +64,28 @@ def telephone_provider_code(self): '9', ]) - def area_code(self): + def area_code(self) -> str: return self.random_element([ '00971', '+971', ]) - def cellphone_number(self): - pattern = self.random_element(self.cellphone_formats) + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) return self.numerify(self.generator.parse(pattern)) - def telephone_number(self): - pattern = self.random_element(self.telephone_formats) + def telephone_number(self) -> str: + pattern: str = self.random_element(self.telephone_formats) return self.numerify(self.generator.parse(pattern)) - def service_phone_number(self): - pattern = self.random_element(self.services_phones_formats) + def service_phone_number(self) -> str: + pattern: str = self.random_element(self.services_phones_formats) return self.numerify(self.generator.parse(pattern)) - def toll_number(self): - pattern = self.random_element(self.toll_formats) + def toll_number(self) -> str: + pattern: str = self.random_element(self.toll_formats) return self.numerify(self.generator.parse(pattern)) - def phone_number(self): - pattern = self.random_element(self.formats) + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/ar_JO/__init__.py b/faker/providers/phone_number/ar_JO/__init__.py index 095e624f52..0b32ea1f8b 100644 --- a/faker/providers/phone_number/ar_JO/__init__.py +++ b/faker/providers/phone_number/ar_JO/__init__.py @@ -29,7 +29,7 @@ class Provider(PhoneNumberProvider): telephone_formats + \ services_phones_formats - def operator_id(self): + def operator_id(self) -> str: return self.random_element([ '4', '7', @@ -37,7 +37,7 @@ def operator_id(self): '9', ]) - def area_code(self): + def area_code(self) -> str: return self.random_element([ '2', '3', @@ -46,18 +46,18 @@ def area_code(self): '7', ]) - def cellphone_number(self): - pattern = self.random_element(self.cellphone_formats) + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) return self.numerify(self.generator.parse(pattern)) - def telephone_number(self): - pattern = self.random_element(self.telephone_formats) + def telephone_number(self) -> str: + pattern: str = self.random_element(self.telephone_formats) return self.numerify(self.generator.parse(pattern)) - def service_phone_number(self): - pattern = self.random_element(self.services_phones_formats) + def service_phone_number(self) -> str: + pattern: str = self.random_element(self.services_phones_formats) return self.numerify(self.generator.parse(pattern)) - def phone_number(self): - pattern = self.random_element(self.formats) + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/ar_PS/__init__.py b/faker/providers/phone_number/ar_PS/__init__.py index dca200dd5e..ce235d4644 100644 --- a/faker/providers/phone_number/ar_PS/__init__.py +++ b/faker/providers/phone_number/ar_PS/__init__.py @@ -108,13 +108,13 @@ class Provider(PhoneNumberProvider): services_phones_formats + \ toll_formats - def provider_code(self): + def provider_code(self) -> str: return self.random_element([ '59', '56', ]) - def area_code(self): + def area_code(self) -> str: return self.random_element([ '00972', '+972', @@ -122,22 +122,22 @@ def area_code(self): '+970', ]) - def cellphone_number(self): - pattern = self.random_element(self.cellphone_formats) + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) return self.numerify(self.generator.parse(pattern)) - def telephone_number(self): - pattern = self.random_element(self.telephone_formats) + def telephone_number(self) -> str: + pattern: str = self.random_element(self.telephone_formats) return self.numerify(self.generator.parse(pattern)) - def service_phone_number(self): - pattern = self.random_element(self.services_phones_formats) + def service_phone_number(self) -> str: + pattern: str = self.random_element(self.services_phones_formats) return self.numerify(self.generator.parse(pattern)) - def toll_number(self): - pattern = self.random_element(self.toll_formats) + def toll_number(self) -> str: + pattern: str = self.random_element(self.toll_formats) return self.numerify(self.generator.parse(pattern)) - def phone_number(self): - pattern = self.random_element(self.formats) + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/en_AU/__init__.py b/faker/providers/phone_number/en_AU/__init__.py index 44af690e59..2468e0f8f2 100644 --- a/faker/providers/phone_number/en_AU/__init__.py +++ b/faker/providers/phone_number/en_AU/__init__.py @@ -33,13 +33,13 @@ class Provider(PhoneNumberProvider): '+61.4##.###.###', ) - def area_code(self): + def area_code(self) -> str: return self.numerify(self.random_element( ['2', '3', '7', '8'])) - def phone_number(self): - pattern = self.random_element(self.formats) + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/en_GB/__init__.py b/faker/providers/phone_number/en_GB/__init__.py index 3b4805b6a5..b13fc2a054 100644 --- a/faker/providers/phone_number/en_GB/__init__.py +++ b/faker/providers/phone_number/en_GB/__init__.py @@ -262,6 +262,6 @@ class Provider(PhoneNumberProvider): '+44(0)9098790###', ) - def cellphone_number(self): - pattern = self.random_element(self.cellphone_formats) + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/en_NZ/__init__.py b/faker/providers/phone_number/en_NZ/__init__.py index 4436c0acbe..5f3ca0e621 100644 --- a/faker/providers/phone_number/en_NZ/__init__.py +++ b/faker/providers/phone_number/en_NZ/__init__.py @@ -39,9 +39,9 @@ class Provider(PhoneNumberProvider): '9', # Auckland ] - def area_code(self): + def area_code(self) -> str: return self.numerify(self.random_element(self.area_codes)) - def phone_number(self): - pattern = self.random_element(self.formats) + def phone_number(self) -> str: + pattern: str = self.random_element(self.formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/en_PH/__init__.py b/faker/providers/phone_number/en_PH/__init__.py index 0b9ca3782e..f20e83fa47 100644 --- a/faker/providers/phone_number/en_PH/__init__.py +++ b/faker/providers/phone_number/en_PH/__init__.py @@ -1,3 +1,5 @@ +from typing import Sequence, Tuple + from ... import BaseProvider @@ -30,124 +32,126 @@ class Provider(BaseProvider): - https://powerpinoys.com/network-prefixes-philippines/ """ - globe_mobile_number_prefixes = ( + globe_mobile_number_prefixes: Tuple[str, ...] = ( '817', '904', '905', '906', '915', '916', '917', '926', '927', '935', '936', '937', '945', '955', '956', '965', '966', '967', '973', '975', '976', '977', '978', '979', '994', '995', '996', '997', ) - smart_mobile_number_prefixes = ( + smart_mobile_number_prefixes: Tuple[str, ...] = ( '813', '907', '908', '909', '910', '911', '912', '913', '914', '918', '919', '920', '921', '928', '929', '930', '938', '939', '940', '946', '947', '948', '949', '950', '951', '961', '970', '981', '989', '992', '998', '999', ) - sun_mobile_number_prefixes = ( + sun_mobile_number_prefixes: Tuple[str, ...] = ( '922', '923', '924', '925', '931', '932', '933', '934', '941', '942', '943', '944', ) - globe_mobile_number_formats = ( + globe_mobile_number_formats: Tuple[str, ...] = ( '0{{globe_mobile_number_prefix}}-###-####', '+63{{globe_mobile_number_prefix}}-###-####', ) - smart_mobile_number_formats = ( + smart_mobile_number_formats: Tuple[str, ...] = ( '0{{smart_mobile_number_prefix}}-###-####', '+63{{smart_mobile_number_prefix}}-###-####', ) - sun_mobile_number_formats = ( + sun_mobile_number_formats: Tuple[str, ...] = ( '0{{sun_mobile_number_prefix}}-###-####', '+63{{sun_mobile_number_prefix}}-###-####', ) - mobile_number_formats = globe_mobile_number_formats + smart_mobile_number_formats + sun_mobile_number_formats + mobile_number_formats: Tuple[str, ...] = globe_mobile_number_formats + smart_mobile_number_formats + \ + sun_mobile_number_formats - bayantel_landline_identifiers = tuple(str(x) for x in range(3000, 3500)) - misc_landline_identifiers = tuple(str(x) for x in range(5300, 5800)) + tuple(str(x) for x in range(6000, 6700)) - non_area2_landline_area_codes = ( + bayantel_landline_identifiers: Tuple[str, ...] = tuple(str(x) for x in range(3000, 3500)) + misc_landline_identifiers: Tuple[str, ...] = tuple(str(x) for x in range(5300, 5800)) + \ + tuple(str(x) for x in range(6000, 6700)) + non_area2_landline_area_codes: Tuple[str, ...] = ( '32', '33', '34', '35', '36', '38', '42', '43', '44', '45', '46', '47', '48', '49', '52', '53', '54', '55', '56', '62', '63', '64', '65', '68', '72', '74', '75', '77', '78', '82', '83', '84', '85', '86', '87', '88', ) - globe_area2_landline_number_formats = ( + globe_area2_landline_number_formats: Tuple[str, ...] = ( '02-7###-####', '+632-7###-####', ) - pldt_area2_landline_number_formats = ( + pldt_area2_landline_number_formats: Tuple[str, ...] = ( '02-8###-####', '+632-8###-####', ) - bayantel_area2_landline_number_formats = ( + bayantel_area2_landline_number_formats: Tuple[str, ...] = ( '02-{{bayantel_landline_identifier}}-####', '+632-{{bayantel_landline_identifier}}-####', ) - misc_area2_landline_number_formats = ( + misc_area2_landline_number_formats: Tuple[str, ...] = ( '02-{{misc_landline_identifier}}-####', '+632-{{misc_landline_identifier}}-####', ) - area2_landline_number_formats = ( - globe_area2_landline_number_formats - + pldt_area2_landline_number_formats - + bayantel_area2_landline_number_formats - + misc_area2_landline_number_formats + area2_landline_number_formats: Tuple[str, ...] = ( + globe_area2_landline_number_formats + + pldt_area2_landline_number_formats + + bayantel_area2_landline_number_formats + + misc_area2_landline_number_formats ) - non_area2_landline_number_formats = ( + non_area2_landline_number_formats: Tuple[str, ...] = ( '0{{non_area2_landline_area_code}}-###-####', '+63{{non_area2_landline_area_code}}-###-####', ) - landline_number_formats = area2_landline_number_formats + non_area2_landline_number_formats + landline_number_formats: Tuple[str, ...] = area2_landline_number_formats + non_area2_landline_number_formats - def _create_phone_number(self, formats): - pattern = self.random_element(formats) + def _create_phone_number(self, formats: Sequence[str]) -> str: + pattern: str = self.random_element(formats) return self.numerify(self.generator.parse(pattern)) - def globe_mobile_number_prefix(self): + def globe_mobile_number_prefix(self) -> str: return self.random_element(self.globe_mobile_number_prefixes) - def smart_mobile_number_prefix(self): + def smart_mobile_number_prefix(self) -> str: return self.random_element(self.smart_mobile_number_prefixes) - def sun_mobile_number_prefix(self): + def sun_mobile_number_prefix(self) -> str: return self.random_element(self.sun_mobile_number_prefixes) - def bayantel_landline_identifier(self): + def bayantel_landline_identifier(self) -> str: return self.random_element(self.bayantel_landline_identifiers) - def misc_landline_identifier(self): + def misc_landline_identifier(self) -> str: return self.random_element(self.misc_landline_identifiers) - def non_area2_landline_area_code(self): + def non_area2_landline_area_code(self) -> str: return self.random_element(self.non_area2_landline_area_codes) - def globe_mobile_number(self): + def globe_mobile_number(self) -> str: return self._create_phone_number(self.globe_mobile_number_formats) - def smart_mobile_number(self): + def smart_mobile_number(self) -> str: return self._create_phone_number(self.smart_mobile_number_formats) - def sun_mobile_number(self): + def sun_mobile_number(self) -> str: return self._create_phone_number(self.sun_mobile_number_formats) - def mobile_number(self): + def mobile_number(self) -> str: return self._create_phone_number(self.mobile_number_formats) - def globe_area2_landline_number(self): + def globe_area2_landline_number(self) -> str: return self._create_phone_number(self.globe_area2_landline_number_formats) - def pldt_area2_landline_number(self): + def pldt_area2_landline_number(self) -> str: return self._create_phone_number(self.pldt_area2_landline_number_formats) - def bayantel_area2_landline_number(self): + def bayantel_area2_landline_number(self) -> str: return self._create_phone_number(self.bayantel_area2_landline_number_formats) - def misc_area2_landline_number(self): + def misc_area2_landline_number(self) -> str: return self._create_phone_number(self.misc_area2_landline_number_formats) - def area2_landline_number(self): + def area2_landline_number(self) -> str: return self._create_phone_number(self.area2_landline_number_formats) - def non_area2_landline_number(self): + def non_area2_landline_number(self) -> str: return self._create_phone_number(self.non_area2_landline_number_formats) - def landline_number(self): + def landline_number(self) -> str: return self._create_phone_number(self.landline_number_formats) diff --git a/faker/providers/phone_number/pt_BR/__init__.py b/faker/providers/phone_number/pt_BR/__init__.py index 2097f2ff6a..b7b9654c35 100644 --- a/faker/providers/phone_number/pt_BR/__init__.py +++ b/faker/providers/phone_number/pt_BR/__init__.py @@ -131,10 +131,10 @@ class Provider(PhoneNumberProvider): '199', ) - def cellphone_number(self): - pattern = self.random_element(self.cellphone_formats) + def cellphone_number(self) -> str: + pattern: str = self.random_element(self.cellphone_formats) return self.numerify(self.generator.parse(pattern)) - def service_phone_number(self): - pattern = self.random_element(self.services_phones_formats) + def service_phone_number(self) -> str: + pattern: str = self.random_element(self.services_phones_formats) return self.numerify(self.generator.parse(pattern)) diff --git a/faker/providers/phone_number/zh_CN/__init__.py b/faker/providers/phone_number/zh_CN/__init__.py index 94533fd9d2..440683a76d 100644 --- a/faker/providers/phone_number/zh_CN/__init__.py +++ b/faker/providers/phone_number/zh_CN/__init__.py @@ -8,5 +8,5 @@ class Provider(PhoneNumberProvider): 145, 133, 153, 180, 181, 189] formats = [str(i) + "########" for i in phonenumber_prefixes] - def phonenumber_prefix(self): + def phonenumber_prefix(self) -> int: return self.random_element(self.phonenumber_prefixes) diff --git a/faker/providers/profile/__init__.py b/faker/providers/profile/__init__.py index 59897baead..eeb697352d 100644 --- a/faker/providers/profile/__init__.py +++ b/faker/providers/profile/__init__.py @@ -1,5 +1,10 @@ import itertools +from datetime import date +from decimal import Decimal +from typing import Dict, List, Optional, Tuple, Union + +from ...typing import GenderType from .. import BaseProvider @@ -9,27 +14,27 @@ class Provider(BaseProvider): """ - def simple_profile(self, sex=None): + def simple_profile(self, sex: Optional[GenderType] = None) -> Dict[str, Union[str, date, GenderType]]: """ Generates a basic profile with personal informations """ - SEX = ["F", "M"] - if sex not in SEX: - sex = self.random_element(SEX) - if sex == 'F': + sex_ = self.random_element(['F', 'M']) if sex is None else sex + if sex_ == 'F': name = self.generator.name_female() - elif sex == 'M': + elif sex_ == 'M': name = self.generator.name_male() return { "username": self.generator.user_name(), "name": name, - "sex": sex, + "sex": sex_, "address": self.generator.address(), "mail": self.generator.free_email(), "birthdate": self.generator.date_of_birth(), } - def profile(self, fields=None, sex=None): + def profile(self, + fields: Optional[List[str]] = None, + sex: Optional[GenderType] = None) -> Dict[str, Union[str, Tuple[Decimal, Decimal], List[str], date]]: """ Generates a complete profile. If "fields" is not empty, only the fields in the list will be returned diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py index edb43e915a..8124575503 100644 --- a/faker/providers/python/__init__.py +++ b/faker/providers/python/__init__.py @@ -4,17 +4,20 @@ import warnings from decimal import Decimal +from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Union, no_type_check -from .. import BaseProvider +from .. import BaseProvider, ElementsType + +ValueTypes = Optional[Union[List[str], Tuple[str, ...]]] class Provider(BaseProvider): - default_value_types = ( + default_value_types: ElementsType = ( 'str', 'str', 'str', 'str', 'float', 'int', 'int', 'decimal', 'date_time', 'uri', 'email', ) - def _check_signature(self, value_types, allowed_types): + def _check_signature(self, value_types: ValueTypes, allowed_types: Tuple[str]) -> Tuple[str, ...]: if value_types is not None and not isinstance(value_types, (list, tuple)): value_types = [value_types] warnings.warn( @@ -233,18 +236,19 @@ def pylist(self, nb_elements=10, variable_nb_elements=True, value_types=None, *a value_types, *allowed_types)) + @no_type_check def pyiterable( self, - nb_elements=10, - variable_nb_elements=True, - value_types=None, - *allowed_types): + nb_elements: int = 10, + variable_nb_elements: bool = True, + value_types: ValueTypes = None, + *allowed_types: str) -> Iterable[Any]: value_types = self._check_signature(value_types, allowed_types) return self.random_element([self.pylist, self.pytuple, self.pyset])( nb_elements, variable_nb_elements, value_types, *allowed_types) - def _random_type(self, type_list): - value_type = self.random_element(type_list) + def _random_type(self, type_list: List[str]) -> str: + value_type: str = self.random_element(type_list) method_name = f'py{value_type}' if hasattr(self, method_name): @@ -254,19 +258,19 @@ def _random_type(self, type_list): def _pyiterable( self, - nb_elements=10, - variable_nb_elements=True, - value_types=None, - *allowed_types): + nb_elements: int = 10, + variable_nb_elements: bool = True, + value_types: ValueTypes = None, + *allowed_types: str) -> Iterator: - value_types = self._check_signature(value_types, allowed_types) + value_types = self._check_signature(value_types, allowed_types) # type: ignore value_types = [t if isinstance(t, str) else getattr(t, '__name__', type(t).__name__).lower() for t in value_types # avoid recursion if t not in ['iterable', 'list', 'tuple', 'dict', 'set']] if not value_types: - value_types = self.default_value_types + value_types = self.default_value_types # type: ignore if variable_nb_elements: nb_elements = self.randomize_nb_elements(nb_elements, min=1) @@ -290,15 +294,15 @@ def pydict(self, nb_elements=10, variable_nb_elements=True, value_types=None, *a self._pyiterable(nb_elements, False, value_types, *allowed_types), )) - def pystruct(self, count=10, value_types=None, *allowed_types): - value_types = self._check_signature(value_types, allowed_types) + def pystruct(self, count: int = 10, value_types: ValueTypes = None, *allowed_types: str) -> Tuple[List, Dict, Dict]: + value_types = self._check_signature(value_types, allowed_types) # type: ignore value_types = [t if isinstance(t, str) else getattr(t, '__name__', type(t).__name__).lower() for t in value_types # avoid recursion if t != 'struct'] if not value_types: - value_types = self.default_value_types + value_types = self.default_value_types # type: ignore types = [] d = {} diff --git a/faker/providers/ssn/__init__.py b/faker/providers/ssn/__init__.py index 6e47c21af0..8d6465af8c 100644 --- a/faker/providers/ssn/__init__.py +++ b/faker/providers/ssn/__init__.py @@ -1,10 +1,10 @@ -from .. import BaseProvider +from .. import BaseProvider, ElementsType localized = True class Provider(BaseProvider): - ssn_formats = ("###-##-####",) + ssn_formats: ElementsType = ("###-##-####",) - def ssn(self): + def ssn(self) -> str: return self.bothify(self.random_element(self.ssn_formats)) diff --git a/faker/providers/ssn/bg_BG/__init__.py b/faker/providers/ssn/bg_BG/__init__.py index 892911d08f..14bef9ddbe 100644 --- a/faker/providers/ssn/bg_BG/__init__.py +++ b/faker/providers/ssn/bg_BG/__init__.py @@ -11,7 +11,7 @@ class Provider(BaseProvider): 'BG##########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Bulgarian VAT ID diff --git a/faker/providers/ssn/cs_CZ/__init__.py b/faker/providers/ssn/cs_CZ/__init__.py index d9d546c425..9a6136ea5c 100644 --- a/faker/providers/ssn/cs_CZ/__init__.py +++ b/faker/providers/ssn/cs_CZ/__init__.py @@ -1,33 +1,33 @@ from math import ceil +from typing import List, Tuple from .. import Provider as BaseProvider class Provider(BaseProvider): - vat_id_formats = ( + vat_id_formats: Tuple[str, ...] = ( 'CZ########', 'CZ#########', 'CZ##########', ) - national_id_months = ['%.2d' % i for i in range(1, 13)] + ['%.2d' % i for i in range(51, 63)] + national_id_months: List[str] = ['%.2d' % i for i in range(1, 13)] + ['%.2d' % i for i in range(51, 63)] - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Czech VAT ID """ - return self.bothify(self.random_element(self.vat_id_formats)) - def birth_number(self): + def birth_number(self) -> str: """ Birth Number (Czech/Slovak: rodné číslo (RČ)) https://en.wikipedia.org/wiki/National_identification_number#Czech_Republic_and_Slovakia """ birthdate = self.generator.date_of_birth() year = f'{birthdate:%y}' - month = self.random_element(self.national_id_months) + month: str = self.random_element(self.national_id_months) day = f'{birthdate:%d}' if birthdate.year > 1953: sn = self.random_number(4, True) diff --git a/faker/providers/ssn/de_AT/__init__.py b/faker/providers/ssn/de_AT/__init__.py index 6c3af9c6e1..1b1bc3e608 100644 --- a/faker/providers/ssn/de_AT/__init__.py +++ b/faker/providers/ssn/de_AT/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'ATU########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Austrian VAT ID diff --git a/faker/providers/ssn/de_DE/__init__.py b/faker/providers/ssn/de_DE/__init__.py index 24ec3f85cb..4bc7d83f78 100644 --- a/faker/providers/ssn/de_DE/__init__.py +++ b/faker/providers/ssn/de_DE/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'DE#########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random German VAT ID diff --git a/faker/providers/ssn/dk_DK/__init__.py b/faker/providers/ssn/dk_DK/__init__.py index 87cedb1000..517b510a13 100644 --- a/faker/providers/ssn/dk_DK/__init__.py +++ b/faker/providers/ssn/dk_DK/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'DK########', ) - def vat_id(self): + def vat_id(self) -> str: """ Returns a random generated Danish Tax ID """ diff --git a/faker/providers/ssn/el_CY/__init__.py b/faker/providers/ssn/el_CY/__init__.py index 82a8a30cae..0aedf75597 100644 --- a/faker/providers/ssn/el_CY/__init__.py +++ b/faker/providers/ssn/el_CY/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'CY#########?', ) - def vat_id(self): + def vat_id(self) -> str: """ Returns a random generated Cypriot Tax ID """ diff --git a/faker/providers/ssn/el_GR/__init__.py b/faker/providers/ssn/el_GR/__init__.py index f93c31a5a1..0d35eecc1c 100644 --- a/faker/providers/ssn/el_GR/__init__.py +++ b/faker/providers/ssn/el_GR/__init__.py @@ -17,7 +17,7 @@ class Provider(BaseProvider): '?? ######', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Greek VAT ID @@ -25,7 +25,7 @@ def vat_id(self): return self.bothify(self.random_element(self.vat_id_formats)) - def police_id(self): + def police_id(self) -> str: """ :return: a random Greek police ID """ diff --git a/faker/providers/ssn/en_CA/__init__.py b/faker/providers/ssn/en_CA/__init__.py index ffdb6bd2ac..36e444ee64 100644 --- a/faker/providers/ssn/en_CA/__init__.py +++ b/faker/providers/ssn/en_CA/__init__.py @@ -47,7 +47,7 @@ class Provider(SsnProvider): # This function reverses the checksum steps to create a random # valid nine-digit Canadian SIN (Social Insurance Number) in the # format '### ### ###'. - def ssn(self): + def ssn(self) -> str: # Create an array of 8 elements initialized randomly. digits = self.generator.random.sample(range(9), 8) diff --git a/faker/providers/ssn/en_GB/__init__.py b/faker/providers/ssn/en_GB/__init__.py index a63a5ccaa5..f996018cc1 100644 --- a/faker/providers/ssn/en_GB/__init__.py +++ b/faker/providers/ssn/en_GB/__init__.py @@ -1,3 +1,5 @@ +from typing import Tuple + from .. import Provider as BaseProvider @@ -12,24 +14,24 @@ class Provider(BaseProvider): # only and is generally included as per the above examples, but a # few 'styles' have been included below for the sake of realism. - nino_formats = ( + nino_formats: Tuple[str, ...] = ( 'ZZ ## ## ## T', 'ZZ######T', 'ZZ ###### T', ) - def ssn(self): - pattern = self.random_element(self.nino_formats) + def ssn(self) -> str: + pattern: str = self.random_element(self.nino_formats) return self.numerify(self.generator.parse(pattern)) - vat_id_formats = ( + vat_id_formats: Tuple[str, ...] = ( 'GB### #### ##', 'GB### #### ## ###', 'GBGD###', 'GBHA###', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random British VAT ID diff --git a/faker/providers/ssn/en_IE/__init__.py b/faker/providers/ssn/en_IE/__init__.py index 002291be28..30b3aa8b10 100644 --- a/faker/providers/ssn/en_IE/__init__.py +++ b/faker/providers/ssn/en_IE/__init__.py @@ -12,7 +12,7 @@ class Provider(BaseProvider): 'IE#######??', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Irish VAT ID diff --git a/faker/providers/ssn/en_IN/__init__.py b/faker/providers/ssn/en_IN/__init__.py index 52d5294533..e2967c991d 100644 --- a/faker/providers/ssn/en_IN/__init__.py +++ b/faker/providers/ssn/en_IN/__init__.py @@ -12,7 +12,7 @@ class Provider(BaseProvider): '%##########', ) - def aadhaar_id(self): + def aadhaar_id(self) -> str: """ Aadhaar is a 12 digit person identifier generated for residents of India. @@ -21,7 +21,7 @@ def aadhaar_id(self): """ aadhaar_digits = self.numerify(self.random_element(self.aadhaar_id_formats)) - checksum = checksums.calculate_luhn(aadhaar_digits) + checksum = checksums.calculate_luhn(int(aadhaar_digits)) aadhaar_number = f'{aadhaar_digits}{checksum}' diff --git a/faker/providers/ssn/en_PH/__init__.py b/faker/providers/ssn/en_PH/__init__.py index 66b549e457..b46f518321 100644 --- a/faker/providers/ssn/en_PH/__init__.py +++ b/faker/providers/ssn/en_PH/__init__.py @@ -33,21 +33,21 @@ class Provider(BaseProvider): pagibig_formats = ('####-####-####',) umid_formats = ('####-#######-#',) - def sss(self): + def sss(self) -> str: return self.numerify(self.random_element(self.sss_formats)) - def gsis(self): + def gsis(self) -> str: return self.numerify(self.random_element(self.gsis_formats)) - def pagibig(self): + def pagibig(self) -> str: return self.numerify(self.random_element(self.pagibig_formats)) - def philhealth(self): + def philhealth(self) -> str: return self.numerify(self.random_element(self.philhealth_formats)) - def umid(self): + def umid(self) -> str: return self.numerify(self.random_element(self.umid_formats)) - def ssn(self): + def ssn(self) -> str: # Use UMID as SSN in the interim till its deprecation return self.umid() diff --git a/faker/providers/ssn/en_US/__init__.py b/faker/providers/ssn/en_US/__init__.py index 0f64c9f512..82c63ac7dd 100644 --- a/faker/providers/ssn/en_US/__init__.py +++ b/faker/providers/ssn/en_US/__init__.py @@ -1,3 +1,5 @@ +from typing import List + from .. import Provider as BaseProvider @@ -7,7 +9,7 @@ class Provider(BaseProvider): ITIN_TYPE = 'ITIN' EIN_TYPE = 'EIN' - def itin(self): + def itin(self) -> str: """Generate a random United States Individual Taxpayer Identification Number (ITIN). An United States Individual Taxpayer Identification Number @@ -24,12 +26,12 @@ def itin(self): serial = self.random_int(min=0, max=9999) # The group number must be between 70 and 99 inclusively but not 89 or 93 - group = self.random_element([x for x in range(70, 100) if x not in [89, 93]]) + group: int = self.random_element([x for x in range(70, 100) if x not in [89, 93]]) itin = f'{area:03d}-{group:02d}-{serial:04d}' return itin - def ein(self): + def ein(self) -> str: """Generate a random United States Employer Identification Number (EIN). An United States An Employer Identification Number (EIN) is @@ -45,7 +47,7 @@ def ein(self): # # https://www.irs.gov/businesses/small-businesses-self-employed/how-eins-are-assigned-and-valid-ein-prefixes - ein_prefix_choices = [ + ein_prefix_choices: List[str] = [ '01', '02', '03', @@ -130,13 +132,13 @@ def ein(self): '98', '99'] - ein_prefix = self.random_element(ein_prefix_choices) + ein_prefix: str = self.random_element(ein_prefix_choices) sequence = self.random_int(min=0, max=9999999) ein = f'{ein_prefix:s}-{sequence:07d}' return ein - def invalid_ssn(self): + def invalid_ssn(self) -> str: """ Generate a random invalid United States Social Security Identification Number (SSN). Invalid SSNs have the following characteristics: @@ -198,7 +200,7 @@ def invalid_ssn(self): invalid_ssn = f'{area:03d}-{group:02d}-{serial:04d}' return invalid_ssn - def ssn(self, taxpayer_identification_number_type=SSN_TYPE): + def ssn(self, taxpayer_identification_number_type: str = SSN_TYPE) -> str: """ Generate a random United States Taxpayer Identification Number of the specified type. If no type is specified, a US SSN is returned. diff --git a/faker/providers/ssn/es_ES/__init__.py b/faker/providers/ssn/es_ES/__init__.py index 199caf5d2b..92431a1777 100644 --- a/faker/providers/ssn/es_ES/__init__.py +++ b/faker/providers/ssn/es_ES/__init__.py @@ -14,7 +14,7 @@ class Provider(BaseProvider): 'ES?#######?', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Spanish VAT ID @@ -22,7 +22,7 @@ def vat_id(self): return self.bothify(self.random_element(self.vat_id_formats)) - def nie(self): + def nie(self) -> str: """ https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero :return: a random Spanish NIE @@ -33,7 +33,7 @@ def nie(self): control = self._calculate_control_doi(str(first_chr) + doi_body) return "XYZ"[first_chr] + doi_body + control - def nif(self): + def nif(self) -> str: """ https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal :return: NIF @@ -42,7 +42,7 @@ def nif(self): nie_body = str(random.randrange(0, 100000000)) # generate a number of a maximum of 8 characters long return nie_body.zfill(8) + self._calculate_control_doi(nie_body) - def cif(self): + def cif(self) -> str: """ https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal :return: a random Spanish CIF @@ -53,7 +53,7 @@ def cif(self): cif = first_chr + doi_body return cif + self._calculate_control_cif(cif) - def doi(self): + def doi(self) -> str: """ https://es.wikipedia.org/wiki/Identificador_de_objeto_digital :return: a random Spanish CIF or NIE or NIF @@ -62,7 +62,7 @@ def doi(self): return random.choice([self.cif, self.nie, self.nif])() @staticmethod - def _calculate_control_doi(doi): + def _calculate_control_doi(doi: str) -> str: """ Calculate the letter that corresponds to the end of a DOI :param doi: calculated value so far needing a control character @@ -73,7 +73,7 @@ def _calculate_control_doi(doi): return lookup[int(doi) % 23] @classmethod - def _calculate_control_cif(cls, cif): + def _calculate_control_cif(cls, cif: str) -> str: """ Calculate the letter that corresponds to the end of a CIF :param cif: calculated value so far needing a control character diff --git a/faker/providers/ssn/es_MX/__init__.py b/faker/providers/ssn/es_MX/__init__.py index 7aeda0ac48..7497aaee73 100644 --- a/faker/providers/ssn/es_MX/__init__.py +++ b/faker/providers/ssn/es_MX/__init__.py @@ -103,7 +103,7 @@ CURP_CHARACTERS = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ" -def _reduce_digits(number): +def _reduce_digits(number: int) -> int: """ Sum of digits of a number until sum becomes single digit. @@ -118,7 +118,7 @@ def _reduce_digits(number): return number % 9 -def ssn_checksum(digits): +def ssn_checksum(digits: map) -> int: """ Calculate the checksum for the mexican SSN (IMSS). """ @@ -128,7 +128,7 @@ def ssn_checksum(digits): ) % 10 -def curp_checksum(characters): +def curp_checksum(characters: str) -> int: """ Calculate the checksum for the mexican CURP. """ @@ -145,7 +145,7 @@ class Provider(BaseProvider): """ ssn_formats = ("###########",) - def ssn(self): + def ssn(self) -> str: """ Mexican Social Security Number, as given by IMSS. @@ -163,7 +163,7 @@ def ssn(self): return num - def curp(self): + def curp(self) -> str: """ See https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Registro_de_Poblaci%C3%B3n. @@ -205,7 +205,7 @@ def curp(self): return random_curp - def rfc(self, natural=True): + def rfc(self, natural: bool = True) -> str: """ See https://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes diff --git a/faker/providers/ssn/et_EE/__init__.py b/faker/providers/ssn/et_EE/__init__.py index 03398220f1..dbc7d71a8f 100644 --- a/faker/providers/ssn/et_EE/__init__.py +++ b/faker/providers/ssn/et_EE/__init__.py @@ -1,10 +1,12 @@ import datetime import operator +from typing import List + from .. import Provider as SsnProvider -def checksum(digits): +def checksum(digits: List[int]) -> int: """Calculate checksum of Estonian personal identity code. Checksum is calculated with "Modulo 11" method using level I or II scale: @@ -30,7 +32,7 @@ class Provider(SsnProvider): scale1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 1) scale2 = (3, 4, 5, 6, 7, 8, 9, 1, 2, 3) - def ssn(self, min_age=16, max_age=90): + def ssn(self, min_age: int = 16, max_age: int = 90) -> str: """ Returns 11 character Estonian personal identity code (isikukood, IK). @@ -65,7 +67,7 @@ def ssn(self, min_age=16, max_age=90): 'EE#########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Estonian VAT ID diff --git a/faker/providers/ssn/fi_FI/__init__.py b/faker/providers/ssn/fi_FI/__init__.py index ceecd2cc3d..386ff21a7e 100644 --- a/faker/providers/ssn/fi_FI/__init__.py +++ b/faker/providers/ssn/fi_FI/__init__.py @@ -5,7 +5,7 @@ class Provider(SsnProvider): - def ssn(self, min_age=0, max_age=105, artificial=False): + def ssn(self, min_age: int = 0, max_age: int = 105, artificial: bool = False) -> str: """ Returns 11 character Finnish personal identity code (Henkilötunnus, HETU, Swedish: Personbeteckning). This function assigns random @@ -39,7 +39,7 @@ def _checksum(hetu): return hetu @staticmethod - def _get_century_code(year): + def _get_century_code(year: int) -> str: """Returns the century code for a given year""" if 2000 <= year < 3000: separator = 'A' @@ -55,7 +55,7 @@ def _get_century_code(year): 'FI########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Finnish VAT ID diff --git a/faker/providers/ssn/fr_CH/__init__.py b/faker/providers/ssn/fr_CH/__init__.py index fea603745a..f197318bb6 100644 --- a/faker/providers/ssn/fr_CH/__init__.py +++ b/faker/providers/ssn/fr_CH/__init__.py @@ -1,10 +1,12 @@ +from typing import List + from .. import Provider as SsnProvider class Provider(SsnProvider): ssn_formats = ("###.####.####.##",) - def ssn(self): + def ssn(self) -> str: """ Returns a 13 digits Swiss SSN named AHV (German) or AVS (French and Italian) @@ -15,21 +17,17 @@ def _checksum(digits): oddsum = sum(digits[1::2]) return (10 - ((evensum + oddsum * 3) % 10)) % 10 - digits = [7, 5, 6] + digits: List[int] = [7, 5, 6] # create an array of first 9 elements initialized randomly digits += self.generator.random.sample(range(10), 9) # determine the last digit to make it qualify the test digits.append(_checksum(digits)) # repeat steps until it does qualify the test - digits = ''.join([str(d) for d in digits]) - ssn = digits[:3] + '.' \ - + digits[3:7] + '.' \ - + digits[7:11] + '.' \ - + digits[11:] - return ssn + digits_ = ''.join([str(d) for d in digits]) + return f'{digits_[:3]}.{digits_[3:7]}.{digits_[7:11]}.{digits_[11:]}' - def vat_id(self): + def vat_id(self) -> str: """ :return: Swiss UID number """ @@ -42,5 +40,5 @@ def _checksum(digits): return 5 return remainder - vat_id = self.numerify('########') + vat_id: str = self.numerify('########') return 'CHE' + vat_id + str(_checksum(vat_id)) diff --git a/faker/providers/ssn/fr_FR/__init__.py b/faker/providers/ssn/fr_FR/__init__.py index 1cdd903670..6a587950cd 100644 --- a/faker/providers/ssn/fr_FR/__init__.py +++ b/faker/providers/ssn/fr_FR/__init__.py @@ -13,7 +13,7 @@ class Provider(BaseProvider): 'FR#? #########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random French VAT ID diff --git a/faker/providers/ssn/he_IL/__init__.py b/faker/providers/ssn/he_IL/__init__.py index 0bc0b55492..91201b20c3 100644 --- a/faker/providers/ssn/he_IL/__init__.py +++ b/faker/providers/ssn/he_IL/__init__.py @@ -3,7 +3,7 @@ class Provider(SsnProvider): - def ssn(self): + def ssn(self) -> str: """ Returns an Israeli identity number, known as Teudat Zehut ("tz"). diff --git a/faker/providers/ssn/hr_HR/__init__.py b/faker/providers/ssn/hr_HR/__init__.py index 0ccc057693..56287efc16 100644 --- a/faker/providers/ssn/hr_HR/__init__.py +++ b/faker/providers/ssn/hr_HR/__init__.py @@ -1,7 +1,9 @@ +from typing import List + from .. import Provider as SsnProvider -def checksum(digits): +def checksum(digits: List[int]) -> int: """ Calculate and return control digit for given list of digits based on ISO7064, MOD 11,10 standard. @@ -30,7 +32,7 @@ class Provider(SsnProvider): (international standard ISO 7064, module 11.10). """ - def ssn(self): + def ssn(self) -> str: digits = self.generator.random.sample(range(10), 10) digits.append(checksum(digits)) @@ -41,7 +43,7 @@ def ssn(self): 'HR###########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Croatian VAT ID diff --git a/faker/providers/ssn/hu_HU/__init__.py b/faker/providers/ssn/hu_HU/__init__.py index 31c6081ccd..bf0a66525c 100644 --- a/faker/providers/ssn/hu_HU/__init__.py +++ b/faker/providers/ssn/hu_HU/__init__.py @@ -1,18 +1,17 @@ from functools import reduce from math import fmod +from typing import Optional +from ....typing import GenderType from .. import Provider as SsnProvider -def zfix(d): - if d < 10: - return "0" + str(d) - else: - return d +def zfix(d: int) -> str: + return '0' + str(d) if d < 10 else str(d) class Provider(SsnProvider): - def ssn(self, dob=None, gender=None): + def ssn(self, dob: Optional[str] = None, gender: Optional[GenderType] = None) -> str: """ Generates Hungarian SSN equivalent (személyazonosító szám or, colloquially, személyi szám) @@ -112,11 +111,10 @@ def ssn(self, dob=None, gender=None): H = self.generator.random_int(1, 12) N = self.generator.random_int(1, 30) - H = zfix(H) - N = zfix(N) + H_, N_ = zfix(H), zfix(N) S = f'{self.generator.random_digit()}{self.generator.random_digit()}{self.generator.random_digit()}' - vdig = f'{M}{E}{H}{N}{S}' + vdig = f'{M}{E}{H_}{N_}{S}' if 17 < E < 97: cum = [(k + 1) * int(v) for k, v in enumerate(vdig)] @@ -131,7 +129,7 @@ def ssn(self, dob=None, gender=None): 'HU########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Hungarian VAT ID diff --git a/faker/providers/ssn/it_IT/__init__.py b/faker/providers/ssn/it_IT/__init__.py index bb53dd16c8..6a2861cd5c 100644 --- a/faker/providers/ssn/it_IT/__init__.py +++ b/faker/providers/ssn/it_IT/__init__.py @@ -13,7 +13,7 @@ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)) -def checksum(value): +def checksum(value: str) -> str: """ Calculates the checksum char used for the 16th char. Author: Vincenzo Palazzo @@ -28,7 +28,7 @@ class Provider(SsnProvider): """ fiscal_code_format = '??????##?##?###' - def ssn(self): + def ssn(self) -> str: code = self.bothify(self.fiscal_code_format).upper() return code + checksum(code) @@ -36,7 +36,7 @@ def ssn(self): 'IT###########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Italian VAT ID diff --git a/faker/providers/ssn/lb_LU/__init__.py b/faker/providers/ssn/lb_LU/__init__.py index 05db048929..d4a3f97b43 100644 --- a/faker/providers/ssn/lb_LU/__init__.py +++ b/faker/providers/ssn/lb_LU/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'LU########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Luxembourgish VAT ID diff --git a/faker/providers/ssn/lt_LT/__init__.py b/faker/providers/ssn/lt_LT/__init__.py index d03841b35c..d39201dbd1 100644 --- a/faker/providers/ssn/lt_LT/__init__.py +++ b/faker/providers/ssn/lt_LT/__init__.py @@ -11,7 +11,7 @@ class Provider(BaseProvider): 'LT############', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Lithuanian VAT ID diff --git a/faker/providers/ssn/lv_LV/__init__.py b/faker/providers/ssn/lv_LV/__init__.py index 3b84a6f0f3..0a3a09ee68 100644 --- a/faker/providers/ssn/lv_LV/__init__.py +++ b/faker/providers/ssn/lv_LV/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'LV###########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Latvian VAT ID diff --git a/faker/providers/ssn/mt_MT/__init__.py b/faker/providers/ssn/mt_MT/__init__.py index 384c002b7f..b99144a15b 100644 --- a/faker/providers/ssn/mt_MT/__init__.py +++ b/faker/providers/ssn/mt_MT/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'MT########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Maltese VAT ID diff --git a/faker/providers/ssn/nl_BE/__init__.py b/faker/providers/ssn/nl_BE/__init__.py index 7e46bba817..4432a0a846 100644 --- a/faker/providers/ssn/nl_BE/__init__.py +++ b/faker/providers/ssn/nl_BE/__init__.py @@ -8,7 +8,7 @@ class Provider(SsnProvider): - def ssn(self): + def ssn(self) -> str: """ Returns a 11 digits Belgian SSN called "rijksregisternummer" as a string @@ -58,7 +58,7 @@ def _checksum(digits): 'BE##########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Belgian VAT ID diff --git a/faker/providers/ssn/nl_NL/__init__.py b/faker/providers/ssn/nl_NL/__init__.py index 71633ca77d..d1e8972040 100644 --- a/faker/providers/ssn/nl_NL/__init__.py +++ b/faker/providers/ssn/nl_NL/__init__.py @@ -3,7 +3,7 @@ class Provider(SsnProvider): - def ssn(self): + def ssn(self) -> str: """ Returns a 9 digits Dutch SSN called "burgerservicenummer (BSN)". @@ -39,7 +39,7 @@ def _checksum(digits): 'NL#########B##', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Dutch VAT ID diff --git a/faker/providers/ssn/no_NO/__init__.py b/faker/providers/ssn/no_NO/__init__.py index b8804a524b..196f09554e 100644 --- a/faker/providers/ssn/no_NO/__init__.py +++ b/faker/providers/ssn/no_NO/__init__.py @@ -1,10 +1,13 @@ import datetime import operator +from typing import List, Optional, Sequence + +from ....typing import GenderType from .. import Provider as SsnProvider -def checksum(digits, scale): +def checksum(digits: Sequence[int], scale: List[int]) -> int: """ Calculate checksum of Norwegian personal identity code. @@ -27,7 +30,7 @@ class Provider(SsnProvider): scale1 = (3, 7, 6, 1, 8, 9, 4, 5, 2) scale2 = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2) - def ssn(self, dob=None, gender=None): + def ssn(self, dob: Optional[str] = None, gender: Optional[GenderType] = None) -> str: """ Returns 11 character Norwegian personal identity code (Fødselsnummer). diff --git a/faker/providers/ssn/pl_PL/__init__.py b/faker/providers/ssn/pl_PL/__init__.py index a5b9bfb2a2..b95f7f4365 100644 --- a/faker/providers/ssn/pl_PL/__init__.py +++ b/faker/providers/ssn/pl_PL/__init__.py @@ -1,7 +1,10 @@ +from datetime import datetime +from typing import List + from .. import Provider as SsnProvider -def checksum(digits): +def checksum(digits: List[int]) -> int: """ Calculates and returns a control digit for given list of digits basing on PESEL standard. """ @@ -16,7 +19,7 @@ def checksum(digits): return check_digit -def calculate_month(birth_date): +def calculate_month(birth_date: datetime) -> int: """ Calculates and returns a month number basing on PESEL standard. """ @@ -28,7 +31,7 @@ def calculate_month(birth_date): class Provider(SsnProvider): - def ssn(self): + def ssn(self) -> str: """ Returns 11 character Polish national identity code (Public Electronic Census System, Polish: Powszechny Elektroniczny System Ewidencji Ludności - PESEL). @@ -64,7 +67,7 @@ def ssn(self): 'PL##########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Polish VAT ID diff --git a/faker/providers/ssn/pt_BR/__init__.py b/faker/providers/ssn/pt_BR/__init__.py index ca21b7b401..7e114b7d71 100644 --- a/faker/providers/ssn/pt_BR/__init__.py +++ b/faker/providers/ssn/pt_BR/__init__.py @@ -1,7 +1,9 @@ +from typing import List + from .. import Provider as SsnProvider -def checksum(digits): +def checksum(digits: List[int]) -> int: """ Returns the checksum of CPF digits. References to the algorithm: @@ -29,7 +31,7 @@ class Provider(SsnProvider): The cpf return a valid number formatted with brazilian mask. eg nnn.nnn.nnn-nn """ - def ssn(self): + def ssn(self) -> str: digits = self.generator.random.sample(range(10), 9) dv = checksum(digits) @@ -38,11 +40,11 @@ def ssn(self): return ''.join(map(str, digits)) - def cpf(self): + def cpf(self) -> str: c = self.ssn() return c[:3] + '.' + c[3:6] + '.' + c[6:9] + '-' + c[9:] - def rg(self): + def rg(self) -> str: """ Brazilian RG, return plain numbers. Check: https://www.ngmatematica.com/2014/02/como-determinar-o-digito-verificador-do.html diff --git a/faker/providers/ssn/pt_PT/__init__.py b/faker/providers/ssn/pt_PT/__init__.py index a5f85eb61f..28381c59dc 100644 --- a/faker/providers/ssn/pt_PT/__init__.py +++ b/faker/providers/ssn/pt_PT/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'PT#########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Portuguese VAT ID diff --git a/faker/providers/ssn/ro_RO/__init__.py b/faker/providers/ssn/ro_RO/__init__.py index 82d44a8d46..429d127849 100644 --- a/faker/providers/ssn/ro_RO/__init__.py +++ b/faker/providers/ssn/ro_RO/__init__.py @@ -1,7 +1,7 @@ from .. import Provider as BaseProvider -def ssn_checksum(number): +def ssn_checksum(number: str) -> int: """ Calculate the checksum for the romanian SSN (CNP). """ @@ -10,7 +10,7 @@ def ssn_checksum(number): return 1 if check == 10 else check -def vat_checksum(number): +def vat_checksum(number: str) -> int: """ Calculate the check digit for romanian VAT numbers. """ @@ -46,7 +46,7 @@ class Provider(BaseProvider): '9########', ) - def vat_id(self): + def vat_id(self) -> str: """ https://ro.wikipedia.org/wiki/Cod_de_identificare_fiscal%C4%83 :return: A random Romanian VAT ID @@ -62,7 +62,7 @@ def vat_id(self): ssn_formats = ("#############",) - def ssn(self): + def ssn(self) -> str: """ Romanian Social Security Number. diff --git a/faker/providers/ssn/sk_SK/__init__.py b/faker/providers/ssn/sk_SK/__init__.py index 0b704d1b26..a65642723d 100644 --- a/faker/providers/ssn/sk_SK/__init__.py +++ b/faker/providers/ssn/sk_SK/__init__.py @@ -14,7 +14,7 @@ class Provider(BaseProvider): national_id_months = ['%.2d' % i for i in range(1, 13)] + ['%.2d' % i for i in range(51, 63)] - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Slovakian VAT ID @@ -22,14 +22,14 @@ def vat_id(self): return self.bothify(self.random_element(self.vat_id_formats)) - def birth_number(self): + def birth_number(self) -> str: """ Birth Number (Czech/Slovak: rodné číslo (RČ)) https://en.wikipedia.org/wiki/National_identification_number#Czech_Republic_and_Slovakia """ birthdate = self.generator.date_of_birth() year = f'{birthdate:%y}' - month = self.random_element(self.national_id_months) + month: str = self.random_element(self.national_id_months) day = f'{birthdate:%d}' if birthdate.year > 1953: sn = self.random_number(4, True) diff --git a/faker/providers/ssn/sl_SI/__init__.py b/faker/providers/ssn/sl_SI/__init__.py index 06fee672d3..6478d40da5 100644 --- a/faker/providers/ssn/sl_SI/__init__.py +++ b/faker/providers/ssn/sl_SI/__init__.py @@ -10,7 +10,7 @@ class Provider(BaseProvider): 'SI########', ) - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: a random Slovenian VAT ID diff --git a/faker/providers/ssn/sv_SE/__init__.py b/faker/providers/ssn/sv_SE/__init__.py index c6b812647f..b452feca50 100644 --- a/faker/providers/ssn/sv_SE/__init__.py +++ b/faker/providers/ssn/sv_SE/__init__.py @@ -1,6 +1,8 @@ import datetime import random +from typing import Tuple + from faker.utils.checksums import calculate_luhn from .. import Provider as SsnProvider @@ -9,13 +11,13 @@ class Provider(SsnProvider): @staticmethod - def _org_to_vat(org_id): + def _org_to_vat(org_id: str) -> str: org_id = org_id.replace('-', '') if len(org_id) == 10: org_id = '16' + org_id return f'SE{org_id}01' - def ssn(self, min_age=18, max_age=90, long=False, dash=True): + def ssn(self, min_age: int = 18, max_age: int = 90, long: bool = False, dash: bool = True) -> str: """ Returns a 10 or 12 (long=True) digit Swedish SSN, "Personnummer". @@ -36,7 +38,7 @@ def ssn(self, min_age=18, max_age=90, long=False, dash=True): pnr_date = f'{birthday:{yr_fmt}%m%d}' chk_date = pnr_date[2:] if long else pnr_date suffix = f'{self.generator.random.randrange(0, 999):03}' - luhn_checksum = str(calculate_luhn(chk_date + suffix)) + luhn_checksum = str(calculate_luhn(int(chk_date + suffix))) hyphen = '-' if dash else '' pnr = f'{pnr_date}{hyphen}{suffix}{luhn_checksum}' @@ -44,7 +46,7 @@ def ssn(self, min_age=18, max_age=90, long=False, dash=True): ORG_ID_DIGIT_1 = (1, 2, 3, 5, 6, 7, 8, 9) - def org_id(self, long=False, dash=True): + def org_id(self, long: bool = False, dash: bool = True) -> str: """ Returns a 10 or 12 digit Organisation ID for a Swedish company. @@ -57,14 +59,14 @@ def org_id(self, long=False, dash=True): onr_one += str(self.generator.random.randrange(20, 99)) onr_one += str(self.generator.random.randrange(0, 99)).zfill(2) onr_two = str(self.generator.random.randrange(0, 999)).zfill(3) - luhn_checksum = str(calculate_luhn(onr_one + onr_two)) + luhn_checksum = str(calculate_luhn(int(onr_one + onr_two))) prefix = '16' if long else '' hyphen = '-' if dash else '' org_id = f'{prefix}{onr_one}{hyphen}{onr_two}{luhn_checksum}' return org_id - def vat_id(self): + def vat_id(self) -> str: """ http://ec.europa.eu/taxation_customs/vies/faq.html#item_11 :return: A random Swedish VAT ID, based on a valid Org ID @@ -73,7 +75,7 @@ def vat_id(self): vid = Provider._org_to_vat(oid) return vid - def org_and_vat_id(self, long=False, dash=True): + def org_and_vat_id(self, long: bool = False, dash: bool = True) -> Tuple[str, str]: """Returns matching Org ID and VAT number""" oid = self.org_id(long=long, dash=dash) vid = Provider._org_to_vat(oid) diff --git a/faker/providers/ssn/th_TH/__init__.py b/faker/providers/ssn/th_TH/__init__.py index c9dd87aca4..2edcdbd2b9 100644 --- a/faker/providers/ssn/th_TH/__init__.py +++ b/faker/providers/ssn/th_TH/__init__.py @@ -13,7 +13,7 @@ class Provider(BaseProvider): # Digits 6-12: Birth certificate number # Digit 13: Checksum - def ssn(self): + def ssn(self) -> str: """ Thai national ID """ @@ -51,7 +51,7 @@ def ssn(self): return nat_id - def vat_id(self): + def vat_id(self) -> str: """ Personal VAT ID is the same as national ID (Corporate VAT ID is different) diff --git a/faker/providers/ssn/tr_TR/__init__.py b/faker/providers/ssn/tr_TR/__init__.py index 7e756d260b..001c813682 100644 --- a/faker/providers/ssn/tr_TR/__init__.py +++ b/faker/providers/ssn/tr_TR/__init__.py @@ -8,11 +8,11 @@ class Provider(BaseProvider): # First number can't be zero # Eleventh number is result of division after sum first number - def ssn(self): + def ssn(self) -> str: """ :example '89340691651' """ - first_part = self.random_element((1, 2, 3, 4, 5, 6, 7, 8, 9)) - middle_part = self.bothify('#########') - last_part = sum(int(x) for x in f'{first_part}{middle_part}') % 10 + first_part: int = self.random_element((1, 2, 3, 4, 5, 6, 7, 8, 9)) + middle_part: str = self.bothify('#########') + last_part: int = sum(int(x) for x in f'{first_part}{middle_part}') % 10 return f'{first_part}{middle_part}{last_part}' diff --git a/faker/providers/ssn/uk_UA/__init__.py b/faker/providers/ssn/uk_UA/__init__.py index 426447aa85..9d6fbd687a 100644 --- a/faker/providers/ssn/uk_UA/__init__.py +++ b/faker/providers/ssn/uk_UA/__init__.py @@ -4,7 +4,7 @@ class Provider(SsnProvider): - def ssn(self): + def ssn(self) -> str: """ Ukrainian "Реєстраційний номер облікової картки платника податків" also known as "Ідентифікаційний номер фізичної особи". diff --git a/faker/providers/ssn/zh_CN/__init__.py b/faker/providers/ssn/zh_CN/__init__.py index f6b8701c2a..36ef7c40f1 100644 --- a/faker/providers/ssn/zh_CN/__init__.py +++ b/faker/providers/ssn/zh_CN/__init__.py @@ -1,12 +1,15 @@ import datetime +from typing import List, Optional + +from ....typing import GenderType from .. import Provider as SsnProvider class Provider(SsnProvider): # Extracted from # http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201504/t20150415_712722.html - area_codes = [ + area_codes: List[str] = [ "110000", "110100", "110101", "110102", "110105", "110106", "110107", "110108", "110109", "110111", "110112", "110113", "110114", "110115", "110116", "110117", "110200", "110228", "110229", "120000", "120100", @@ -511,7 +514,7 @@ class Provider(SsnProvider): "659003", "659004", "710000", "810000", "820000", ] - def ssn(self, min_age=18, max_age=90, gender=None): + def ssn(self, min_age: int = 18, max_age: int = 90, gender: Optional[GenderType] = None) -> str: """ Return 18 character chinese personal identity code @@ -525,8 +528,8 @@ def checksum(s): birthday = datetime.date.today() - age birthday_str = birthday.strftime('%Y%m%d') - ssn_without_checksum = self.numerify( - self.random_element(self.area_codes) + birthday_str + "##") + area_code: str = self.random_element(self.area_codes) + ssn_without_checksum = self.numerify(area_code + birthday_str + "##") _number = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') if gender: diff --git a/faker/providers/ssn/zh_TW/__init__.py b/faker/providers/ssn/zh_TW/__init__.py index 87089bc333..84af8f120c 100644 --- a/faker/providers/ssn/zh_TW/__init__.py +++ b/faker/providers/ssn/zh_TW/__init__.py @@ -4,5 +4,5 @@ class Provider(SsnProvider): ssn_formats = ("?#########",) - def ssn(self): + def ssn(self) -> str: return self.bothify(self.random_element(self.ssn_formats)).upper() diff --git a/faker/providers/user_agent/__init__.py b/faker/providers/user_agent/__init__.py index 40fe1830cc..d2a8786fe1 100644 --- a/faker/providers/user_agent/__init__.py +++ b/faker/providers/user_agent/__init__.py @@ -2,28 +2,28 @@ from datetime import datetime -from .. import BaseProvider +from .. import BaseProvider, ElementsType class Provider(BaseProvider): """Implement default user agent provider for Faker.""" - user_agents = ( + user_agents: ElementsType = ( 'chrome', 'firefox', 'internet_explorer', 'opera', 'safari', ) - windows_platform_tokens = ( + windows_platform_tokens: ElementsType = ( 'Windows 95', 'Windows 98', 'Windows 98; Win 9x 4.90', 'Windows CE', 'Windows NT 4.0', 'Windows NT 5.0', 'Windows NT 5.01', 'Windows NT 5.1', 'Windows NT 5.2', 'Windows NT 6.0', 'Windows NT 6.1', 'Windows NT 6.2', 'Windows NT 10.0', ) - linux_processors = ('i686', 'x86_64') + linux_processors: ElementsType = ('i686', 'x86_64') - mac_processors = ('Intel', 'PPC', 'U; Intel', 'U; PPC') + mac_processors: ElementsType = ('Intel', 'PPC', 'U; Intel', 'U; PPC') - android_versions = ( + android_versions: ElementsType = ( '1.0', '1.1', '1.5', '1.6', '2.0', '2.0.1', '2.1', '2.2', '2.2.1', '2.2.2', '2.2.3', '2.3', '2.3.1', '2.3.2', '2.3.3', '2.3.4', '2.3.5', '2.3.6', '2.3.7', '3.0', '3.1', '3.2', '3.2.1', '3.2.2', '3.2.3', '3.2.4', '3.2.5', '3.2.6', '4.0', '4.0.1', '4.0.2', '4.0.3', '4.0.4', '4.1', '4.1.1', '4.1.2', '4.2', '4.2.1', '4.2.2', '4.3', @@ -31,35 +31,35 @@ class Provider(BaseProvider): '7.0', '7.1', '7.1.1', '7.1.2', '8.0.0', '8.1.0', '9', '10', '11', ) - apple_devices = ('iPhone', 'iPad') + apple_devices: ElementsType = ('iPhone', 'iPad') - ios_versions = ( + ios_versions: ElementsType = ( '3.1.3', '4.2.1', '5.1.1', '6.1.6', '7.1.2', '9.3.5', '9.3.6', '10.3.3', '10.3.4', '12.4.8', '14.2', '14.2.1', ) - def mac_processor(self): + def mac_processor(self) -> str: """Generate a MacOS processor token used in user agent strings.""" return self.random_element(self.mac_processors) - def linux_processor(self): + def linux_processor(self) -> str: """Generate a Linux processor token used in user agent strings.""" return self.random_element(self.linux_processors) - def user_agent(self): + def user_agent(self) -> str: """Generate a random web browser user agent string.""" - name = self.random_element(self.user_agents) + name: str = self.random_element(self.user_agents) return getattr(self, name)() - def chrome(self, version_from=13, version_to=63, - build_from=800, build_to=899): + def chrome(self, version_from: int = 13, version_to: int = 63, + build_from: int = 800, build_to: int = 899) -> str: """Generate a Chrome web browser user agent string.""" - saf = f'{self.generator.random.randint(531, 536)}.{self.generator.random.randint(0, 2)}' - bld = self.lexify(self.numerify('##?###'), string.ascii_uppercase) - tmplt = '({0}) AppleWebKit/{1} (KHTML, like Gecko)' \ - ' Chrome/{2}.0.{3}.0 Safari/{4}' - tmplt_ios = '({0}) AppleWebKit/{1} (KHTML, like Gecko)' \ - ' CriOS/{2}.0.{3}.0 Mobile/{4} Safari/{1}' - platforms = ( + saf: str = f'{self.generator.random.randint(531, 536)}.{self.generator.random.randint(0, 2)}' + bld: str = self.lexify(self.numerify('##?###'), string.ascii_uppercase) + tmplt: str = '({0}) AppleWebKit/{1} (KHTML, like Gecko)' \ + ' Chrome/{2}.0.{3}.0 Safari/{4}' + tmplt_ios: str = '({0}) AppleWebKit/{1} (KHTML, like Gecko)' \ + ' CriOS/{2}.0.{3}.0 Mobile/{4} Safari/{1}' + platforms: ElementsType = ( tmplt.format(self.linux_platform_token(), saf, self.generator.random.randint(version_from, version_to), @@ -89,25 +89,25 @@ def chrome(self, version_from=13, version_to=63, return 'Mozilla/5.0 ' + self.random_element(platforms) - def firefox(self): + def firefox(self) -> str: """Generate a Mozilla Firefox web browser user agent string.""" - ver = ( + ver: ElementsType = ( (f'Gecko/{self.generator.date_time_between(datetime(2011, 1, 1))} ' f'Firefox/{self.generator.random.randint(4, 15)}.0'), (f'Gecko/{self.generator.date_time_between(datetime(2010, 1, 1))} ' f'Firefox/3.6.{self.generator.random.randint(1, 20)}'), f'Gecko/{self.generator.date_time_between(datetime(2010, 1, 1))} Firefox/3.8', ) - tmplt_win = '({0}; {1}; rv:1.9.{2}.20) {3}' - tmplt_lin = '({0}; rv:1.9.{1}.20) {2}' - tmplt_mac = '({0}; rv:1.9.{1}.20) {2}' - tmplt_and = '({0}; Mobile; rv:{1}.0) Gecko/{1}.0 Firefox/{1}.0' - tmplt_ios = '({0}) AppleWebKit/{1} (KHTML, like Gecko) FxiOS/{2}.{3}.0 Mobile/{4} Safari/{1}' - saf = '{}.{}'.format(self.generator.random.randint(531, 536), - self.generator.random.randint(0, 2)) - bld = self.lexify(self.numerify('##?###'), string.ascii_uppercase) - bld2 = self.lexify(self.numerify('#?####'), string.ascii_lowercase) - platforms = ( + tmplt_win: str = '({0}; {1}; rv:1.9.{2}.20) {3}' + tmplt_lin: str = '({0}; rv:1.9.{1}.20) {2}' + tmplt_mac: str = '({0}; rv:1.9.{1}.20) {2}' + tmplt_and: str = '({0}; Mobile; rv:{1}.0) Gecko/{1}.0 Firefox/{1}.0' + tmplt_ios: str = '({0}) AppleWebKit/{1} (KHTML, like Gecko) FxiOS/{2}.{3}.0 Mobile/{4} Safari/{1}' + saf: str = '{}.{}'.format(self.generator.random.randint(531, 536), + self.generator.random.randint(0, 2)) + bld: str = self.lexify(self.numerify('##?###'), string.ascii_uppercase) + bld2: str = self.lexify(self.numerify('#?####'), string.ascii_lowercase) + platforms: ElementsType = ( tmplt_win.format(self.windows_platform_token(), self.generator.locale().replace('_', '-'), self.generator.random.randint(0, 2), @@ -129,24 +129,25 @@ def firefox(self): return 'Mozilla/5.0 ' + self.random_element(platforms) - def safari(self): + def safari(self) -> str: """Generate a Safari web browser user agent string.""" - saf = (f'{self.generator.random.randint(531, 535)}.' - f'{self.generator.random.randint(1, 50)}.' - f'{self.generator.random.randint(1, 7)}') - if not self.generator.random.getrandbits(1): - ver = f'{self.generator.random.randint(4, 5)}.{self.generator.random.randint(0, 1)}' - else: - ver = f'{self.generator.random.randint(4, 5)}.0.{self.generator.random.randint(1, 5)}' - tmplt_win = '(Windows; U; {0}) AppleWebKit/{1} (KHTML, like Gecko)' \ - ' Version/{2} Safari/{3}' - tmplt_mac = '({0} rv:{1}.0; {2}) AppleWebKit/{3} (KHTML, like Gecko)' \ - ' Version/{4} Safari/{5}' - tmplt_ipod = '(iPod; U; CPU iPhone OS {0}_{1} like Mac OS X; {2})' \ - ' AppleWebKit/{3} (KHTML, like Gecko) Version/{4}.0.5' \ - ' Mobile/8B{5} Safari/6{6}' - locale = self.generator.locale().replace('_', '-') - platforms = ( + saf: str = (f'{self.generator.random.randint(531, 535)}.' + f'{self.generator.random.randint(1, 50)}.' + f'{self.generator.random.randint(1, 7)}') + + ver: str = f'{self.generator.random.randint(4, 5)}.{self.generator.random.randint(0, 1)}' \ + if not self.generator.random.getrandbits(1) else \ + f'{self.generator.random.randint(4, 5)}.0.{self.generator.random.randint(1, 5)}' + + tmplt_win: str = '(Windows; U; {0}) AppleWebKit/{1} (KHTML, like Gecko)' \ + ' Version/{2} Safari/{3}' + tmplt_mac: str = '({0} rv:{1}.0; {2}) AppleWebKit/{3} (KHTML, like Gecko)' \ + ' Version/{4} Safari/{5}' + tmplt_ipod: str = '(iPod; U; CPU iPhone OS {0}_{1} like Mac OS X; {2})' \ + ' AppleWebKit/{3} (KHTML, like Gecko) Version/{4}.0.5' \ + ' Mobile/8B{5} Safari/6{6}' + locale: str = self.generator.locale().replace('_', '-') + platforms: ElementsType = ( tmplt_win.format(self.windows_platform_token(), saf, ver, @@ -168,39 +169,41 @@ def safari(self): return 'Mozilla/5.0 ' + self.random_element(platforms) - def opera(self): + def opera(self) -> str: """Generate an Opera web browser user agent string.""" - token = self.linux_platform_token() if self.generator.random.getrandbits(1) else self.windows_platform_token() - locale = self.generator.locale().replace('_', '-') - platform = (f'({token}; {locale}) Presto/2.9.{self.generator.random.randint(160, 190)} ' - f'Version/{self.generator.random.randint(10, 12)}.00') + token: str = self.linux_platform_token() if self.generator.random.getrandbits(1) \ + else self.windows_platform_token() + locale: str = self.generator.locale().replace('_', '-') + platform: str = (f'({token}; {locale}) Presto/2.9.{self.generator.random.randint(160, 190)} ' + f'Version/{self.generator.random.randint(10, 12)}.00') return f'Opera/{self.generator.random.randint(8, 9)}.{self.generator.random.randint(10, 99)}.{platform}' - def internet_explorer(self): + def internet_explorer(self) -> str: """Generate an IE web browser user agent string.""" return (f'Mozilla/5.0 (compatible; MSIE {self.generator.random.randint(5, 9)}.0; ' f'{self.windows_platform_token()}; ' f'Trident/{self.generator.random.randint(3, 5)}.{self.generator.random.randint(0, 1)})') - def windows_platform_token(self): + def windows_platform_token(self) -> str: """Generate a Windows platform token used in user agent strings.""" return self.random_element(self.windows_platform_tokens) - def linux_platform_token(self): + def linux_platform_token(self) -> str: """Generate a Linux platform token used in user agent strings.""" return f'X11; Linux {self.random_element(self.linux_processors)}' - def mac_platform_token(self): + def mac_platform_token(self) -> str: """Generate a MacOS platform token used in user agent strings.""" return (f'Macintosh; {self.random_element(self.mac_processors)} Mac OS X 10_' f'{self.generator.random.randint(5, 12)}_{self.generator.random.randint(0, 9)}') - def android_platform_token(self): + def android_platform_token(self) -> str: """Generate an Android platform token used in user agent strings.""" return f'Android {self.random_element(self.android_versions)}' - def ios_platform_token(self): + def ios_platform_token(self) -> str: """Generate an iOS platform token used in user agent strings.""" - apple_device = self.random_element(self.apple_devices) + apple_device: str = self.random_element(self.apple_devices) + ios_version: str = self.random_element(self.ios_versions) return (f'{apple_device}; CPU {apple_device} ' - f'OS {self.random_element(self.ios_versions).replace(".", "_")} like Mac OS X') + f'OS {ios_version.replace(".", "_")} like Mac OS X') diff --git a/faker/proxy.py b/faker/proxy.py index 25d29525d1..cce4e39342 100644 --- a/faker/proxy.py +++ b/faker/proxy.py @@ -4,12 +4,14 @@ import re from collections import OrderedDict +from random import Random +from typing import Any, Callable, Dict, Hashable, List, Optional, Pattern, Sequence, Tuple, Union -from faker.config import DEFAULT_LOCALE -from faker.exceptions import UniquenessException -from faker.factory import Factory -from faker.generator import Generator -from faker.utils.distribution import choices_distribution +from .config import DEFAULT_LOCALE +from .exceptions import UniquenessException +from .factory import Factory +from .generator import Generator +from .utils.distribution import choices_distribution _UNIQUE_ATTEMPTS = 1000 @@ -17,16 +19,20 @@ class Faker: """Proxy class capable of supporting multiple locales""" - cache_pattern = re.compile(r'^_cached_\w*_mapping$') + cache_pattern: Pattern = re.compile(r'^_cached_\w*_mapping$') generator_attrs = [ attr for attr in dir(Generator) if not attr.startswith('__') and attr not in ['seed', 'seed_instance', 'random'] ] - def __init__(self, locale=None, providers=None, - generator=None, includes=None, - use_weighting=True, **config): + def __init__(self, + locale: Optional[Union[str, Sequence[str], Dict[str, Union[int, float]]]] = None, + providers: Optional[List[str]] = None, + generator: Optional[Generator] = None, + includes: Optional[List[str]] = None, + use_weighting: bool = True, + **config: Any) -> None: self._factory_map = OrderedDict() self._weights = None self._unique_proxy = UniqueProxy(self) @@ -73,10 +79,10 @@ def __dir__(self): } return sorted(attributes) - def __getitem__(self, locale): + def __getitem__(self, locale: str) -> Generator: return self._factory_map[locale.replace('-', '_')] - def __getattribute__(self, attr): + def __getattribute__(self, attr: str) -> Any: """ Handles the "attribute resolution" behavior for declared members of this proxy class @@ -94,7 +100,7 @@ def __getattribute__(self, attr): else: return super().__getattribute__(attr) - def __getattr__(self, attr): + def __getattr__(self, attr: str) -> Any: """ Handles cache access and proxying behavior @@ -113,7 +119,7 @@ def __getattr__(self, attr): factory = self._select_factory(attr) return getattr(factory, attr) - def __deepcopy__(self, memodict={}): + def __deepcopy__(self, memodict: Dict = {}) -> 'Faker': cls = self.__class__ result = cls.__new__(cls) result._locales = copy.deepcopy(self._locales) @@ -127,14 +133,14 @@ def __deepcopy__(self, memodict={}): } return result - def __setstate__(self, state): + def __setstate__(self, state: Any) -> None: self.__dict__.update(state) @property - def unique(self): + def unique(self) -> 'UniqueProxy': return self._unique_proxy - def _select_factory(self, method_name): + def _select_factory(self, method_name: str) -> Factory: """ Returns a random factory that supports the provider method @@ -155,7 +161,7 @@ def _select_factory(self, method_name): factory = random.choice(factories) return factory - def _map_provider_method(self, method_name): + def _map_provider_method(self, method_name: str) -> Tuple[List[Factory], Optional[List[float]]]: """ Creates a 2-tuple of factories and weights for the given provider method name @@ -182,26 +188,26 @@ def _map_provider_method(self, method_name): mapping = list(factories), list(weights) else: value = [ - factory + factory # type: ignore for factory in self.factories if hasattr(factory, method_name) ] - mapping = value, None + mapping = value, None # type: ignore # Then cache and return results setattr(self, attr, mapping) return mapping @classmethod - def seed(cls, seed=None): + def seed(cls, seed: Optional[Hashable] = None) -> None: """ - Seeds the shared `random.Random` object across all factories + Hashables the shared `random.Random` object across all factories :param seed: seed value """ Generator.seed(seed) - def seed_instance(self, seed=None): + def seed_instance(self, seed: Optional[Hashable] = None) -> None: """ Creates and seeds a new `random.Random` object for each factory @@ -210,7 +216,7 @@ def seed_instance(self, seed=None): for factory in self._factories: factory.seed_instance(seed) - def seed_locale(self, locale, seed=None): + def seed_locale(self, locale: str, seed: Optional[Hashable] = None) -> None: """ Creates and seeds a new `random.Random` object for the factory of the specified locale @@ -220,7 +226,7 @@ def seed_locale(self, locale, seed=None): self._factory_map[locale.replace('-', '_')].seed_instance(seed) @property - def random(self): + def random(self) -> Random: """ Proxies `random` getter calls @@ -236,7 +242,7 @@ def random(self): raise NotImplementedError(msg) @random.setter - def random(self, value): + def random(self, value: Random) -> None: """ Proxies `random` setter calls @@ -252,31 +258,31 @@ def random(self, value): raise NotImplementedError(msg) @property - def locales(self): + def locales(self) -> List[str]: return list(self._locales) @property - def weights(self): + def weights(self) -> Optional[List[Union[int, float]]]: return self._weights @property - def factories(self): + def factories(self) -> List[Generator]: return self._factories - def items(self): - return self._factory_map.items() + def items(self) -> List[Tuple[str, Generator]]: + return list(self._factory_map.items()) class UniqueProxy: - def __init__(self, proxy): + def __init__(self, proxy: Faker): self._proxy = proxy - self._seen = {} + self._seen: Dict = {} self._sentinel = object() - def clear(self): + def clear(self) -> None: self._seen = {} - def __getattr__(self, name: str): + def __getattr__(self, name: str) -> Any: obj = getattr(self._proxy, name) if callable(obj): return self._wrap(name, obj) @@ -293,7 +299,7 @@ def __getstate__(self): def __setstate__(self, state): self.__dict__.update(state) - def _wrap(self, name, function): + def _wrap(self, name: str, function: Callable) -> Callable: @functools.wraps(function) def wrapper(*args, **kwargs): key = (name, args, tuple(sorted(kwargs.items()))) diff --git a/faker/sphinx/docstring.py b/faker/sphinx/docstring.py index 9d808b797f..ab8250e9d3 100644 --- a/faker/sphinx/docstring.py +++ b/faker/sphinx/docstring.py @@ -4,6 +4,7 @@ import re from collections import namedtuple +from typing import Pattern from faker import Faker from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE @@ -11,15 +12,15 @@ logger = logging.getLogger(__name__) _fake = Faker(AVAILABLE_LOCALES) -_base_provider_method_pattern = re.compile(r'^faker\.providers\.BaseProvider\.(?P\w+)$') -_standard_provider_method_pattern = re.compile(r'^faker\.providers\.\w+\.Provider\.(?P\w+)$') -_locale_provider_method_pattern = re.compile( +_base_provider_method_pattern: Pattern = re.compile(r'^faker\.providers\.BaseProvider\.(?P\w+)$') +_standard_provider_method_pattern: Pattern = re.compile(r'^faker\.providers\.\w+\.Provider\.(?P\w+)$') +_locale_provider_method_pattern: Pattern = re.compile( r'^faker\.providers\.\w+' r'\.(?P[a-z]{2,3}_[A-Z]{2})' r'\.Provider' r'\.(?P\w+)$', ) -_sample_line_pattern = re.compile( +_sample_line_pattern: Pattern = re.compile( r'^:sample' r'(?: size=(?P[1-9][0-9]*))?' r'(?: seed=(?P[0-9]+))?' diff --git a/faker/typing.py b/faker/typing.py new file mode 100644 index 0000000000..b855c25c2c --- /dev/null +++ b/faker/typing.py @@ -0,0 +1,11 @@ +from datetime import date, datetime, timedelta +from typing import Sequence, TypeVar, Union + +try: + from typing import Literal # type: ignore +except ImportError: + from typing_extensions import Literal # type: ignore + +DateParseType = Union[date, datetime, timedelta, str, int] +HueType = TypeVar('HueType', str, float, Sequence[int]) +GenderType = TypeVar("GenderType", bound=Literal['M', 'F']) diff --git a/faker/utils/decorators.py b/faker/utils/decorators.py index 718a72c54e..46a49e39ba 100644 --- a/faker/utils/decorators.py +++ b/faker/utils/decorators.py @@ -1,32 +1,34 @@ from functools import wraps -from typing import Any, Callable, Dict, Tuple +from typing import Callable, Dict, Tuple, TypeVar -from faker.utils import text +from ..utils import text + +T = TypeVar('T') def slugify(fn: Callable) -> Callable: @wraps(fn) - def wrapper(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> str: + def wrapper(*args: Tuple[T, ...], **kwargs: Dict[str, T]) -> str: return text.slugify(fn(*args, **kwargs)) return wrapper def slugify_domain(fn: Callable) -> Callable: @wraps(fn) - def wrapper(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> str: + def wrapper(*args: Tuple[T, ...], **kwargs: Dict[str, T]) -> str: return text.slugify(fn(*args, **kwargs), allow_dots=True) return wrapper def slugify_unicode(fn: Callable) -> Callable: @wraps(fn) - def wrapper(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> str: + def wrapper(*args: Tuple[T, ...], **kwargs: Dict[str, T]) -> str: return text.slugify(fn(*args, **kwargs), allow_unicode=True) return wrapper def lowercase(fn: Callable) -> Callable: @wraps(fn) - def wrapper(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> str: + def wrapper(*args: Tuple[T, ...], **kwargs: Dict[str, T]) -> str: return fn(*args, **kwargs).lower() return wrapper diff --git a/faker/utils/distribution.py b/faker/utils/distribution.py index 93b133d48f..5dd802aee3 100644 --- a/faker/utils/distribution.py +++ b/faker/utils/distribution.py @@ -24,13 +24,14 @@ def cumsum(it: Iterable[float]) -> Generator[float, None, None]: def choices_distribution_unique( - a: Sequence[T], p: Sequence[float], random: Optional[Random] = None, length: int = 1, + a: Sequence[T], p: Optional[Sequence[float]], random: Optional[Random] = None, length: int = 1, ) -> Sequence[T]: # As of Python 3.7, there isn't a way to sample unique elements that takes # weight into account. if random is None: random = mod_random + assert p is not None assert len(a) == len(p) assert len(a) >= length, "You can't request more unique samples than elements in the dataset." @@ -51,7 +52,7 @@ def choices_distribution_unique( def choices_distribution( - a: Sequence[T], p: Sequence[float], random: Optional[Random] = None, length: int = 1, + a: Sequence[T], p: Optional[Sequence[float]], random: Optional[Random] = None, length: int = 1, ) -> Sequence[T]: if random is None: random = mod_random @@ -68,9 +69,9 @@ def choices_distribution( choices = [] if p is None: - p = itertools.repeat(1, len(a)) + p = itertools.repeat(1, len(a)) # type: ignore - cdf = list(cumsum(p)) + cdf = list(cumsum(p)) # type: ignore normal = cdf[-1] cdf2 = [i / normal for i in cdf] for i in range(length): diff --git a/faker/utils/loading.py b/faker/utils/loading.py index e60db12e20..3ede83bc39 100644 --- a/faker/utils/loading.py +++ b/faker/utils/loading.py @@ -4,7 +4,7 @@ from importlib import import_module from pathlib import Path from types import ModuleType -from typing import List, Set +from typing import List def get_path(module: ModuleType) -> str: @@ -18,7 +18,7 @@ def get_path(module: ModuleType) -> str: # others lib_dir = Path(sys.executable).parent / 'lib' - path = lib_dir.joinpath(*module.__package__.split(".")) + path = lib_dir.joinpath(*module.__package__.split(".")) # type: ignore else: # unfrozen path = Path(module.__file__).parent @@ -36,7 +36,7 @@ def list_module(module: ModuleType) -> List[str]: def find_available_locales(providers: List[str]) -> List[str]: - available_locales: Set[str] = set() + available_locales = set() for provider_path in providers: @@ -44,8 +44,7 @@ def find_available_locales(providers: List[str]) -> List[str]: if getattr(provider_module, 'localized', False): langs = list_module(provider_module) available_locales.update(langs) - available_locales: List[str] = sorted(available_locales) - return available_locales + return sorted(available_locales) def find_available_providers(modules: List[ModuleType]) -> List[str]: diff --git a/faker/utils/text.py b/faker/utils/text.py index 7bc3e84770..a0df590364 100644 --- a/faker/utils/text.py +++ b/faker/utils/text.py @@ -1,9 +1,11 @@ import re import unicodedata -_re_pattern = re.compile(r'[^\w\s-]', flags=re.U) -_re_pattern_allow_dots = re.compile(r'[^\.\w\s-]', flags=re.U) -_re_spaces = re.compile(r'[-\s]+', flags=re.U) +from typing import Pattern + +_re_pattern: Pattern = re.compile(r'[^\w\s-]', flags=re.U) +_re_pattern_allow_dots: Pattern = re.compile(r'[^\.\w\s-]', flags=re.U) +_re_spaces: Pattern = re.compile(r'[-\s]+', flags=re.U) def slugify(value: str, allow_dots: bool = False, allow_unicode: bool = False) -> str: @@ -14,10 +16,7 @@ def slugify(value: str, allow_dots: bool = False, allow_unicode: bool = False) - Adapted from Django 1.9 """ - if allow_dots: - pattern = _re_pattern_allow_dots - else: - pattern = _re_pattern + pattern: Pattern = _re_pattern_allow_dots if allow_dots else _re_pattern value = str(value) if allow_unicode: diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000000..ff7ed1fc46 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,11 @@ +[mypy] +disallow_subclassing_any = True +disallow_incomplete_defs = True +check_untyped_defs = True +warn_redundant_casts = True +warn_unused_ignores = False +allow_redefinition = True +pretty = True +follow_imports=silent +ignore_missing_imports = True +show_error_codes = True \ No newline at end of file diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py index cc1272a26e..f0462efa5d 100644 --- a/tests/providers/test_address.py +++ b/tests/providers/test_address.py @@ -1,5 +1,6 @@ import re +from typing import Pattern from unittest import mock import pytest @@ -1147,7 +1148,7 @@ def test_city_suffix(self, faker, num_samples): assert city_suffix in ZhTwAddressProvider.city_suffixes def test_city(self, faker, num_samples): - city_pattern = re.compile(r'(?P.*?)[市縣]?') + city_pattern: Pattern = re.compile(r'(?P.*?)[市縣]?') for _ in range(num_samples): city = faker.city() assert isinstance(city, str) @@ -1195,7 +1196,7 @@ def test_city_suffix(self, faker, num_samples): assert city_suffix in ZhCnAddressProvider.city_suffixes def test_city(self, faker, num_samples): - city_pattern = re.compile(r'.*?[市县]') + city_pattern: Pattern = re.compile(r'.*?[市县]') for _ in range(num_samples): city = faker.city() assert isinstance(city, str) @@ -1326,10 +1327,10 @@ class TestEnPh: @classmethod def setup_class(cls): - cls.building_number_pattern = re.compile( + cls.building_number_pattern: Pattern = re.compile( r'(?:[1-9]|[1-9]\d{1,3})(?:[A-J]|\s[A-J]|-[A-J]|\sUnit\s[A-J])?', ) - cls.address_pattern = re.compile( + cls.address_pattern: Pattern = re.compile( r'(?P.*), (?P.*?), (?P\d{4}) (?P.*?)', ) cls.metro_manila_postcodes = EnPhAddressProvider.metro_manila_postcodes @@ -1417,7 +1418,7 @@ def test_country(self, faker, num_samples): assert country in RuRuAddressProvider.countries def test_region(self, faker, num_samples): - region_pattern = re.compile( + region_pattern: Pattern = re.compile( r'(?:респ\. (?P.*))|' r'(?:(?P.*?) край)|' r'(?:(?P.*?) обл.)|' diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py index bda4b6268a..f716d560b7 100644 --- a/tests/providers/test_automotive.py +++ b/tests/providers/test_automotive.py @@ -1,5 +1,7 @@ import re +from typing import Pattern + from faker.providers.automotive.de_DE import Provider as DeDeAutomotiveProvider from faker.providers.automotive.es_ES import Provider as EsEsAutomotiveProvider from faker.providers.automotive.ro_RO import Provider as RoRoAutomotiveProvider @@ -24,7 +26,7 @@ def test_license_plate(self, faker, num_samples): class TestSkSk(_SimpleAutomotiveTestMixin): """Test sk_SK automotive provider methods""" - license_plate_pattern = re.compile(r'(?P[A-Z]{2})\d{3}[A-Z]{2}') + license_plate_pattern: Pattern = re.compile(r'(?P[A-Z]{2})\d{3}[A-Z]{2}') def perform_extra_checks(self, license_plate, match): assert match.group('prefix') in SkSkAutomotiveProvider.license_plate_prefix @@ -32,12 +34,12 @@ def perform_extra_checks(self, license_plate, match): class TestPtBr(_SimpleAutomotiveTestMixin): """Test pt_BR automotive provider methods""" - license_plate_pattern = re.compile(r'[A-Z]{3}-\d{4}') + license_plate_pattern: Pattern = re.compile(r'[A-Z]{3}-\d{4}') class TestPtPt(_SimpleAutomotiveTestMixin): """Test pt_PT automotive provider methods""" - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'\d{2}-\d{2}-[A-Z]{2}|' r'\d{2}-[A-Z]{2}-\d{2}|' r'[A-Z]{2}-\d{2}-\d{2}|' @@ -46,17 +48,17 @@ class TestPtPt(_SimpleAutomotiveTestMixin): class TestHeIl(_SimpleAutomotiveTestMixin): - license_plate_pattern = re.compile(r'(\d{3}-\d{2}-\d{3})|(\d{2}-\d{3}-\d{2})') + license_plate_pattern: Pattern = re.compile(r'(\d{3}-\d{2}-\d{3})|(\d{2}-\d{3}-\d{2})') class TestHuHu(_SimpleAutomotiveTestMixin): """Test hu_HU automotive provider methods""" - license_plate_pattern = re.compile(r'[A-Z]{3}-\d{3}') + license_plate_pattern: Pattern = re.compile(r'[A-Z]{3}-\d{3}') class TestDeDe(_SimpleAutomotiveTestMixin): """Test de_DE automotive provider methods""" - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'(?P[A-Z\u00D6\u00DC]{1,3})-[A-Z]{1,2}-[1-9]{1,4}', re.UNICODE, ) @@ -67,13 +69,13 @@ def perform_extra_checks(self, license_plate, match): class TestSvSe(_SimpleAutomotiveTestMixin): """Test sv_SE automotive provider methods""" - license_plate_pattern = re.compile(r'[A-Z]{3} \d{2}[\dA-Z]') + license_plate_pattern: Pattern = re.compile(r'[A-Z]{3} \d{2}[\dA-Z]') class TestPlPl: def test_License_plate(self, faker, num_samples): - pattern = re.compile(r'{patterns}'.format(patterns='|'.join(faker.license_plate_regex_formats()))) + pattern: Pattern = re.compile(r'{patterns}'.format(patterns='|'.join(faker.license_plate_regex_formats()))) for _ in range(num_samples): plate = faker.license_plate() assert pattern.fullmatch(plate) @@ -81,9 +83,9 @@ def test_License_plate(self, faker, num_samples): class TestEnPh(_SimpleAutomotiveTestMixin): """Test en_PH automotive provider methods""" - license_plate_pattern = re.compile(r'[A-Z]{2}\d{4,5}|[A-Z]{3}\d{3,4}') - motorcycle_pattern = re.compile(r'[A-Z]{2}\d{4,5}') - automobile_pattern = re.compile(r'[A-Z]{3}\d{3,4}') + license_plate_pattern: Pattern = re.compile(r'[A-Z]{2}\d{4,5}|[A-Z]{3}\d{3,4}') + motorcycle_pattern: Pattern = re.compile(r'[A-Z]{2}\d{4,5}') + automobile_pattern: Pattern = re.compile(r'[A-Z]{3}\d{3,4}') def test_motorcycle_plate(self, faker, num_samples): for _ in range(num_samples): @@ -112,7 +114,7 @@ class TestTlPh(TestEnPh): class TestRuRu(_SimpleAutomotiveTestMixin): """Test ru_RU automotive provider methods""" _plate_letters = ''.join(RuRuAutomotiveProvider.license_plate_letters) - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'(?:' r'(?P[{0}]\d\d\d[{0}][{0}])|' r'(?P[{0}][{0}]\d\d\d)|' @@ -136,18 +138,18 @@ def test_vehicle_category(self, faker, num_samples): class TestFrFr(_SimpleAutomotiveTestMixin): """Test fr_FR automotive provider methods""" - license_plate_pattern = re.compile(r'\d{3}-[A-Z]{3}-\d{2}|[A-Z]{2}-\d{3}-[A-Z]{2}') + license_plate_pattern: Pattern = re.compile(r'\d{3}-[A-Z]{3}-\d{2}|[A-Z]{2}-\d{3}-[A-Z]{2}') class TestNoNo(_SimpleAutomotiveTestMixin): """Test no_NO automotive provider methods""" - license_plate_pattern = re.compile(r'[A-Z]{2} \d{5}') + license_plate_pattern: Pattern = re.compile(r'[A-Z]{2} \d{5}') class TestEsEs: """Test es_ES automotive provider methods""" - new_format_pattern = re.compile(r'\d{4}\s[A-Z]{3}') - old_format_pattern = re.compile(r'(?P[A-Z]{1,2})\s\d{4}\s[A-Z]{2}') + new_format_pattern: Pattern = re.compile(r'\d{4}\s[A-Z]{3}') + old_format_pattern: Pattern = re.compile(r'(?P[A-Z]{1,2})\s\d{4}\s[A-Z]{2}') def test_plate_new_format(self, faker, num_samples): for _ in range(num_samples): @@ -179,7 +181,7 @@ def test_plate_format(self, faker, num_samples): class TestThTh(_SimpleAutomotiveTestMixin): """Test th_TH automotive provider methods""" - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'(\d [ก-ฮ]{2} \d{1,4})|' # car r'([ก-ฮ]{2} \d{1,4})|' # car r'([ก-ฮ]{3} \d{1,3})|' # motorcycle @@ -189,7 +191,7 @@ class TestThTh(_SimpleAutomotiveTestMixin): class TestTrTr(_SimpleAutomotiveTestMixin): """Test tr_TR automotive provider methods""" - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'\d{2} [A-Z] \d{4}|' r'\d{2} [A-Z] \d{5}|' r'\d{2} [A-Z]{2} \d{3}|' @@ -206,7 +208,7 @@ def perform_extra_checks(self, license_plate, match): class TestRoRo(_SimpleAutomotiveTestMixin): """Test ro_RO automotive provider methods""" - license_plate_pattern = re.compile( + license_plate_pattern: Pattern = re.compile( r'(?P[A-Z]{1,2})-\d{2,3}-[A-Z]{3}') def perform_extra_checks(self, license_plate, match): diff --git a/tests/providers/test_barcode.py b/tests/providers/test_barcode.py index 2fa1335bdc..e5383a9de7 100644 --- a/tests/providers/test_barcode.py +++ b/tests/providers/test_barcode.py @@ -1,13 +1,15 @@ import re +from typing import Pattern + import pytest class TestBarcodeProvider: """Test barcode provider methods""" num_samples = 1000 - ean8_pattern = re.compile(r'\d{8}') - ean13_pattern = re.compile(r'\d{13}') + ean8_pattern: Pattern = re.compile(r'\d{8}') + ean13_pattern: Pattern = re.compile(r'\d{13}') def test_ean(self, faker, num_samples): for _ in range(num_samples): @@ -82,8 +84,8 @@ def provider(faker, provider_class): class _LocaleCommonMixin: - ean8_pattern = re.compile(r'\d{8}') - ean13_pattern = re.compile(r'\d{13}') + ean8_pattern: Pattern = re.compile(r'\d{8}') + ean13_pattern: Pattern = re.compile(r'\d{13}') @staticmethod def assert_prefix(barcode_digits, prefixes): @@ -131,8 +133,8 @@ def test_localized_ean13(self, faker, num_samples, provider): class _LocaleNorthAmericaMixin(_LocaleCommonMixin): - upc_a_pattern = re.compile(r'\d{12}') - upc_e_pattern = re.compile(r'[01]\d{7}') + upc_a_pattern: Pattern = re.compile(r'\d{12}') + upc_e_pattern: Pattern = re.compile(r'[01]\d{7}') def test_upc_a(self, faker, num_samples): for _ in range(num_samples): diff --git a/tests/providers/test_color.py b/tests/providers/test_color.py index 5ad81cecb7..7a05ec97b6 100644 --- a/tests/providers/test_color.py +++ b/tests/providers/test_color.py @@ -2,6 +2,8 @@ import random import re +from typing import Pattern + import pytest from faker.providers.color import RandomColor @@ -38,7 +40,7 @@ def test_rgb_color(self, faker, num_samples): assert 0 <= b <= 255 def test_rgb_css_color(self, faker, num_samples): - pattern = re.compile(r'rgb\((?P\d{1,3},\d{1,3},\d{1,3})\)') + pattern: Pattern = re.compile(r'rgb\((?P\d{1,3},\d{1,3},\d{1,3})\)') for _ in range(num_samples): match = pattern.fullmatch(faker.rgb_css_color()) rgb = match.group('rgb') @@ -62,25 +64,25 @@ class TestRandomColor: """Test RandomColor class""" num_samples = 1000 seed = 4761 - hsv_color_pattern = re.compile( + hsv_color_pattern: Pattern = re.compile( r'hsv\(' r'(?P\d|[1-9]\d|[1-3]\d{2}), ' r'(?P\d|[1-9]\d|100), ' r'(?P\d|[1-9]\d|100)\)', ) - hsl_color_pattern = re.compile( + hsl_color_pattern: Pattern = re.compile( r'hsl\(' r'(?P\d|[1-9]\d|[1-3]\d{2}), ' r'(?P\d|[1-9]\d|[1-3]\d{2}), ' r'(?P\d|[1-9]\d|[1-3]\d{2})\)', ) - rgb_color_pattern = re.compile( + rgb_color_pattern: Pattern = re.compile( r'rgb\(' r'(?P\d|[1-9]\d|[1-3]\d{2}), ' r'(?P\d|[1-9]\d|[1-3]\d{2}), ' r'(?P\d|[1-9]\d|[1-3]\d{2})\)', ) - hex_color_pattern = re.compile(r'#[0-9a-f]{6}') + hex_color_pattern: Pattern = re.compile(r'#[0-9a-f]{6}') def setup_method(self): self.random_color = RandomColor(seed=self.seed) @@ -242,7 +244,7 @@ def test_bad_color_map(self): # If we remove 62 from the yellow range, calling the previous function should fail colormap = copy.deepcopy(self.random_color.colormap) - colormap['yellow']['hue_range'] = [47, 61] + colormap['yellow']['hue_range'] = [(47, 61)] self.random_color.colormap = colormap with pytest.raises(ValueError): self.random_color.generate(hue=62) diff --git a/tests/providers/test_company.py b/tests/providers/test_company.py index 0c1df1046f..523c3b3c63 100644 --- a/tests/providers/test_company.py +++ b/tests/providers/test_company.py @@ -1,6 +1,7 @@ import re from datetime import datetime +from typing import Pattern from unittest.mock import patch import pytest @@ -209,7 +210,7 @@ def setup_class(cls): cls.company_types = EnPhCompanyProvider.company_types cls.company_suffixes = EnPhCompanyProvider.company_suffixes.keys() cls.company_products = EnPhCompanyProvider.company_products - cls.national_corporation_pattern = re.compile(r'^National (.*?) Corporation of the Philippines$') + cls.national_corporation_pattern: Pattern = re.compile(r'^National (.*?) Corporation of the Philippines$') def test_random_company_noun_chain(self, faker, num_samples): for _ in range(num_samples): diff --git a/tests/providers/test_credit_card.py b/tests/providers/test_credit_card.py index 6c2561eb91..0b3a2d7995 100644 --- a/tests/providers/test_credit_card.py +++ b/tests/providers/test_credit_card.py @@ -1,18 +1,20 @@ import re +from typing import Pattern + from faker.providers.bank.ru_RU import Provider as RuRuBankProvider from faker.providers.credit_card import Provider as CreditCardProvider class TestCreditCardProvider: """Test credit card provider methods""" - mastercard_pattern = re.compile( + mastercard_pattern: Pattern = re.compile( r'(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}', ) - visa_pattern = re.compile(r'4[0-9]{12}([0-9]{3}){0,2}') - discover_pattern = re.compile(r'6(?:011|5[0-9]{2})[0-9]{12}') - diners_club_pattern = re.compile(r'3(?:0[0-5]|[68][0-9])[0-9]{11}') - jcb_pattern = re.compile(r'(?:2131|1800|35\d{3})\d{11}') + visa_pattern: Pattern = re.compile(r'4[0-9]{12}([0-9]{3}){0,2}') + discover_pattern: Pattern = re.compile(r'6(?:011|5[0-9]{2})[0-9]{12}') + diners_club_pattern: Pattern = re.compile(r'3(?:0[0-5]|[68][0-9])[0-9]{11}') + jcb_pattern: Pattern = re.compile(r'(?:2131|1800|35\d{3})\d{11}') def test_mastercard(self, faker, num_samples): provider = CreditCardProvider(faker) @@ -81,14 +83,14 @@ def test_jcb15(self, faker, num_samples): class TestRuRu: """Test ru_RU credit card provider methods""" - visa_pattern = re.compile(r'4[0-9]{15}') - mastercard_pattern = re.compile( + visa_pattern: Pattern = re.compile(r'4[0-9]{15}') + mastercard_pattern: Pattern = re.compile( r'(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}', ) - mir_pattern = re.compile(r'220[0-4][0-9]{12}') - maestro_pattern = re.compile(r'(?:50|5[6-9]|6[0-9])[0-9]{14}') - amex_pattern = re.compile(r'3[4|7][0-9]{13}') - unionpay_pattern = re.compile(r'(?:62|81)[0-9]{14}') + mir_pattern: Pattern = re.compile(r'220[0-4][0-9]{12}') + maestro_pattern: Pattern = re.compile(r'(?:50|5[6-9]|6[0-9])[0-9]{14}') + amex_pattern: Pattern = re.compile(r'3[4|7][0-9]{13}') + unionpay_pattern: Pattern = re.compile(r'(?:62|81)[0-9]{14}') def test_visa(self, faker, num_samples): for _ in range(num_samples): @@ -130,9 +132,9 @@ def test_credit_card_full(self, faker, num_samples): class TestPtPt: """Test pt_PT credit card provider methods""" - visa_pattern = re.compile(r'4[0-9]{15}') - mastercard_pattern = re.compile(r'5[1-5][0-9]{14}') - maestro_pattern = re.compile(r'(50|67)[0-9]{14}') + visa_pattern: Pattern = re.compile(r'4[0-9]{15}') + mastercard_pattern: Pattern = re.compile(r'5[1-5][0-9]{14}') + maestro_pattern: Pattern = re.compile(r'(50|67)[0-9]{14}') def test_visa(self, faker, num_samples): for _ in range(num_samples): diff --git a/tests/providers/test_internet.py b/tests/providers/test_internet.py index 28d5b1b378..a926ebacda 100644 --- a/tests/providers/test_internet.py +++ b/tests/providers/test_internet.py @@ -2,6 +2,7 @@ from ipaddress import ip_address, ip_network from itertools import cycle +from typing import Pattern from unittest.mock import PropertyMock, patch import pytest @@ -24,11 +25,11 @@ class TestInternetProvider: """Test internet provider methods""" num_samples = 100 - ipv4_pattern = re.compile( + ipv4_pattern: Pattern = re.compile( r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}' r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$', ) - ipv4_network_pattern = re.compile( + ipv4_network_pattern: Pattern = re.compile( r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}' r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' r'/(?:\d|[12]\d|3[0-2])$', @@ -271,7 +272,7 @@ def test_ipv4_distribution_selection(self): mock_choices_fn.reset_mock() provider._random_ipv4_address_from_subnets(subnets, invalid_weights) - assert mock_choices_fn.call_count == 1 + assert mock_choices_fn.call_count == 0 assert mock_random_choice.call_count == 1 def test_ipv6(self, faker, num_samples): @@ -322,12 +323,12 @@ def test_iana_id(self, faker, num_samples): assert 1 <= int(faker.iana_id()) <= 8888888 def test_ripe_id(self, faker, num_samples): - pattern = re.compile(r'^ORG-[A-Z]{2,4}[1-9]\d{0,4}-RIPE$') + pattern: Pattern = re.compile(r'^ORG-[A-Z]{2,4}[1-9]\d{0,4}-RIPE$') for _ in range(num_samples): assert pattern.fullmatch(faker.ripe_id()) def test_nic_handles(self, faker, num_samples): - pattern = re.compile(r'^[A-Z]{2,4}[1-9]\d{0,4}-[A-Z]*') + pattern: Pattern = re.compile(r'^[A-Z]{2,4}[1-9]\d{0,4}-[A-Z]*') for _ in range(num_samples): nhs = faker.nic_handles() for nh in nhs: diff --git a/tests/providers/test_misc.py b/tests/providers/test_misc.py index 3541359735..5e3ceb3640 100644 --- a/tests/providers/test_misc.py +++ b/tests/providers/test_misc.py @@ -13,6 +13,7 @@ except ImportError: PIL = None +from typing import Pattern from unittest.mock import patch import pytest @@ -57,7 +58,7 @@ class TestMiscProvider: num_samples = 10 def test_uuid4_str(self, faker, num_samples): - pattern = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}') + pattern: Pattern = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}') for _ in range(num_samples): assert pattern.fullmatch(faker.uuid4()) diff --git a/tests/providers/test_phone_number.py b/tests/providers/test_phone_number.py index 287cfae59a..64228ad74c 100644 --- a/tests/providers/test_phone_number.py +++ b/tests/providers/test_phone_number.py @@ -1,5 +1,7 @@ import re +from typing import Pattern + from faker.providers.phone_number import Provider as PhoneNumberProvider from faker.providers.phone_number.en_PH import Provider as EnPhPhoneNumberProvider @@ -25,7 +27,7 @@ class TestJaJp: def test_phone_number(self, faker, num_samples): for _ in range(num_samples): - pattern = re.compile(r'(?:0[789]0|\d{2})-\d{4}-\d{4}') + pattern: Pattern = re.compile(r'(?:0[789]0|\d{2})-\d{4}-\d{4}') phone_number = faker.phone_number() assert pattern.fullmatch(phone_number) @@ -34,7 +36,7 @@ class TestPtBr: """Test pt_BR phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'(?:\+55 )?' r'(?:[1-8]1|84|\((?:0[1-8]1|084)\))' r' \d{4}[ -]\d{4}|' @@ -45,13 +47,13 @@ def test_phone_number(self, faker, num_samples): assert pattern.fullmatch(phone_number) def test_msisdn(self, faker, num_samples): - pattern = re.compile(r'55(?:[1-8]19|849)\d{8}') + pattern: Pattern = re.compile(r'55(?:[1-8]19|849)\d{8}') for _ in range(num_samples): msisdn = faker.msisdn() assert pattern.fullmatch(msisdn) def test_cellphone(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'(?:\+55 )?' r'(?:\d{2}|\(0?\d{2}\))' r' 9 ?\d{4}[ -]\d{4}', @@ -61,7 +63,7 @@ def test_cellphone(self, faker, num_samples): assert pattern.fullmatch(cellphone) def test_service_phone(self, faker, num_samples): - pattern = re.compile(r'1(?:0|2|5|8|9)?(?:[0-9])') + pattern: Pattern = re.compile(r'1(?:0|2|5|8|9)?(?:[0-9])') for _ in range(num_samples): service = faker.service_phone_number() assert pattern.fullmatch(service) @@ -71,7 +73,7 @@ class TestHuHu: """Test hu_HU phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'(?:' r'\+36 \d{2} |' r'\(06\)\d{2}/|' @@ -90,7 +92,7 @@ class TestThTh: """Test th_TH phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( # leading zero or internaional code r'((\+66)|\+66[ -]?\(0\)|0)[ -]?' # landline or mobile @@ -109,7 +111,7 @@ class TestHyAm: """Test hy_AM phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'(?:[23]\d{2}-|\([23]\d{2}\) |[23]\d{2}\.)\d{5}|' r'(?:(?:10|9\d)-|\((?:10|9\d)\) |(?:10|9\d)\.)\d{6}', ) @@ -124,9 +126,9 @@ class TestEnPh: @classmethod def setup_class(cls): - cls.mobile_number_pattern = re.compile(r'^(?:0|\+63)(\d+)-\d{3}-\d{4}$') - cls.area2_landline_number_pattern = re.compile(r'^(?:0|\+63)2-(\d{4})-\d{4}') - cls.non_area2_landline_number_pattern = re.compile(r'^(?:0|\+63)(\d{2})-(\d{3})-\d{4}') + cls.mobile_number_pattern: Pattern = re.compile(r'^(?:0|\+63)(\d+)-\d{3}-\d{4}$') + cls.area2_landline_number_pattern: Pattern = re.compile(r'^(?:0|\+63)2-(\d{4})-\d{4}') + cls.non_area2_landline_number_pattern: Pattern = re.compile(r'^(?:0|\+63)(\d{2})-(\d{3})-\d{4}') cls.globe_mobile_number_prefixes = EnPhPhoneNumberProvider.globe_mobile_number_prefixes cls.smart_mobile_number_prefixes = EnPhPhoneNumberProvider.smart_mobile_number_prefixes cls.sun_mobile_number_prefixes = EnPhPhoneNumberProvider.sun_mobile_number_prefixes @@ -233,7 +235,7 @@ class TestTaIn: """Test ta_IN phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'\+91 \d{3} ?\d{7}|' r'0\d{2}(-)?\d{2}(?(1)| ?)\d{6}', ) @@ -246,7 +248,7 @@ class TestEsEs: """Test es_ES phone number provider methods""" def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( r'\+34 ?(?:7[0-4]|[689]\d)\d' r'(?: \d{3} \d{3}|\d{6}| \d{2} \d{2} \d{2})', ) @@ -258,49 +260,49 @@ def test_phone_number(self, faker, num_samples): class TestArAe: """Test ar_AE phone number provider methods""" - cellphone_pattern = ( + cellphone_pattern: str = ( r'(?:\+|00)971\s?5[024568]\s?\d{3}\s?\d{4}|' r'05[024568]\s?\d{3}\s?\d{4}' ) - telephone_pattern = ( + telephone_pattern: str = ( r'(?:\+|00)971\s?[1234679]\s?\d{3}\s?\d{4}|' r'0[1234679]\s?\d{3}\s?\d{4}' ) - toll_pattern = ( + toll_pattern: str = ( r'200\d{4}|' r'600\d{6}|' r'800\d{3,7}' ) - service_phone_pattern = ( + service_phone_pattern: str = ( r'9(?:9(?:9|8|7|6|1)|01|22)' ) def test_cellphone_number(self, faker, num_samples): - pattern = re.compile(self.cellphone_pattern) + pattern: Pattern = re.compile(self.cellphone_pattern) for _ in range(num_samples): cellphone = faker.cellphone_number() assert pattern.fullmatch(cellphone) def test_telephone_number(self, faker, num_samples): - pattern = re.compile(self.telephone_pattern) + pattern: Pattern = re.compile(self.telephone_pattern) for _ in range(num_samples): telephone = faker.telephone_number() assert pattern.fullmatch(telephone) def test_toll_number(self, faker, num_samples): - pattern = re.compile(self.toll_pattern) + pattern: Pattern = re.compile(self.toll_pattern) for _ in range(num_samples): toll = faker.toll_number() assert pattern.fullmatch(toll) def test_service_phone_number(self, faker, num_samples): - pattern = re.compile(self.service_phone_pattern) + pattern: Pattern = re.compile(self.service_phone_pattern) for _ in range(num_samples): service = faker.service_phone_number() assert pattern.fullmatch(service) def test_phone_number(self, faker, num_samples): - pattern = re.compile( + pattern: Pattern = re.compile( rf'{self.cellphone_pattern}|' rf'{self.telephone_pattern}|' rf'{self.toll_pattern}|' diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py index acb82caaa8..dda0a839fc 100644 --- a/tests/providers/test_ssn.py +++ b/tests/providers/test_ssn.py @@ -3,6 +3,7 @@ from datetime import datetime from itertools import cycle +from typing import Pattern from unittest import mock import freezegun @@ -901,11 +902,11 @@ class TestEnPh(unittest.TestCase): num_sample_runs = 1000 def setUp(self): - self.sss_pattern = re.compile(r'^\d{2}-\d{7}-\d$') - self.gsis_pattern = re.compile(r'^\d{11}$') - self.philhealth_pattern = re.compile(r'^\d{2}-\d{9}-\d$') - self.pagibig_pattern = re.compile(r'^\d{4}-\d{4}-\d{4}$') - self.umid_pattern = re.compile(r'^\d{4}-\d{7}-\d$') + self.sss_pattern: Pattern = re.compile(r'^\d{2}-\d{7}-\d$') + self.gsis_pattern: Pattern = re.compile(r'^\d{11}$') + self.philhealth_pattern: Pattern = re.compile(r'^\d{2}-\d{9}-\d$') + self.pagibig_pattern: Pattern = re.compile(r'^\d{4}-\d{4}-\d{4}$') + self.umid_pattern: Pattern = re.compile(r'^\d{4}-\d{7}-\d$') self.setup_faker() def setup_faker(self): diff --git a/tests/providers/test_user_agent.py b/tests/providers/test_user_agent.py index cda2fccc3c..d64de4d947 100644 --- a/tests/providers/test_user_agent.py +++ b/tests/providers/test_user_agent.py @@ -1,14 +1,17 @@ import re +from typing import Pattern + from faker.providers.user_agent import Provider as UaProvider class TestUserAgentProvider: """Test user agent provider methods""" num_samples = 1000 - android_token_pattern = re.compile(r'Android (?P\d+(?:\.\d){0,2})') - ios_token_pattern = re.compile(r'^(?P.*?); CPU \1 OS (?P\d+(?:_\d){0,2}) like Mac OS X') - mac_token_pattern = re.compile(r'Macintosh; (?P.*?) Mac OS X 10_([5-9]|1[0-2])_(\d)') + android_token_pattern: Pattern = re.compile(r'Android (?P\d+(?:\.\d){0,2})') + ios_token_pattern: Pattern = re.compile(r'^(?P.*?); CPU \1 OS ' + + r'(?P\d+(?:_\d){0,2}) like Mac OS X') + mac_token_pattern: Pattern = re.compile(r'Macintosh; (?P.*?) Mac OS X 10_([5-9]|1[0-2])_(\d)') def test_android_platform_token(self, faker, num_samples): for _ in range(num_samples): diff --git a/tox.ini b/tox.ini index ab7361317d..2e936f112b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py{36,37,38,39,py3},32bit,alpine,flake8,checkmanifest,isort +envlist=py{36,37,38,39,py3},32bit,alpine,flake8,checkmanifest,isort,mypy skip_missing_interpreters = true [testenv] @@ -39,6 +39,13 @@ deps = commands = {envpython} -m isort --check-only --diff . +[testenv:mypy] +basepython = python +deps = + mypy>=0.910 +commands = + mypy --install-types --non-interactive --config mypy.ini faker + [testenv:32bit] basepython = python passenv = TEST_32BIT