Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typing [Fixed #1489!] #1536

Merged
merged 65 commits into from Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ff3ef2e
Create nl_NL
MarcelRobeer Oct 2, 2021
1d376d5
Delete nl_NL
MarcelRobeer Oct 2, 2021
ee2494e
Add date_time provider for nl_NL
MarcelRobeer Oct 2, 2021
2f56dfc
Added date_time nl_NL test case
MarcelRobeer Oct 2, 2021
74f130b
Merge branch 'joke2k:master' into master
MarcelRobeer Oct 7, 2021
dd9995d
Added nl_NL provider
MarcelRobeer Oct 7, 2021
82b4dd4
Added nl_NL test case
MarcelRobeer Oct 7, 2021
eecfaf0
Merge branch 'joke2k:master' into master
MarcelRobeer Oct 7, 2021
34f180e
Added nl_NL automotive provider
MarcelRobeer Oct 7, 2021
5990f65
Added tests for nl_NL automotive provider
MarcelRobeer Oct 7, 2021
aea16ed
flake8 fixes
MarcelRobeer Oct 7, 2021
0afa22d
flake8 fixes in test_automotive
MarcelRobeer Oct 7, 2021
7d1dc57
import order fixes
MarcelRobeer Oct 7, 2021
1c0981b
Added type annotations
MarcelRobeer Oct 10, 2021
b5673a8
mypy fixes
MarcelRobeer Oct 10, 2021
33b4054
isort fixes
MarcelRobeer Oct 10, 2021
2201cc8
minor flake8 fixes
MarcelRobeer Oct 10, 2021
f5a9985
Fixed circular import error in generator.py
MarcelRobeer Oct 10, 2021
64a2bfd
Circular import error fix
MarcelRobeer Oct 10, 2021
f2fee0a
Typing fixes for OrderedDict
MarcelRobeer Oct 10, 2021
28f7daa
OrderedDict Python 3.6 fix
MarcelRobeer Oct 10, 2021
80ac094
OrderedDictType fix in proxy
MarcelRobeer Oct 10, 2021
a7d257e
Added mypy test to tox.ini
MarcelRobeer Oct 10, 2021
1cf54eb
Update tox.ini
MarcelRobeer Oct 10, 2021
ff450d6
Update tox.ini
MarcelRobeer Oct 10, 2021
4fbb820
PyPy is incompatible with mypy
MarcelRobeer Oct 10, 2021
1bb4e05
Update tox.ini
MarcelRobeer Oct 10, 2021
72ef6da
Removed `automotive` provider `nl_NL`
MarcelRobeer Oct 11, 2021
fc1a851
Typo
MarcelRobeer Oct 11, 2021
bc93220
Many typing fixes
MarcelRobeer Oct 11, 2021
2d201e1
Added ElementsType (input for `BaseProvider.random_element()`)
MarcelRobeer Oct 12, 2021
951a0eb
First typing fixes in date_time
MarcelRobeer Oct 12, 2021
7acf2b1
Minor Typing fixes to date_time
MarcelRobeer Oct 12, 2021
6ea03fd
Typing fixes in `providers.company`
MarcelRobeer Oct 12, 2021
ca8ae4f
Minor typing fixes in `providers.barcode`
MarcelRobeer Oct 12, 2021
b026a0e
Minor typing fixes in `providers.address`
MarcelRobeer Oct 12, 2021
57a222b
Minor typing fixes in `providers.person`
MarcelRobeer Oct 12, 2021
a839ef0
Update decorators.py
MarcelRobeer Oct 12, 2021
ecd1224
Minor typing fixes in `providers.automotive`
MarcelRobeer Oct 12, 2021
43b5aab
Import typing.Pattern in test files
MarcelRobeer Oct 12, 2021
b90c6b8
Added type: ignore[attr-defined] hotfix
MarcelRobeer Oct 12, 2021
4225aa6
Added final missing Pattern imports
MarcelRobeer Oct 12, 2021
926c88b
Optional distrib, flake8 fix in test_user_agent
MarcelRobeer Oct 12, 2021
163d774
Minor typing fixes
MarcelRobeer Oct 12, 2021
100a0ee
Literal not supported before Python 3.8
MarcelRobeer Oct 12, 2021
3053b43
Bug fix in datetime.fromtimestamp
MarcelRobeer Oct 12, 2021
5eb091a
Fixed broken tests
MarcelRobeer Oct 12, 2021
b564666
Fixed test_ipv4_distribution_selection
MarcelRobeer Oct 13, 2021
f3addca
Update decimal in `geo.el_GR`
MarcelRobeer Oct 13, 2021
a67540f
Add mypy config and improve command for tox
nicarl Oct 13, 2021
d716a65
Fix last type errors
nicarl Oct 13, 2021
8bf0616
Merge pull request #1 from nicarl/fix_last_type_errors
MarcelRobeer Oct 14, 2021
5fc2af5
Updated MANIFEST.in to include mypy.ini
MarcelRobeer Oct 14, 2021
9786240
Renamed typing.py to typing.pyi
MarcelRobeer Oct 14, 2021
2b37692
Some Python versions don't like .pyi
MarcelRobeer Oct 14, 2021
5027aa1
Updated coding_style.rst
MarcelRobeer Oct 14, 2021
cfc1190
Added mypy to .github/workflows/ci.yml
MarcelRobeer Oct 14, 2021
23bb6d6
Merge branch 'master' into master
MarcelRobeer Oct 14, 2021
c3cf47b
Merge branch 'master' of https://github.com/MarcelRobeer/faker
MarcelRobeer Oct 14, 2021
85a225c
Added dependency order to ci.yml
MarcelRobeer Oct 16, 2021
b9c76f5
Python 3.10 to "3.10" in ci.yml
MarcelRobeer Oct 16, 2021
79ee364
Unused ignores across versions
MarcelRobeer Oct 16, 2021
d05ef2e
Show error codes
MarcelRobeer Oct 16, 2021
4e0724c
Python 3.6 mypy fix
MarcelRobeer Oct 16, 2021
016ef66
Final changes
MarcelRobeer Oct 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion docs/coding_style.rst
Expand Up @@ -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.

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion 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()
45 changes: 27 additions & 18 deletions faker/cli.py
Expand Up @@ -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 = []

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -86,7 +96,7 @@ def print_doc(provider_or_field=None,

else:
doc = documentor.Documentor(fake)
unsupported = []
unsupported: List[str] = []

while True:
try:
Expand All @@ -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:
Expand All @@ -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

Expand Down Expand Up @@ -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: '
Expand Down
2 changes: 1 addition & 1 deletion 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'

Expand Down
31 changes: 21 additions & 10 deletions 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
Expand All @@ -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):
Expand All @@ -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':
Expand Down Expand Up @@ -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__
3 changes: 2 additions & 1 deletion faker/exceptions.py
Expand Up @@ -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)
25 changes: 13 additions & 12 deletions faker/factory.py
Expand Up @@ -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__)

Expand All @@ -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 = []

Expand Down Expand Up @@ -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)

Expand All @@ -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)

Expand Down Expand Up @@ -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