Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions faker/providers/passport/it_IT/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from .. import ElementsType
from .. import Provider as PassportProvider


class Provider(PassportProvider):
"""Implement passport provider for ``it_IT``.

Sources:

- https://www.poliziadistato.it/articolo/10301
- https://www.poliziadistato.it/statics/32/note_tecniche.pdf
"""

electronic_passport_number_formats: ElementsType[str] = (
# standard passaporto elettronico (elettronic passport)
# Format: 2 letters, 7 digits (e.g., YA1234567), used from 2010 on
"??#######",
)

def passport_number(self) -> str:
"""
Generate a valid Italian passport number

The format consist in 2 uppercase letters followed by 7 digits.
"""

# select the passport number format
format = self.random_element(self.electronic_passport_number_formats)

return self.bothify(format).upper()
19 changes: 19 additions & 0 deletions faker/providers/ssn/it_IT/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from string import ascii_uppercase, digits

from .. import Provider as SsnProvider
from .. import ElementsType

ALPHABET = ascii_uppercase
ALPHANUMERICS = sorted(digits + ascii_uppercase)
Expand Down Expand Up @@ -8026,6 +8027,24 @@ def ssn(self) -> str:
code: str = f"{surname}{name}{year}{month}{day}{municipality}"
return code + checksum(code)

cie_format: ElementsType[str] = (
# standard carta identitá elettronica (elettronic identity card )
# Format: 2 letters, 5 digits, 2 letters
"??#####??",
)

def cie(self) -> str:
"""
Generate a valid Italian Electronic Identity Card (CIE) number.
Format: 2 uppercase letters, 5 numbers, 2 uppercase letters

sources:
- https://www.cartaidentita.interno.gov.it/cose-la-carta/caratteristiche-del-documento/
"""

format = self.random_element(self.cie_format)
return self.bothify(format).upper()

vat_id_formats = ("IT###########",)

def vat_id(self) -> str:
Expand Down
16 changes: 16 additions & 0 deletions tests/providers/test_passport.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import re
import pytest
from faker.providers.passport.it_IT import Provider as ItPassportProvider

from typing import Pattern

Expand All @@ -21,3 +23,17 @@ def test_passport_number(self, faker, num_samples):
pattern: Pattern = re.compile(r"[A-Z]{1,2}\d{7}")
passport_number = faker.passport_number()
assert pattern.fullmatch(passport_number)


@pytest.mark.parametrize("faker", ["it_IT"], indirect=True)
class TestItIT:
"""Test it_IT passport provider methods"""

def test_passport_number(self, faker, num_samples):
faker.add_provider(ItPassportProvider)

pattern = re.compile(r"^[A-Z]{2}\d{7}$")

for _ in range(num_samples):
passport_number = faker.passport_number()
assert pattern.fullmatch(passport_number)
7 changes: 7 additions & 0 deletions tests/providers/test_ssn.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,13 @@ def setUp(self):
self.fake = Faker("it_IT")
Faker.seed(0)

def test_cie(self):
pattern = re.compile(r"^[A-Z]{2}\d{5}[A-Z]{2}$")

for _ in range(100):
cie_code = self.fake.cie()
assert pattern.fullmatch(cie_code)

def test_vat_id(self):
for _ in range(100):
assert re.search(r"^IT\d{11}$", self.fake.vat_id())
Expand Down