Hello community,

here is the log from the commit of package python-Faker for openSUSE:Factory 
checked in at 2019-08-05 11:18:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Faker (Old)
 and      /work/SRC/openSUSE:Factory/.python-Faker.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Faker"

Mon Aug  5 11:18:08 2019 rev:12 rq:718191 version:2.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Faker/python-Faker.changes        
2019-05-27 08:36:01.619126137 +0200
+++ /work/SRC/openSUSE:Factory/.python-Faker.new.4126/python-Faker.changes      
2019-08-05 11:18:10.502516115 +0200
@@ -1,0 +2,18 @@
+Wed Jul 24 09:39:48 UTC 2019 - Marketa Calabkova <[email protected]>
+
+- update to version 2.0.0
+  * Breaking change: Only allow providers to use OrderedDict s, to 
+    avoid any more PYTHONHASHSEED problems.
+  * Remove some validations from Faker and delegate it to an 
+    external library, validators.
+  * Add an "Invalid SSN" generator to the en_US SSN Provider.
+  * Loosen version restrictions on freezegun and random2.
+  * Add date_of_birth and sex argument to pesel Provider (pl_PL).
+  * Fix datetime parsing on environments with negative offsets.
+
+-------------------------------------------------------------------
+Fri Jul 19 20:16:51 UTC 2019 - Sean Marlow <[email protected]>
+
+- Update ipaddress requirements.
+
+-------------------------------------------------------------------

Old:
----
  Faker-1.0.7.tar.gz

New:
----
  Faker-2.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Faker.spec ++++++
--- /var/tmp/diff_new_pack.2sZXjC/_old  2019-08-05 11:18:11.346515769 +0200
+++ /var/tmp/diff_new_pack.2sZXjC/_new  2019-08-05 11:18:11.346515769 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define oldpython python
 Name:           python-Faker
-Version:        1.0.7
+Version:        2.0.0
 Release:        0
 Summary:        Python package that generates fake data
 License:        MIT
@@ -27,19 +27,19 @@
 URL:            https://github.com/joke2k/faker
 Source:         
https://files.pythonhosted.org/packages/source/F/Faker/Faker-%{version}.tar.gz
 BuildRequires:  %{python_module UkPostcodeParser >= 1.1.1}
-BuildRequires:  %{python_module email_validator >= 1.0.2}
-BuildRequires:  %{python_module freezegun >= 0.3.11}
+BuildRequires:  %{python_module freezegun}
 BuildRequires:  %{python_module mock}
-BuildRequires:  %{python_module more-itertools}
 BuildRequires:  %{python_module pytest >= 3.8.0}
+BuildRequires:  %{python_module pytest-runner}
 BuildRequires:  %{python_module python-dateutil >= 2.4}
-BuildRequires:  %{python_module random2 >= 1.0.1}
+BuildRequires:  %{python_module random2}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module six >= 1.10}
 BuildRequires:  %{python_module text-unidecode >= 1.2}
+BuildRequires:  %{python_module validators >= 0.13.0}
 BuildRequires:  fdupes
-BuildRequires:  python-ipaddress
 BuildRequires:  python-rpm-macros
+BuildRequires:  python2-ipaddress
 Requires:       python-python-dateutil >= 2.4
 Requires:       python-setuptools
 Requires:       python-six >= 1.10
@@ -47,9 +47,8 @@
 Requires(post): update-alternatives
 Requires(postun): update-alternatives
 BuildArch:      noarch
-BuildRequires:  %{python_module pytest-runner}
 %ifpython2
-Requires:       python-ipaddress
+Requires:       python2-ipaddress
 Obsoletes:      %{oldpython}-fake-factory < %{version}
 Provides:       %{oldpython}-fake-factory = %{version}
 %endif

++++++ Faker-1.0.7.tar.gz -> Faker-2.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/CHANGELOG.rst 
new/Faker-2.0.0/CHANGELOG.rst
--- old/Faker-1.0.7/CHANGELOG.rst       2019-05-14 17:55:14.000000000 +0200
+++ new/Faker-2.0.0/CHANGELOG.rst       2019-07-15 16:41:26.000000000 +0200
@@ -1,6 +1,23 @@
 Changelog
 =========
 
+`2.0.0 - 15-July-2019 
<https://github.com/joke2k/faker/compare/v2.0.0...v1.0.8>`__
+----------------------------------------------------------------------------------
+* Breaking change: Only allow providers to use ``OrderedDict`` s, to avoid any 
more ``PYTHONHASHSEED`` problems. Thanks @adamchainz.
+
+`1.0.8 - 15-July-2019 
<https://github.com/joke2k/faker/compare/v1.0.7...v1.0.8>`__
+----------------------------------------------------------------------------------
+
+* Rename ``pyint`` ``min`` and ``max`` to ``min_value`` and ``max_value``. 
Thanks @francoisfreitag.
+* Remove some validations from Faker and delegate it to an external library, 
``validators``. Thanks @kingbuzzman.
+* Add an "Invalid SSN" generator to the ``en_US`` SSN Provider. Thanks 
@darrylwhiting.
+* Include "Praia" as street_prefix in ``pr_BR`` address Provider. Thanks 
@G5Olivieri.
+* Loosen version restrictions on ``freezegun`` and ``random2``. Thanks 
@timokau.
+* Add SSN provider for ``es_MX``. Thanks @mrfunnyshoes.
+* Add ``pwz`` generator for ``pl_PL``. Thanks @torm89.
+* Add ``date_of_birth`` and ``sex`` argument to ``pesel`` Provider (`pl_PL`). 
Thanks @torm89.
+* Fix datetime parsing on environments with negative offsets. Thanks 
@bluesheeptoken.
+
 `1.0.7 - 14-May-2019 
<https://github.com/joke2k/faker/compare/v1.0.6...v1.0.7>`__
 
---------------------------------------------------------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/Faker.egg-info/PKG-INFO 
new/Faker-2.0.0/Faker.egg-info/PKG-INFO
--- old/Faker-1.0.7/Faker.egg-info/PKG-INFO     2019-05-14 18:11:36.000000000 
+0200
+++ new/Faker-2.0.0/Faker.egg-info/PKG-INFO     2019-07-15 16:58:24.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: Faker
-Version: 1.0.7
+Version: 2.0.0
 Summary: Faker is a Python package that generates fake data for you.
 Home-page: https://github.com/joke2k/faker
 Author: joke2k
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/Faker.egg-info/SOURCES.txt 
new/Faker-2.0.0/Faker.egg-info/SOURCES.txt
--- old/Faker-1.0.7/Faker.egg-info/SOURCES.txt  2019-05-14 18:11:36.000000000 
+0200
+++ new/Faker-2.0.0/Faker.egg-info/SOURCES.txt  2019-07-15 16:58:24.000000000 
+0200
@@ -3,6 +3,7 @@
 LICENSE.txt
 MANIFEST.in
 README.rst
+RELEASE_PROCESS.rst
 VERSION
 setup.cfg
 setup.py
