Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/faker/providers/isbn/__init__.py: 35%
31 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from typing import List, Tuple
3from faker.providers.isbn.rules import RegistrantRule
5from .. import BaseProvider
6from .isbn import ISBN, ISBN10, ISBN13
7from .rules import RULES
10class Provider(BaseProvider):
11 """Generates fake ISBNs. ISBN rules vary across languages/regions
12 so this class makes no attempt at replicating all of the rules. It
13 only replicates the 978 EAN prefix for the English registration
14 groups, meaning the first 4 digits of the ISBN-13 will either be
15 978-0 or 978-1. Since we are only replicating 978 prefixes, every
16 ISBN-13 will have a direct mapping to an ISBN-10.
18 See https://www.isbn-international.org/content/what-isbn for the
19 format of ISBNs.
20 See https://www.isbn-international.org/range_file_generation for the
21 list of rules pertaining to each prefix/registration group.
22 """
24 def _body(self) -> List[str]:
25 """Generate the information required to create an ISBN-10 or
26 ISBN-13.
27 """
28 ean: str = self.random_element(RULES.keys())
29 reg_group: str = self.random_element(RULES[ean].keys())
31 # Given the chosen ean/group, decide how long the
32 # registrant/publication string may be.
33 # We must allocate for the calculated check digit, so
34 # subtract 1
35 reg_pub_len: int = ISBN.MAX_LENGTH - len(ean) - len(reg_group) - 1
37 # Generate a registrant/publication combination
38 reg_pub: str = self.numerify("#" * reg_pub_len)
40 # Use rules to separate the registrant from the publication
41 rules: List[RegistrantRule] = RULES[ean][reg_group]
42 registrant, publication = self._registrant_publication(reg_pub, rules)
43 return [ean, reg_group, registrant, publication]
45 @staticmethod
46 def _registrant_publication(reg_pub: str, rules: List[RegistrantRule]) -> Tuple[str, str]:
47 """Separate the registration from the publication in a given
48 string.
49 :param reg_pub: A string of digits representing a registration
50 and publication.
51 :param rules: A list of RegistrantRules which designate where
52 to separate the values in the string.
53 :returns: A (registrant, publication) tuple of strings.
54 """
55 for rule in rules:
56 if rule.min <= reg_pub[:-1] <= rule.max:
57 reg_len = rule.registrant_length
58 break
59 else:
60 raise Exception("Registrant/Publication not found in registrant " "rule list.")
61 registrant, publication = reg_pub[:reg_len], reg_pub[reg_len:]
62 return registrant, publication
64 def isbn13(self, separator: str = "-") -> str:
65 ean, group, registrant, publication = self._body()
66 isbn = ISBN13(ean, group, registrant, publication)
67 return isbn.format(separator)
69 def isbn10(self, separator: str = "-") -> str:
70 ean, group, registrant, publication = self._body()
71 isbn = ISBN10(ean, group, registrant, publication)
72 return isbn.format(separator)