Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Faker for openSUSE:Factory checked in at 2023-06-21 22:37:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Faker (Old) and /work/SRC/openSUSE:Factory/.python-Faker.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Faker" Wed Jun 21 22:37:21 2023 rev:44 rq:1094144 version:18.10.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Faker/python-Faker.changes 2023-05-29 22:47:36.562241805 +0200 +++ /work/SRC/openSUSE:Factory/.python-Faker.new.15902/python-Faker.changes 2023-06-21 22:37:36.045555680 +0200 @@ -1,0 +2,8 @@ +Tue Jun 20 17:41:01 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 18.10.1: + * Fix handling leap year in `en_US` Passport provider. + * Add `passport` Provider and `en_US` Implementation. + * Fix `fr_FR` `postcode` length. + +------------------------------------------------------------------- Old: ---- Faker-18.9.0.tar.gz New: ---- Faker-18.10.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Faker.spec ++++++ --- /var/tmp/diff_new_pack.3xmCBZ/_old 2023-06-21 22:37:36.737559845 +0200 +++ /var/tmp/diff_new_pack.3xmCBZ/_new 2023-06-21 22:37:36.741559869 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-Faker -Version: 18.9.0 +Version: 18.10.1 Release: 0 Summary: Python package that generates fake data License: MIT ++++++ Faker-18.9.0.tar.gz -> Faker-18.10.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/CHANGELOG.md new/Faker-18.10.1/CHANGELOG.md --- old/Faker-18.9.0/CHANGELOG.md 2023-05-16 18:38:09.000000000 +0200 +++ new/Faker-18.10.1/CHANGELOG.md 2023-06-02 21:06:49.000000000 +0200 @@ -1,5 +1,17 @@ ## Changelog +### [v18.10.1 - 2023-06-02](https://github.com/joke2k/faker/compare/v18.10.0...v18.10.1) + +* Fix handling leap year in `en_US` Passport provider. Thanks @mgorny. + +### [v18.10.0 - 2023-06-01](https://github.com/joke2k/faker/compare/v18.9.1...v18.10.0) + +* Add `passport` Provider and `en_US` Implementation. Thanks @llw2128. + +### [v18.9.1 - 2023-06-01](https://github.com/joke2k/faker/compare/v18.9.0...v18.9.1) + +* Fix `fr_FR` `postcode` length. Thanks @vmttn. + ### [v18.9.0 - 2023-05-16](https://github.com/joke2k/faker/compare/v18.8.0...v18.9.0) * Add `xml` provider. Thanks @Elihaybe. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/Faker.egg-info/PKG-INFO new/Faker-18.10.1/Faker.egg-info/PKG-INFO --- old/Faker-18.9.0/Faker.egg-info/PKG-INFO 2023-05-16 18:39:07.000000000 +0200 +++ new/Faker-18.10.1/Faker.egg-info/PKG-INFO 2023-06-02 21:07:23.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Faker -Version: 18.9.0 +Version: 18.10.1 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-18.9.0/Faker.egg-info/SOURCES.txt new/Faker-18.10.1/Faker.egg-info/SOURCES.txt --- old/Faker-18.9.0/Faker.egg-info/SOURCES.txt 2023-05-16 18:39:07.000000000 +0200 +++ new/Faker-18.10.1/Faker.egg-info/SOURCES.txt 2023-06-02 21:07:23.000000000 +0200 @@ -441,6 +441,8 @@ faker/providers/misc/en_US/__init__.py faker/providers/misc/fil_PH/__init__.py faker/providers/misc/tl_PH/__init__.py +faker/providers/passport/__init__.py +faker/providers/passport/en_US/__init__.py faker/providers/person/__init__.py faker/providers/person/ar_AA/__init__.py faker/providers/person/ar_PS/__init__.py @@ -643,6 +645,7 @@ tests/test_decode.py tests/test_factory.py tests/test_generator.py +tests/test_passport.py tests/test_providers_formats.py tests/test_proxy.py tests/test_unique.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/PKG-INFO new/Faker-18.10.1/PKG-INFO --- old/Faker-18.9.0/PKG-INFO 2023-05-16 18:39:09.469044700 +0200 +++ new/Faker-18.10.1/PKG-INFO 2023-06-02 21:07:24.435199000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Faker -Version: 18.9.0 +Version: 18.10.1 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-18.9.0/VERSION new/Faker-18.10.1/VERSION --- old/Faker-18.9.0/VERSION 2023-05-16 18:38:29.000000000 +0200 +++ new/Faker-18.10.1/VERSION 2023-06-02 21:07:06.000000000 +0200 @@ -1 +1 @@ -18.9.0 +18.10.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/faker/__init__.py new/Faker-18.10.1/faker/__init__.py --- old/Faker-18.9.0/faker/__init__.py 2023-05-16 18:38:29.000000000 +0200 +++ new/Faker-18.10.1/faker/__init__.py 2023-06-02 21:07:06.000000000 +0200 @@ -2,6 +2,6 @@ from faker.generator import Generator from faker.proxy import Faker -VERSION = "18.9.0" +VERSION = "18.10.1" __all__ = ("Factory", "Generator", "Faker") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/faker/providers/address/fr_FR/__init__.py new/Faker-18.10.1/faker/providers/address/fr_FR/__init__.py --- old/Faker-18.9.0/faker/providers/address/fr_FR/__init__.py 2023-05-04 00:26:30.000000000 +0200 +++ new/Faker-18.10.1/faker/providers/address/fr_FR/__init__.py 2023-06-01 18:15:54.000000000 +0200 @@ -469,10 +469,10 @@ def postcode(self) -> str: """ - Randomly returns a postcode generated from existing french depertment number. + Randomly returns a postcode generated from existing french department number. exemple: '33260' """ department = self.department_number() if department in ["2A", "2B"]: department = "20" - return f"{department}{self.random_number(digits=5 - len(department))}" + return f"{department}{self.random_number(digits=5 - len(department), fix_len=True)}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/faker/providers/passport/__init__.py new/Faker-18.10.1/faker/providers/passport/__init__.py --- old/Faker-18.9.0/faker/providers/passport/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Faker-18.10.1/faker/providers/passport/__init__.py 2023-06-01 18:21:14.000000000 +0200 @@ -0,0 +1,45 @@ +import datetime +import re + +from string import ascii_uppercase +from typing import Tuple + +from .. import BaseProvider, ElementsType + +localized = True + + +class Provider(BaseProvider): + """Implement default Passport provider for Faker.""" + + passport_number_formats: ElementsType = () + + def passport_dob(self) -> datetime.date: + """Generate a datetime date of bisrth.""" + birthday = self.generator.date_of_birth() + return birthday + + def passport_owner(self, gender: str = "X") -> Tuple[str, str]: + """Generate a given_name and surname for a passport owner + The ``gender`` argument is the gender marker of a passport owner, which is a one character string + that is either male, female, or non-binary. + """ + if gender == "M": + given_name = self.generator.parse("{{first_name_male}}") + elif gender == "F": + given_name = self.generator.parse("{{first_name_female}}") + else: + given_name = self.generator.parse("{{first_name_nonbinary}}") + + surname = self.generator.parse("{{last_name}}") + + return given_name, surname + + def passport_number(self) -> str: + """Generate a passport number by replacing tokens to be alphanumeric""" + temp = re.sub( + r"\?", + lambda x: self.random_element(ascii_uppercase), + self.random_element(self.passport_number_formats), + ) + return self.numerify(temp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/faker/providers/passport/en_US/__init__.py new/Faker-18.10.1/faker/providers/passport/en_US/__init__.py --- old/Faker-18.9.0/faker/providers/passport/en_US/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Faker-18.10.1/faker/providers/passport/en_US/__init__.py 2023-06-02 21:05:53.000000000 +0200 @@ -0,0 +1,99 @@ +import random + +from datetime import date, timedelta +from typing import Tuple + +from .. import Provider as PassportProvider + + +class Provider(PassportProvider): + """Implement passport provider for ``en_US`` locale. + + Sources: + + - https://travel.state.gov/content/travel/en/passports/passport-help/next-generation-passport.html + - https://www.vitalrecordsonline.com/glossary/passport-book-number + """ + + passport_number_formats = ( + # NGP + "?########", + # Pre-NGP + "#########", + ) + + def passport_dates(self, birthday: date = date.today()) -> Tuple[str, str, str]: + """Generates a formatted date of birth, issue, and expiration dates. + issue and expiration dates are conditioned to fall within U.S. standards of 5 and 10 year expirations + + + The ``birthday`` argument is a datetime.date object representing a date of birth. + + Sources: + + -https://travel.state.gov/content/travel/en/passports/passport-help/faqs.html + """ + birth_date = birthday.strftime("%d ") + birthday.strftime("%b ") + birthday.strftime("%Y") + today = date.today() + age = (today - birthday).days // 365 + if age < 16: + expiry_years = 5 + issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today) + # Checks if age is less than 5 so issue date is not before birthdate + if age < 5: + issue_date = self.generator.date_time_between(birthday, today) + elif age >= 26: + expiry_years = 10 + issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today) + else: + # In cases between age 16 and 26, the issue date is 5 years ago, but expiry may be in 10 or 5 years + expiry_years = 5 + issue_date = self.generator.date_time_between( + today - timedelta(days=expiry_years * 365 - 1), birthday + timedelta(days=16 * 365 - 1) + ) + # all people over 21 must have been over 16 when they recieved passport or it will be expired otherwise + if age >= 21: + issue_date = self.generator.date_time_between(today - timedelta(days=expiry_years * 365 - 1), today) + expiry_years = 10 + + if issue_date.day == 29 and issue_date.month == 2: + issue_date -= timedelta(days=1) + expiry_date = issue_date.replace(year=issue_date.year + expiry_years) + + issue_date_format = issue_date.strftime("%d ") + issue_date.strftime("%b ") + issue_date.strftime("%Y") + expiry_date_format = expiry_date.strftime("%d ") + expiry_date.strftime("%b ") + expiry_date.strftime("%Y") + return birth_date, issue_date_format, expiry_date_format + + def passport_gender(self, seed: int = 0) -> str: + """Generates a string representing the gender displayed on a passport + + Sources: + + - https://williamsinstitute.law.ucla.edu/publications/x-gender-markers-passports/ + """ + if seed != 0: + random.seed(seed) + + genders = ["M", "F", "X"] + gender = random.choices(genders, weights=[0.493, 0.493, 0.014], k=1)[0] + return gender + + def passport_full(self) -> str: + """Generates a formatted sting with US Passport information""" + dob = self.passport_dob() + birth_date, issue_date, expiry_date = self.passport_dates(dob) + gender_g = self.passport_gender() + given_name, surname = self.passport_owner(gender=gender_g) + number = self.passport_number() + + full_rep = """{first_name}\n{second_name}\n{gender}\n{dob}\n{issue}\n{expire}\n{num}\n""" + full_rep = full_rep.format( + first_name=given_name, + second_name=surname, + gender=gender_g, + dob=birth_date, + issue=issue_date, + expire=expiry_date, + num=number, + ) + return full_rep diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/tests/providers/test_address.py new/Faker-18.10.1/tests/providers/test_address.py --- old/Faker-18.9.0/tests/providers/test_address.py 2023-05-04 00:26:30.000000000 +0200 +++ new/Faker-18.10.1/tests/providers/test_address.py 2023-06-01 18:15:54.000000000 +0200 @@ -870,6 +870,7 @@ for _ in range(num_samples): postcode = faker.postcode() assert isinstance(postcode, str) + assert len(postcode) == 5 assert ( postcode[:3] in department_numbers # for 3 digits deparments number or postcode[:2] == "20" # for Corsica : "2A" or "2B" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/tests/test_passport.py new/Faker-18.10.1/tests/test_passport.py --- old/Faker-18.9.0/tests/test_passport.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Faker-18.10.1/tests/test_passport.py 2023-06-01 18:21:14.000000000 +0200 @@ -0,0 +1,82 @@ +from datetime import date, datetime, timedelta + +from faker.providers.person.en_US import Provider as EnUSPersonProvider + +female_first_name = list(EnUSPersonProvider.first_names_female.keys()) +male_first_name = list(EnUSPersonProvider.first_names_male.keys()) +nb_first_name = list(EnUSPersonProvider.first_names_nonbinary.keys()) +last_name = list(EnUSPersonProvider.last_names.keys()) + + +class TestPassportProvider: + def testDOB(self, faker, num_samples=100): + for _ in range(num_samples): + dob = faker.passport_dob() + age = (date.today() - dob).days // 365 + assert isinstance(dob, date) + assert age <= 115 + assert age >= 0 + + def testOwnerNames(self, faker, num_samples=100): + for _ in range(num_samples): + given_name, surname = faker.passport_owner("F") + assert given_name in female_first_name + assert surname in last_name + + given_name, surname = faker.passport_owner("M") + assert given_name in male_first_name + assert surname in last_name + + given_name, surname = faker.passport_owner("X") + assert given_name in nb_first_name + assert surname in last_name + + def testNumFormat(self, faker, num_samples=100): + for _ in range(num_samples): + pass_number = faker.passport_number() + if pass_number[0].isalpha(): + assert pass_number[1:].isdigit() + else: + assert pass_number.isdigit() + assert len(pass_number) == 9 + + +class TestEnUS: + def testDates(self, faker, num_samples=20): + age4 = date.today() - timedelta(days=4 * 365) + age12 = date.today() - timedelta(days=12 * 365) + age17 = date.today() - timedelta(days=17 * 365) + age23 = date.today() - timedelta(days=23 * 365) + age30 = date.today() - timedelta(days=30 * 365) + + birthdays = [(age4, 4), (age12, 12), (age17, 17), (age23, 23), (age30, 30)] + for _ in range(num_samples): + for birthday in birthdays: + birth_date_f, issue_date_f, expiry_date_f = faker.passport_dates(birthday[0]) + birth_date = datetime.strptime(birth_date_f, "%d %b %Y").date() + issue_date = datetime.strptime(issue_date_f, "%d %b %Y").date() + expiry_date = datetime.strptime(expiry_date_f, "%d %b %Y").date() + + if birthday[1] < 21: + assert (expiry_date - issue_date).days // 365 == 5 + else: + assert (expiry_date - issue_date).days // 365 == 10 + + assert expiry_date > issue_date + assert birth_date < issue_date + + def testGender(self, faker, num_samples=100): + for _ in range(num_samples): + assert faker.passport_gender(7899) in ["M", "F", "X"] + + def testfull(self, faker, num_samples=100): + for _ in range(num_samples): + pass_data = faker.passport_full().split("\n") + assert pass_data[1] in last_name + assert pass_data[2] in ["M", "F", "X"] + if pass_data[2] == "M": + assert pass_data[0] in male_first_name + elif pass_data[2] == "F": + assert pass_data[0] in female_first_name + elif pass_data[2] == "X": + assert pass_data[0] in nb_first_name diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Faker-18.9.0/tests/utils/test_utils.py new/Faker-18.10.1/tests/utils/test_utils.py --- old/Faker-18.9.0/tests/utils/test_utils.py 2023-03-01 21:05:50.000000000 +0100 +++ new/Faker-18.10.1/tests/utils/test_utils.py 2023-06-01 18:21:14.000000000 +0200 @@ -87,6 +87,7 @@ "faker.providers.job", "faker.providers.lorem", "faker.providers.misc", + "faker.providers.passport", "faker.providers.person", "faker.providers.phone_number", "faker.providers.profile",