@@ -342,6 +343,7 @@
 faker/providers/ssn/en_US/__init__.py
 faker/providers/ssn/es_CA/__init__.py
 faker/providers/ssn/es_ES/__init__.py
+faker/providers/ssn/es_MX/__init__.py
 faker/providers/ssn/et_EE/__init__.py
 faker/providers/ssn/fi_FI/__init__.py
 faker/providers/ssn/fr_CH/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/MANIFEST.in new/Faker-2.0.0/MANIFEST.in
--- old/Faker-1.0.7/MANIFEST.in 2019-04-15 17:09:53.000000000 +0200
+++ new/Faker-2.0.0/MANIFEST.in 2019-07-15 16:44:46.000000000 +0200
@@ -2,6 +2,7 @@
 include LICENSE.txt
 include CONTRIBUTING.rst
 include CHANGELOG.rst
+include RELEASE_PROCESS.rst
 include VERSION
 recursive-include tests *.json
 recursive-include tests *.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/PKG-INFO new/Faker-2.0.0/PKG-INFO
--- old/Faker-1.0.7/PKG-INFO    2019-05-14 18:11:37.000000000 +0200
+++ new/Faker-2.0.0/PKG-INFO    2019-07-15 16:58:25.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: Faker
-Version: 1.0.7
+Version: 2.0.0
 Summary: Faker is a Python package that generates fake data for you.
 Home-page: https://github.com/joke2k/faker
 Author: joke2k
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/RELEASE_PROCESS.rst 
new/Faker-2.0.0/RELEASE_PROCESS.rst
--- old/Faker-1.0.7/RELEASE_PROCESS.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/Faker-2.0.0/RELEASE_PROCESS.rst 2019-07-15 16:35:50.000000000 +0200
@@ -0,0 +1,11 @@
+Release Process
+---------------
+
+1. Compile entries in ``CHANGELOG.rst``. Each entry should:
+
+  * Be in the past tense  (eg "Fix datetime on Windows")
+  * End with acknowledging the PR author(s): "Thanks @<github username>."
+
+2. Run ``bumpversion <patch|minor|major>``.
+3. Check the commit generated by ``bumpversion``, then ``git push``.
+4. Run ``make release``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/VERSION new/Faker-2.0.0/VERSION
--- old/Faker-1.0.7/VERSION     2019-05-14 18:10:06.000000000 +0200
+++ new/Faker-2.0.0/VERSION     2019-07-15 16:57:52.000000000 +0200
@@ -1 +1 @@
-1.0.7
+2.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/__init__.py 
new/Faker-2.0.0/faker/__init__.py
--- old/Faker-1.0.7/faker/__init__.py   2019-05-14 18:10:06.000000000 +0200
+++ new/Faker-2.0.0/faker/__init__.py   2019-07-15 16:57:52.000000000 +0200
@@ -1,6 +1,6 @@
 from faker.generator import Generator  # noqa F401
 from faker.factory import Factory  # noqa F401
 
-VERSION = '1.0.7'
+VERSION = '2.0.0'
 
 Faker = Factory.create
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/__init__.py 
new/Faker-2.0.0/faker/providers/__init__.py
--- old/Faker-1.0.7/faker/providers/__init__.py 2019-04-15 17:09:53.000000000 
+0200
+++ new/Faker-2.0.0/faker/providers/__init__.py 2019-07-15 16:39:47.000000000 
+0200
@@ -3,6 +3,8 @@
 import re
 import string
 
+from collections import OrderedDict
+
 from faker.utils.distribution import choices_distribution, 
choices_distribution_unique
 
 
@@ -178,6 +180,9 @@
         return self.generator.random.choice(string.ascii_uppercase)
 
     def random_elements(self, elements=('a', 'b', 'c'), length=None, 
unique=False):
+        if isinstance(elements, dict) and not isinstance(elements, 
OrderedDict):
+            raise ValueError("Use OrderedDict only to avoid dependency on 
PYTHONHASHSEED (See #363).")
+
         fn = choices_distribution_unique if unique else choices_distribution
 
         if length is None:
@@ -208,10 +213,15 @@
         """
         Returns a list of random, non-unique elements from a passed object.
 
-        If `elements` is a dictionary, the value will be used as
-        a weighting element. For example::
+        If `elements` is an OrderedDict, the value will be used as a weighting
+        element. For example::
 
-            random_element({"{{variable_1}}": 0.5, "{{variable_2}}": 0.2, 
"{{variable_3}}": 0.2, "{{variable_4}}": 0.1})
+            random_element(OrderedDict([
+                ("{{variable_1}}", 0.5),
+                ("{{variable_2}}", 0.2),
+                ("{{variable_3}}", 0.2),
+                ("{{variable_4}}": 0.1)
+            ])
 
         will have the following distribution:
             * `variable_1`: 50% probability
@@ -226,10 +236,15 @@
         """
         Returns a random element from a passed object.
 
-        If `elements` is a dictionary, the value will be used as
-        a weighting element. For example::
+        If `elements` is an OrderedDict, the value will be used as a weighting
+        element. For example::
 
-            random_element({"{{variable_1}}": 0.5, "{{variable_2}}": 0.2, 
"{{variable_3}}": 0.2, "{{variable_4}}": 0.1})
+            random_element(OrderedDict([
+                ("{{variable_1}}", 0.5),
+                ("{{variable_2}}", 0.2),
+                ("{{variable_3}}", 0.2),
+                ("{{variable_4}}": 0.1)
+            ])
 
         will have the following distribution:
             * `variable_1`: 50% probability
@@ -238,6 +253,7 @@
             * `variable_4`: 10% probability
 
         """
+
         return self.random_elements(elements, length=1)[0]
 
     def random_sample(self, elements=('a', 'b', 'c'), length=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Faker-1.0.7/faker/providers/address/no_NO/__init__.py 
new/Faker-2.0.0/faker/providers/address/no_NO/__init__.py
--- old/Faker-1.0.7/faker/providers/address/no_NO/__init__.py   2019-03-05 
18:07:52.000000000 +0100
+++ new/Faker-2.0.0/faker/providers/address/no_NO/__init__.py   2019-07-15 
16:39:47.000000000 +0200
@@ -1,6 +1,8 @@
 # coding=utf-8
 from __future__ import unicode_literals
 
+from collections import OrderedDict
+
 from .. import Provider as AddressProvider
 
 
@@ -26,9 +28,16 @@
     street_address_formats = ('{{street_name}} {{building_number}}',)
     address_formats = ('{{street_address}}, {{postcode}} {{city}}',)
     building_number_formats = ('%', '%', '%', '%?', '##', '##', '##?', '###')
-    building_number_suffixes = {
-        'A': 0.2, 'B': 0.2, 'C': 0.2, 'D': 0.1, 'E': 0.1, 'F': 0.1, 'G': 0.05,
-        'H': 0.05}
+    building_number_suffixes = OrderedDict([
+        ('A', 0.2),
+        ('B', 0.2),
+        ('C', 0.2),
+        ('D', 0.1),
+        ('E', 0.1),
+        ('F', 0.1),
+        ('G', 0.05),
+        ('H', 0.05),
+    ])
     postcode_formats = ('####',)
 
     def building_number(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Faker-1.0.7/faker/providers/address/pt_BR/__init__.py 
new/Faker-2.0.0/faker/providers/address/pt_BR/__init__.py
--- old/Faker-1.0.7/faker/providers/address/pt_BR/__init__.py   2019-03-05 
18:07:52.000000000 +0100
+++ new/Faker-2.0.0/faker/providers/address/pt_BR/__init__.py   2019-07-12 
17:17:07.000000000 +0200
@@ -53,6 +53,7 @@
         'Passarela',
         'Pátio',
         'Praça',
+        'Praia',
         'Quadra',
         'Recanto',
         'Residencial',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/date_time/__init__.py 
new/Faker-2.0.0/faker/providers/date_time/__init__.py
--- old/Faker-1.0.7/faker/providers/date_time/__init__.py       2019-04-12 
17:10:07.000000000 +0200
+++ new/Faker-2.0.0/faker/providers/date_time/__init__.py       2019-07-15 
16:35:50.000000000 +0200
@@ -6,7 +6,6 @@
 
 from calendar import timegm
 from datetime import timedelta, MAXYEAR
-from time import time
 
 from dateutil import relativedelta
 from dateutil.tz import tzlocal, tzutc
@@ -1474,7 +1473,7 @@
     @classmethod
     def _parse_end_datetime(cls, value):
         if value is None:
-            return int(time())
+            return datetime_to_timestamp(datetime.now())
 
         return cls._parse_date_time(value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/person/et_EE/__init__.py 
new/Faker-2.0.0/faker/providers/person/et_EE/__init__.py
--- old/Faker-1.0.7/faker/providers/person/et_EE/__init__.py    2017-12-05 
16:57:34.000000000 +0100
+++ new/Faker-2.0.0/faker/providers/person/et_EE/__init__.py    2019-07-15 
16:39:47.000000000 +0200
@@ -1,5 +1,8 @@
 # coding=utf-8
 from __future__ import unicode_literals
+
+from collections import OrderedDict
+
 from .. import Provider as PersonProvider
 
 
@@ -9,13 +12,20 @@
     # About 70% of the population are Estonians and about 25% are Russians
     est_rat = 0.7
     rus_rat = 1.0 - est_rat
-    formats = {'{{first_name_est}} {{last_name_est}}': est_rat,
-               '{{first_name_rus}} {{last_name_rus}}': rus_rat}
+    formats = OrderedDict([
+        ('{{first_name_est}} {{last_name_est}}', est_rat),
+        ('{{first_name_rus}} {{last_name_rus}}', rus_rat),
+    ])
+
+    formats_male = OrderedDict([
+        ('{{first_name_male_est}} {{last_name_est}}', est_rat),
+        ('{{first_name_male_rus}} {{last_name_rus}}', rus_rat),
+    ])
 
-    formats_male = {'{{first_name_male_est}} {{last_name_est}}': est_rat,
-                    '{{first_name_male_rus}} {{last_name_rus}}': rus_rat}
-    formats_female = {'{{first_name_female_est}} {{last_name_est}}': est_rat,
-                      '{{first_name_female_rus}} {{last_name_rus}}': rus_rat}
+    formats_female = OrderedDict([
+        ('{{first_name_female_est}} {{last_name_est}}', est_rat),
+        ('{{first_name_female_rus}} {{last_name_rus}}', rus_rat),
+    ])
 
     prefixes_neutral = ('doktor', 'dr', 'prof')
     prefixes_male = ('härra', 'hr') + prefixes_neutral
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/person/pl_PL/__init__.py 
new/Faker-2.0.0/faker/providers/person/pl_PL/__init__.py
--- old/Faker-1.0.7/faker/providers/person/pl_PL/__init__.py    2019-05-14 
17:28:28.000000000 +0200
+++ new/Faker-2.0.0/faker/providers/person/pl_PL/__init__.py    2019-07-15 
16:35:50.000000000 +0200
@@ -21,28 +21,6 @@
     return check_digit
 
 
-def generate_pesel_checksum_value(pesel_digits):
-    """
-    Calculates and returns a control digit for given PESEL.
-    """
-    checksum_values = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7]
-
-    checksum = sum((int(a) * b for a, b in zip(list(pesel_digits), 
checksum_values)))
-
-    return checksum % 10
-
-
-def checksum_pesel_number(pesel_digits):
-    """
-    Calculates and returns True if PESEL is valid.
-    """
-    checksum_values = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1]
-
-    checksum = sum((int(a) * b for a, b in zip(list(pesel_digits), 
checksum_values)))
-
-    return checksum % 10 == 0
-
-
 class Provider(PersonProvider):
     formats = (
         '{{first_name}} {{last_name}}',
@@ -725,30 +703,74 @@
 
         return ''.join(str(character) for character in identity)
 
-    def pesel(self):
+    @staticmethod
+    def pesel_compute_check_digit(pesel):
+        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):
         """
         Returns 11 characters of Universal Electronic System for Registration 
of the Population.
         Polish: Powszechny Elektroniczny System Ewidencji Ludności.
 
         PESEL has 11 digits which identifies just one person.
-        Month: if person was born in 1900-2000, december is 12. If person was 
born > 2000, we have to add 20 to month,
-        so december is 32.
-        Person id: last digit identifies person's sex. Even for females, odd 
for males.
+        pesel_date: if person was born in 1900-2000, december is 12. If person 
was born > 2000, we have to add 20 to
+        month, so december is 32.
+        pesel_sex: last digit identifies person's sex. Even for females, odd 
for males.
 
         https://en.wikipedia.org/wiki/PESEL
         """
+        if date_of_birth is None:
+            date_of_birth = self.generator.date_of_birth()
+
+        pesel_date = '{year}{month:02d}{day:02d}'.format(
+            year=date_of_birth.year, day=date_of_birth.day,
+            month=date_of_birth.month if date_of_birth.year < 2000 else 
date_of_birth.month + 20)
+        pesel_date = pesel_date[2:]
+
+        pesel_core = ''.join(map(str, (self.random_digit() for _ in range(3))))
+        pesel_sex = self.random_digit()
+
+        if (sex == 'M' and pesel_sex % 2 == 0) or (sex == 'F' and pesel_sex % 
2 == 1):
+            pesel_sex = (pesel_sex + 1) % 10
+
+        pesel = '{date}{core}{sex}'.format(date=pesel_date, core=pesel_core, 
sex=pesel_sex)
+        pesel += str(self.pesel_compute_check_digit(pesel))
+
+        return pesel
+
+    @staticmethod
+    def pwz_doctor_compute_check_digit(x):
+        return sum((i+1)*d for i, d in enumerate(x)) % 11
+
+    def pwz_doctor(self):
+        """
+        Function generates an identification number for medical doctors
+        Polish: Prawo Wykonywania Zawodu (PWZ)
+
+        
https://www.nil.org.pl/rejestry/centralny-rejestr-lekarzy/zasady-weryfikowania-nr-prawa-wykonywania-zawodu
+        """
+        core = [self.random_digit() for _ in range(6)]
+        check_digit = self.pwz_doctor_compute_check_digit(core)
+
+        if check_digit == 0:
+            core[-1] = (core[-1] + 1) % 10
+            check_digit = self.pwz_doctor_compute_check_digit(core)
+
+        return '{}{}'.format(check_digit, ''.join(map(str, core)))
+
+    def pwz_nurse(self, kind='nurse'):
+        """
+        Function generates an identification number for nurses and midwives
+        Polish: Prawo Wykonywania Zawodu (PWZ)
 
-        birth = self.generator.date_of_birth()
+        
http://arch.nipip.pl/index.php/prawo/uchwaly/naczelnych-rad/w-roku-2015/posiedzenie-15-17-grudnia/3664-uchwala-
+        
nr-381-vi-2015-w-sprawie-trybu-postepowania-dotyczacego-stwierdzania-i-przyznawania-prawa-wykonywania-zawodu-pi
+        
elegniarki-i-zawodu-poloznej-oraz-sposobu-prowadzenia-rejestru-pielegniarek-i-rejestru-poloznych-przez-okregowe
+        -rady-pielegniarek-i-polo
+        """
+        region = self.random_int(1, 45)
+        core = [self.random_digit() for _ in range(5)]
+        kind_char = 'A' if kind == 'midwife' else 'P'
 
-        year_pesel = str(birth.year)[-2:]
-        month_pesel = birth.month if birth.year < 2000 else birth.month + 20
-        day_pesel = birth.day
-        person_id = self.random_int(1000, 9999)
-
-        current_pesel = 
'{year}{month:02d}{day:02d}{person_id:04d}'.format(year=year_pesel, 
month=month_pesel,
-                                                                           
day=day_pesel,
-                                                                           
person_id=person_id)
-
-        checksum_value = generate_pesel_checksum_value(current_pesel)
-        return 
'{pesel_without_checksum}{checksum_value}'.format(pesel_without_checksum=current_pesel,
-                                                                 
checksum_value=checksum_value)
+        return '{:02d}{}{}'.format(region, ''.join(map(str, core)), kind_char)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/python/__init__.py 
new/Faker-2.0.0/faker/providers/python/__init__.py
--- old/Faker-1.0.7/faker/providers/python/__init__.py  2019-05-14 
17:28:28.000000000 +0200
+++ new/Faker-2.0.0/faker/providers/python/__init__.py  2019-07-12 
17:17:07.000000000 +0200
@@ -71,8 +71,8 @@
             self.random_number(right_digits),
         ))
 
-    def pyint(self, min=0, max=9999, step=1):
-        return self.generator.random_int(min, max, step=step)
+    def pyint(self, min_value=0, max_value=9999, step=1):
+        return self.generator.random_int(min_value, max_value, step=step)
 
     def pydecimal(self, left_digits=None, right_digits=None, positive=False,
                   min_value=None, max_value=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/ssn/en_US/__init__.py 
new/Faker-2.0.0/faker/providers/ssn/en_US/__init__.py
--- old/Faker-1.0.7/faker/providers/ssn/en_US/__init__.py       2019-03-05 
18:07:52.000000000 +0100
+++ new/Faker-2.0.0/faker/providers/ssn/en_US/__init__.py       2019-07-12 
17:17:07.000000000 +0200
@@ -6,6 +6,7 @@
 
 
 class Provider(BaseProvider):
+    INVALID_SSN_TYPE = 'INVALID_SSN'
     SSN_TYPE = 'SSN'
     ITIN_TYPE = 'ITIN'
     EIN_TYPE = 'EIN'
@@ -139,6 +140,68 @@
         ein = "{0:s}-{1:07d}".format(ein_prefix, sequence)
         return ein
 
+    def invalid_ssn(self):
+        """ Generate a random invalid United States Social Security 
Identification Number (SSN).
+
+        Invalid SSNs have the following characteristics:
+        Cannot begin with the number 9
+        Cannot begin with 666 in positions 1 - 3
+        Cannot begin with 000 in positions 1 - 3
+        Cannot contain 00 in positions 4 - 5
+        Cannot contain 0000 in positions 6 - 9
+
+        https://www.ssa.gov/kc/SSAFactSheet--IssuingSSNs.pdf
+
+        Additionally, return an invalid SSN that is NOT a valid ITIN by 
excluding certain ITIN related "group" values
+        """
+        itin_group_numbers = [
+            70,
+            71,
+            72,
+            73,
+            74,
+            75,
+            76,
+            77,
+            78,
+            79,
+            80,
+            81,
+            82,
+            83,
+            84,
+            85,
+            86,
+            87,
+            88,
+            90,
+            91,
+            92,
+            94,
+            95,
+            96,
+            97,
+            98,
+            99]
+        area = self.random_int(min=0, max=999)
+        if area < 900 and area not in {666, 0}:
+            random_group_or_serial = self.random_int(min=1, max=1000)
+            if random_group_or_serial <= 500:
+                group = 0
+                serial = self.random_int(0, 9999)
+            else:
+                group = self.random_int(0, 99)
+                serial = 0
+        elif area in {666, 0}:
+            group = self.random_int(0, 99)
+            serial = self.random_int(0, 9999)
+        else:
+            group = random.choice([x for x in range(0, 100) if x not in 
itin_group_numbers])
+            serial = self.random_int(0, 9999)
+
+        invalid_ssn = "{0:03d}-{1:02d}-{2:04d}".format(area, group, serial)
+        return invalid_ssn
+
     def ssn(self, taxpayer_identification_number_type=SSN_TYPE):
         """ Generate a random United States Taxpayer Identification Number of 
the specified type.
 
@@ -149,6 +212,8 @@
             return self.itin()
         elif taxpayer_identification_number_type == self.EIN_TYPE:
             return self.ein()
+        elif taxpayer_identification_number_type == self.INVALID_SSN_TYPE:
+            return self.invalid_ssn()
         elif taxpayer_identification_number_type == self.SSN_TYPE:
 
             # Certain numbers are invalid for United States Social Security
@@ -166,4 +231,5 @@
             return ssn
 
         else:
-            raise ValueError("taxpayer_identification_number_type must be one 
of 'SSN', 'EIN', or 'ITIN'.")
+            raise ValueError("taxpayer_identification_number_type must be one 
of 'SSN', 'EIN', 'ITIN',"
+                             " or 'INVALID_SSN'.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/faker/providers/ssn/es_MX/__init__.py 
new/Faker-2.0.0/faker/providers/ssn/es_MX/__init__.py
--- old/Faker-1.0.7/faker/providers/ssn/es_MX/__init__.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/Faker-2.0.0/faker/providers/ssn/es_MX/__init__.py       2019-07-12 
17:17:07.000000000 +0200
@@ -0,0 +1,254 @@
+# coding=utf-8
+"""
+SSN provider for es_MX.
+
+This module adds a provider for mexican SSN, along with Unique Population
+Registry Code (CURP) and Federal Taxpayer Registry ID (RFC).
+"""
+
+
+from __future__ import unicode_literals
+
+import random
+import string
+
+from .. import Provider as BaseProvider
+
+
+ALPHABET = string.ascii_uppercase
+ALPHANUMERIC = string.digits + ALPHABET
+VOWELS = "AEIOU"
+CONSONANTS = [
+    letter
+    for letter in ALPHABET
+    if letter not in VOWELS
+]
+
+# 
https://es.wikipedia.org/wiki/Plantilla:Abreviaciones_de_los_estados_de_M%C3%A9xico
+STATES_RENAPO = [
+    "AS",
+    "BC",
+    "BS",
+    "CC",
+    "CS",
+    "CH",
+    "DF",
+    "CL",
+    "CM",
+    "DG",
+    "GT",
+    "GR",
+    "HG",
+    "JC",
+    "MC",
+    "MN",
+    "MS",
+    "NT",
+    "NL",
+    "OC",
+    "PL",
+    "QO",
+    "QR",
+    "SP",
+    "SL",
+    "SR",
+    "TC",
+    "TS",
+    "TL",
+    "VZ",
+    "YN",
+    "ZS",
+    "NE",  # Foreign Born
+]
+
+FORBIDDEN_WORDS = {
+    "BUEI": "BUEX",
+    "BUEY": "BUEX",
+    "CACA": "CACX",
+    "CACO": "CACX",
+    "CAGA": "CAGX",
+    "CAGO": "CAGX",
+    "CAKA": "CAKX",
+    "CAKO": "CAKX",
+    "COGE": "COGX",
+    "COJA": "COJX",
+    "COJE": "COJX",
+    "COJI": "COJX",
+    "COJO": "COJX",
+    "CULO": "CULX",
+    "FETO": "FETX",
+    "GUEY": "GUEX",
+    "JOTO": "JOTX",
+    "KACA": "KACX",
+    "KACO": "KACX",
+    "KAGA": "KAGX",
+    "KAGO": "KAGX",
+    "KOGE": "KOGX",
+    "KOJO": "KOJX",
+    "KAKA": "KAKX",
+    "KULO": "KULX",
+    "MAME": "MAMX",
+    "MAMO": "MAMX",
+    "MEAR": "MEAX",
+    "MEAS": "MEAX",
+    "MEON": "MEOX",
+    "MION": "MIOX",
+    "MOCO": "MOCX",
+    "MULA": "MULX",
+    "PEDA": "PEDX",
+    "PEDO": "PEDX",
+    "PENE": "PENX",
+    "PUTA": "PUTX",
+    "PUTO": "PUTX",
+    "QULO": "QULX",
+    "RATA": "RATX",
+    "RUIN": "RUIN",
+}
+
+CURP_CHARACTERS = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
+
+
+def _reduce_digits(number):
+    """
+    Sum of digits of a number until sum becomes single digit.
+
+    Example:
+        658 => 6 + 5 + 8 = 19 => 1 + 9 = 10 => 1
+    """
+    if number == 0:
+        return 0
+    if number % 9 == 0:
+        return 9
+
+    return number % 9
+
+
+def ssn_checksum(digits):
+    """
+    Calculate the checksum for the mexican SSN (IMSS).
+    """
+    return -sum(
+        _reduce_digits(n * (i % 2 + 1))
+        for i, n in enumerate(digits)
+    ) % 10
+
+
+def curp_checksum(characters):
+    """
+    Calculate the checksum for the mexican CURP.
+    """
+    start = 18
+    return -sum(
+        (start - i) * CURP_CHARACTERS.index(n)
+        for i, n in enumerate(characters)
+    ) % 10
+
+
+class Provider(BaseProvider):
+    """
+    A Faker provider for the Mexican SSN, RFC and CURP
+    """
+    ssn_formats = ("###########",)
+
+    def ssn(self):
+        """
+        Mexican Social Security Number, as given by IMSS.
+
+        :return: a random Mexican SSN
+        """
+        office = self.random_int(min=1, max=99)
+        birth_year = self.random_int(min=0, max=99)
+        start_year = self.random_int(min=0, max=99)
+        serial = self.random_int(min=1, max=9999)
+
+        num = "{0:02d}{1:02d}{2:02d}{3:04d}".format(
+            office,
+            start_year,
+            birth_year,
+            serial,
+        )
+
+        check = ssn_checksum(map(int, num))
+        num += str(check)
+
+        return num
+
+    def curp(self):
+        """
+        See 
https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Registro_de_Poblaci%C3%B3n.
+
+        :return: a random Mexican CURP (Unique Population Registry Code)
+        """
+        birthday = self.generator.date_of_birth()
+
+        first_surname = random.choice(ALPHABET) + random.choice(VOWELS)
+        second_surname = random.choice(ALPHABET)
+        given_name = random.choice(ALPHABET)
+        name_initials = first_surname + second_surname + given_name
+
+        birth_date = birthday.strftime("%y%m%d")
+        gender = random.choice("HM")
+        state = random.choice(STATES_RENAPO)
+        first_surname_inside = random.choice(CONSONANTS)
+        second_surname_inside = random.choice(CONSONANTS)
+        given_name_inside = random.choice(ALPHABET)
+
+        # This character is assigned to avoid duplicity
+        # It's normally '0' for those born < 2000
+        # and 'A' for those born >= 2000
+        assigned_character = "0" if birthday.year < 2000 else "A"
+
+        name_initials = FORBIDDEN_WORDS.get(name_initials, name_initials)
+
+        random_curp = (
+            name_initials +
+            birth_date +
+            gender +
+            state +
+            first_surname_inside +
+            second_surname_inside +
+            given_name_inside +
+            assigned_character
+        )
+
+        random_curp += str(curp_checksum(random_curp))
+
+        return random_curp
+
+    def rfc(self, natural=True):
+        """
+        See https://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes
+
+        :param natural: Whether to return the RFC of a natural person.
+            Otherwise return the RFC of a legal person.
+        :type natural: bool
+        :return: a random Mexican RFC
+        """
+        birthday = self.generator.date_of_birth()
+
+        if natural:
+            first_surname = random.choice(ALPHABET) + random.choice(VOWELS)
+            second_surname = random.choice(ALPHABET)
+            given_name = random.choice(ALPHABET)
+            name_initials = first_surname + second_surname + given_name
+        else:
+            name_initials = (
+                self.random_uppercase_letter() +
+                self.random_uppercase_letter() +
+                self.random_uppercase_letter()
+            )
+
+        birth_date = birthday.strftime("%y%m%d")
+        disambiguation_code = (
+            random.choice(ALPHANUMERIC) +
+            random.choice(ALPHANUMERIC) +
+            random.choice(ALPHANUMERIC)
+        )
+
+        random_rfc = (
+            name_initials +
+            birth_date +
+            disambiguation_code
+        )
+
+        return random_rfc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/setup.py new/Faker-2.0.0/setup.py
--- old/Faker-1.0.7/setup.py    2019-05-14 17:28:28.000000000 +0200
+++ new/Faker-2.0.0/setup.py    2019-07-12 18:06:49.000000000 +0200
@@ -69,13 +69,15 @@
         "text-unidecode==1.2",
     ],
     tests_require=[
-        "email_validator>=1.0.1,<1.1.0",
+        "validators>=0.13.0",
         "ukpostcodeparser>=1.1.1",
         "mock ; python_version < '3.3'",
         "pytest>=3.8.0,<3.9",
         "more-itertools<6.0.0 ; python_version < '3.0'",
-        "random2==1.0.1",
-        "freezegun==0.3.11",
+        # restricted because they may drop python2 support in future versions
+        # https://github.com/joke2k/faker/issues/970
+        "random2<1.1",
+        "freezegun<0.4",
     ],
     extras_require={
         ':python_version<"3.3"': [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/providers/test_date_time.py 
new/Faker-2.0.0/tests/providers/test_date_time.py
--- old/Faker-1.0.7/tests/providers/test_date_time.py   2019-04-12 
17:10:07.000000000 +0200
+++ new/Faker-2.0.0/tests/providers/test_date_time.py   2019-07-15 
16:35:50.000000000 +0200
@@ -3,10 +3,13 @@
 
 from datetime import date, datetime, timedelta, tzinfo
 from datetime import time as datetime_time
-import time
-import unittest
+import os
+import platform
+import pytest
 import random
 import sys
+import time
+import unittest
 
 import six
 
@@ -17,8 +20,6 @@
 from faker.providers.date_time.ar_EG import Provider as EgProvider
 from faker.providers.date_time.hy_AM import Provider as HyAmProvider
 
-import pytest
-
 
 def is64bit():
     return sys.maxsize > 2**32
@@ -448,7 +449,7 @@
         from faker.providers.date_time import datetime_to_timestamp
 
         for _ in range(100):
-            now = datetime.now(utc).replace(microsecond=0)
+            now = datetime.now().replace(microsecond=0)
             epoch_start = datetime(1970, 1, 1, tzinfo=utc)
 
             # Ensure doubly-constrained unix_times are generated correctly
@@ -490,6 +491,14 @@
             self.assertIsInstance(constrained_unix_time, int)
             self.assertBetween(constrained_unix_time, 0, 
datetime_to_timestamp(now))
 
+            # Ensure it does not throw error with startdate='now' for machines 
with negative offset
+            if platform.system() != 'Windows':
+                os.environ['TZ'] = 'Europe/Paris'
+                time.tzset()
+            self.factory.unix_time(start_datetime='now')
+            if platform.system() != 'Windows':
+                del os.environ['TZ']
+
 
 class TestPlPL(unittest.TestCase):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/providers/test_internet.py 
new/Faker-2.0.0/tests/providers/test_internet.py
--- old/Faker-1.0.7/tests/providers/test_internet.py    2019-05-14 
17:28:28.000000000 +0200
+++ new/Faker-2.0.0/tests/providers/test_internet.py    2019-07-12 
17:17:07.000000000 +0200
@@ -12,7 +12,7 @@
 import pytest
 import six
 
-from email_validator import validate_email
+from validators import email as validate_email
 
 from faker import Faker
 from faker.providers.person.ja_JP import Provider as JaProvider
@@ -120,7 +120,7 @@
 
     def test_email(self):
         email = self.factory.email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
 
     def test_domain_word(self):
         domain_word = self.factory.domain_word()
@@ -155,7 +155,7 @@
 
     def test_email(self):
         email = self.factory.email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
 
 
 class TestHuHU(unittest.TestCase):
@@ -200,7 +200,7 @@
     )
     def test_ascii_safe_email(self):
         email = self.factory.ascii_safe_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'fabienne'
 
     @mock.patch(
@@ -209,7 +209,7 @@
     )
     def test_ascii_free_email(self):
         email = self.factory.ascii_free_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'fabienne'
 
     @mock.patch(
@@ -218,7 +218,7 @@
     )
     def test_ascii_company_email(self):
         email = self.factory.ascii_company_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'fabienne'
 
 
@@ -234,7 +234,7 @@
     )
     def test_ascii_safe_email(self):
         email = self.factory.ascii_safe_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'asyl'
 
     @mock.patch(
@@ -243,7 +243,7 @@
     )
     def test_ascii_free_email(self):
         email = self.factory.ascii_free_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'asyl'
 
     @mock.patch(
@@ -252,7 +252,7 @@
     )
     def test_ascii_company_email(self):
         email = self.factory.ascii_company_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'asyl'
 
 
@@ -268,7 +268,7 @@
     )
     def test_ascii_safe_email(self):
         email = self.factory.ascii_safe_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'vitoriamagalhaes'
 
     @mock.patch(
@@ -277,7 +277,7 @@
     )
     def test_ascii_free_email(self):
         email = self.factory.ascii_free_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'joaosimoes'
 
     @mock.patch(
@@ -286,5 +286,5 @@
     )
     def test_ascii_company_email(self):
         email = self.factory.ascii_company_email()
-        validate_email(email, check_deliverability=False)
+        validate_email(email)
         assert email.split('@')[0] == 'andrecaua'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/providers/test_person.py 
new/Faker-2.0.0/tests/providers/test_person.py
--- old/Faker-1.0.7/tests/providers/test_person.py      2019-05-14 
17:28:28.000000000 +0200
+++ new/Faker-2.0.0/tests/providers/test_person.py      2019-07-15 
16:35:50.000000000 +0200
@@ -4,9 +4,14 @@
 
 import re
 import unittest
-
+import datetime
 import six
 
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+
 from faker import Faker
 from faker.providers.person.ar_AA import Provider as ArProvider
 from faker.providers.person.fi_FI import Provider as FiProvider
@@ -14,9 +19,9 @@
 from faker.providers.person.ne_NP import Provider as NeProvider
 from faker.providers.person.sv_SE import Provider as SvSEProvider
 from faker.providers.person.cs_CZ import Provider as CsCZProvider
+from faker.providers.person.pl_PL import Provider as PlPLProvider
 from faker.providers.person.pl_PL import (
     checksum_identity_card_number as pl_checksum_identity_card_number,
-    checksum_pesel_number as pl_checksum_pesel_number,
 )
 from faker.providers.person.zh_CN import Provider as ZhCNProvider
 from faker.providers.person.zh_TW import Provider as ZhTWProvider
@@ -207,13 +212,43 @@
         for _ in range(100):
             assert re.search(r'^[A-Z]{3}\d{6}$', 
self.factory.identity_card_number())
 
-    def test_pesel_number_checksum(self):
-        assert pl_checksum_pesel_number('31090655159') is True
-        assert pl_checksum_pesel_number('95030853577') is True
-        assert pl_checksum_pesel_number('05260953442') is True
-        assert pl_checksum_pesel_number('31090655158') is False
-        assert pl_checksum_pesel_number('95030853576') is False
-        assert pl_checksum_pesel_number('05260953441') is False
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pesel_birth_date(self, mock_random_digit):
+        mock_random_digit.side_effect = [3, 5, 8, 8, 7, 9, 9, 3]
+        assert self.factory.pesel(datetime.date(1999, 12, 31)) == '99123135885'
+        assert self.factory.pesel(datetime.date(2000,  1,  1)) == '00210179936'
+
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pesel_sex_male(self, mock_random_digit):
+        mock_random_digit.side_effect = [1, 3, 4, 5, 6, 1, 7, 0]
+        assert self.factory.pesel(datetime.date(1909, 3, 3), 'M') == 
'09030313454'
+        assert self.factory.pesel(datetime.date(1913, 8, 16), 'M') == 
'13081661718'
+
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pesel_sex_female(self, mock_random_digit):
+        mock_random_digit.side_effect = [4, 9, 1, 6, 6, 1, 7, 3]
+        assert self.factory.pesel(datetime.date(2007, 4, 13), 'F') == 
'07241349161'
+        assert self.factory.pesel(datetime.date(1933, 12, 16), 'F') == 
'33121661744'
+
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pwz_doctor(self, mock_random_digit):
+        mock_random_digit.side_effect = [6, 9, 1, 9, 6, 5, 2, 7, 9, 9, 1, 5]
+        assert self.factory.pwz_doctor() == '2691965'
+        assert self.factory.pwz_doctor() == '4279915'
+
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pwz_doctor_check_digit_zero(self, mock_random_digit):
+        mock_random_digit.side_effect = [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 9, 9]
+        assert self.factory.pwz_doctor() == '6000012'
+        assert self.factory.pwz_doctor() == '1000090'
+
+    @mock.patch.object(PlPLProvider, 'random_int')
+    @mock.patch.object(PlPLProvider, 'random_digit')
+    def test_pwz_nurse(self, mock_random_digit, mock_random_int):
+        mock_random_digit.side_effect = [3, 4, 5, 6, 7, 1, 7, 5, 1, 2]
+        mock_random_int.side_effect = [45, 3]
+        assert self.factory.pwz_nurse(kind='nurse') == '4534567P'
+        assert self.factory.pwz_nurse(kind='midwife') == '0317512A'
 
 
 class TestCsCZ(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/providers/test_python.py 
new/Faker-2.0.0/tests/providers/test_python.py
--- old/Faker-1.0.7/tests/providers/test_python.py      2019-04-15 
17:10:34.000000000 +0200
+++ new/Faker-2.0.0/tests/providers/test_python.py      2019-07-12 
17:17:07.000000000 +0200
@@ -20,16 +20,16 @@
         self.assertEqual(0, random_int % 2)
 
     def test_pyint_bound_0(self):
-        self.assertEqual(0, self.factory.pyint(min=0, max=0))
+        self.assertEqual(0, self.factory.pyint(min_value=0, max_value=0))
 
     def test_pyint_bound_positive(self):
-        self.assertEqual(5, self.factory.pyint(min=5, max=5))
+        self.assertEqual(5, self.factory.pyint(min_value=5, max_value=5))
 
     def test_pyint_bound_negative(self):
-        self.assertEqual(-5, self.factory.pyint(min=-5, max=-5))
+        self.assertEqual(-5, self.factory.pyint(min_value=-5, max_value=-5))
 
     def test_pyint_range(self):
-        self.assertTrue(0 <= self.factory.pyint(min=0, max=2) <= 2)
+        self.assertTrue(0 <= self.factory.pyint(min_value=0, max_value=2) <= 2)
 
 
 class TestPyfloat(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/providers/test_ssn.py 
new/Faker-2.0.0/tests/providers/test_ssn.py
--- old/Faker-1.0.7/tests/providers/test_ssn.py 2019-05-08 18:02:39.000000000 
+0200
+++ new/Faker-2.0.0/tests/providers/test_ssn.py 2019-07-12 17:17:07.000000000 
+0200
@@ -9,6 +9,7 @@
 import freezegun
 import pytest
 import random2
+from validators.i18n.es import es_cif as is_cif, es_nif as is_nif, es_nie as 
is_nie
 
 from faker import Faker
 from faker.providers.ssn.en_CA import checksum as ca_checksum
@@ -18,6 +19,8 @@
 from faker.providers.ssn.no_NO import checksum as no_checksum, Provider as 
no_Provider
 from faker.providers.ssn.pl_PL import checksum as pl_checksum, calculate_month 
as pl_calculate_mouth
 from faker.providers.ssn.pt_BR import checksum as pt_checksum
+from faker.providers.ssn.es_MX import (ssn_checksum as mx_ssn_checksum,
+                                       curp_checksum as mx_curp_checksum)
 
 
 class TestBgBG(unittest.TestCase):
@@ -113,6 +116,98 @@
             assert 1 <= int(serial) <= 9999
             assert area != '666'
 
+    def test_invalid_ssn(self):
+        self.factory.random = random2.Random()
+        # Magic Numbers below generate '666-92-7944', '000-54-2963', 
'956-GG-9478', '436-00-1386',
+        # and 134-76-0000 respectively. The "group" (GG) returned for 
'956-GG-9478 will be a random
+        # number, and that random number is not in the "itin_group_numbers" 
List. The random GG occurs
+        # even when using the same seed_instance() due to using 
random.choice() for GG to avoid valid
+        # ITINs being returned as an invalid SSN:
+        #
+        # Ensure that generated SSNs are 11 characters long
+        # including dashes, consist of dashes and digits only, and the tested 
number
+        # violates the requirements below, ensuring an INVALID SSN is returned:
+        #
+        # A United States Social Security Number
+        # (SSN) is a tax processing number issued by the Internal
+        # Revenue Service with the format "AAA-GG-SSSS".  The
+        # number is divided into three parts: the first three
+        # digits, known as the area number because they were
+        # formerly assigned by geographical region; the middle two
+        # digits, known as the group number; and the final four
+        # digits, known as the serial number. SSNs with the
+        # following characteristics are not allocated:
+        #
+        # 1) Numbers with all zeros in any digit group
+        # (000-##-####, ###-00-####, ###-##-0000).
+        #
+        # 2) Numbers with 666 or 900-999 in the first digit group.
+        #
+        # https://en.wikipedia.org/wiki/Social_Security_number
+        #
+        # ITIN explained:
+        # 
https://www.irs.gov/individuals/international-taxpayers/general-itin-information
+
+        itin_group_numbers = [
+            70,
+            71,
+            72,
+            73,
+            74,
+            75,
+            76,
+            77,
+            78,
+            79,
+            80,
+            81,
+            82,
+            83,
+            84,
+            85,
+            86,
+            87,
+            88,
+            90,
+            91,
+            92,
+            94,
+            95,
+            96,
+            97,
+            98,
+            99]
+
+        self.factory.seed_instance(1143)
+        ssn = 
self.factory.ssn(taxpayer_identification_number_type='INVALID_SSN')
+
+        assert len(ssn) == 11
+        assert ssn.replace('-', '').isdigit()
+        assert ssn.startswith('666')
+
+        self.factory.seed_instance(1514)
+        ssn = 
self.factory.ssn(taxpayer_identification_number_type='INVALID_SSN')
+
+        assert ssn.startswith('000')
+
+        self.factory.seed_instance(2)
+        ssn = 
self.factory.ssn(taxpayer_identification_number_type='INVALID_SSN')
+        [area, group, serial] = ssn.split('-')
+
+        assert 900 <= int(area) <= 999 and int(group) not in itin_group_numbers
+
+        self.factory.seed_instance(9)
+        ssn = 
self.factory.ssn(taxpayer_identification_number_type='INVALID_SSN')
+        [area, group, serial] = ssn.split('-')
+
+        assert int(area) < 900 and int(group) == 0
+
+        self.factory.seed_instance(1)
+        ssn = 
self.factory.ssn(taxpayer_identification_number_type='INVALID_SSN')
+        [area, group, serial] = ssn.split('-')
+
+        assert int(area) < 900 and int(serial) == 0
+
     def test_prohibited_ssn_value(self):
         # 666 is a prohibited value. The magic number selected as a seed
         # is one that would (if not specifically checked for) return an
@@ -268,92 +363,6 @@
             self.factory.ssn(taxpayer_identification_number_type='ssn')
 
 
-def nif_nie_validation(doi, number_by_letter, special_cases):
-    """
-    Validate if the doi is a NIF or a NIE.
-    :param doi: DOI to validate.
-    :return: boolean if it's valid.
-    """
-    doi = doi.upper()
-    if doi in special_cases:
-        return False
-
-    table = 'TRWAGMYFPDXBNJZSQVHLCKE'
-
-    if len(doi) == 9:
-        control = doi[8]
-
-        # If it is not a DNI, convert the first letter to the corresponding 
digit
-        numbers = number_by_letter.get(doi[0], doi[0]) + doi[1:8]
-
-        return numbers.isdigit() and control == table[int(numbers) % 23]
-
-    return False
-
-
-def is_cif(doi):
-    """
-    Validate if the doi is a CIF.
-    :param doi: DOI to validate.
-    :return: boolean if it's valid.
-    """
-    doi = doi.upper()
-
-    if len(doi) != 9:
-        return False
-
-    table = 'JABCDEFGHI'
-    first_chr = doi[0]
-    doi_body = doi[1:8]
-    control = doi[8]
-
-    if not doi_body.isdigit():
-        return False
-
-    # Multiply each each odd position doi digit by 2 and sum it all together
-    odd_result = sum(int(x) for x in ''.join(str(int(x) * 2) for x in 
doi_body[0::2]))
-    # Sum all even doi digits
-    even_result = sum(map(int, doi_body[1::2]))
-
-    res = (10 - (even_result + odd_result) % 10) % 10
-
-    if first_chr in 'ABEH':  # Number type
-        return str(res) == control
-    elif first_chr in 'PSQW':  # Letter type
-        return table[res] == control
-    elif first_chr not in 'CDFGJNRUV':
-        return False
-
-    return control == str(res) or control == table[res]
-
-
-def is_nif(doi):
-    """
-    Validate if the doi is a NIF.
-    :param doi: DOI to validate.
-    :return: boolean if it's valid.
-    """
-    number_by_letter = {'L': '0', 'M': '0', 'K': '0'}
-    special_cases = ['X0000000T', '00000000T', '00000001R', '00000001R']
-    return nif_nie_validation(doi, number_by_letter, special_cases)
-
-
-def is_nie(doi):
-    """
-    Validate if the doi is a NIE.
-    :param doi: DOI to validate.
-    :return: boolean if it's valid.
-    """
-    number_by_letter = {'X': '0', 'Y': '1', 'Z': '2'}
-    special_cases = ['X0000000T']
-
-    # NIE must must start with X Y or Z
-    if not doi or doi[0] not in number_by_letter.keys():
-        return False
-
-    return nif_nie_validation(doi, number_by_letter, special_cases)
-
-
 class TestEsES(unittest.TestCase):
     def setUp(self):
         self.factory = Faker('es_ES')
@@ -383,6 +392,41 @@
         self.factory = Faker('es_CA')
 
 
+class TestEsMX(unittest.TestCase):
+    def setUp(self):
+        self.factory = Faker('es_MX')
+
+    def test_ssn(self):
+        for _ in range(100):
+            ssn = self.factory.ssn()
+
+            assert len(ssn) == 11
+            assert ssn.isnumeric()
+            assert mx_ssn_checksum(map(int, ssn[:-1])) == int(ssn[-1])
+
+    def test_curp(self):
+        for _ in range(100):
+            curp = self.factory.curp()
+
+            assert len(curp) == 18
+            assert re.search(r'^[A-Z]{4}\d{6}[A-Z]{6}[0A]\d$', curp)
+            assert mx_curp_checksum(curp[:-1]) == int(curp[-1])
+
+    def test_rfc_natural(self):
+        for _ in range(100):
+            rfc = self.factory.rfc()
+
+            assert len(rfc) == 13
+            assert re.search(r'^[A-Z]{4}\d{6}[0-9A-Z]{3}$', rfc)
+
+    def test_rfc_legal(self):
+        for _ in range(100):
+            rfc = self.factory.rfc(natural=False)
+
+            assert len(rfc) == 12
+            assert re.search(r'^[A-Z]{3}\d{6}[0-9A-Z]{3}$', rfc)
+
+
 class TestEtEE(unittest.TestCase):
     """ Tests SSN in the et_EE locale """
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Faker-1.0.7/tests/test_factory.py 
new/Faker-2.0.0/tests/test_factory.py
--- old/Faker-1.0.7/tests/test_factory.py       2019-05-14 17:28:28.000000000 
+0200
+++ new/Faker-2.0.0/tests/test_factory.py       2019-07-15 16:39:47.000000000 
+0200
@@ -6,6 +6,8 @@
 import unittest
 import string
 import sys
+
+from collections import OrderedDict
 from ipaddress import ip_address, ip_network
 
 import six
@@ -218,13 +220,17 @@
         pick = provider.random_element(choices)
         assert pick in choices
 
-        choices = {'a': 5, 'b': 2, 'c': 2, 'd': 1}
+        # dicts not allowed because they introduce dependency on PYTHONHASHSEED
+        with self.assertRaises(ValueError):
+            provider.random_element({})
+
+        choices = OrderedDict([('a', 5), ('b', 2), ('c', 2), ('d', 1)])
         pick = provider.random_element(choices)
-        assert pick in choices
+        self.assertTrue(pick in choices)
 
-        choices = {'a': 0.5, 'b': 0.2, 'c': 0.2, 'd': 0.1}
+        choices = OrderedDict([('a', 0.5), ('b', 0.2), ('c', 0.2), ('d', 0.1)])
         pick = provider.random_element(choices)
-        assert pick in choices
+        self.assertTrue(pick in choices)
 
     def test_binary(self):
         from faker.providers.misc import Provider


Reply via email to