def test_parse_with_invalid_check_digit() -> None: with pytest.raises(ParseError) as exc_info: Sscc.parse("376130321109103421") assert ( str(exc_info.value) == "Invalid SSCC check digit for '376130321109103421': Expected 0, got 1." )
def test_parse_value_with_invalid_length() -> None: with pytest.raises(ParseError) as exc_info: Sscc.parse("123") assert ( str(exc_info.value) == "Failed to parse '123' as SSCC: Expected 18 digits, got 3." )
def test_parse_nonnumeric_value(value: str) -> None: with pytest.raises(ParseError) as exc_info: Sscc.parse(value) assert ( str(exc_info.value) == f"Failed to parse {value!r} as SSCC: Expected a numerical value." )
def test_parse_nonnumeric_value() -> None: with pytest.raises(ParseError) as exc_info: Sscc.parse("012345678901234abc") assert ( str(exc_info.value) == "Failed to parse '012345678901234abc' as SSCC: Expected a numerical value." )
def test_as_hri_with_too_high_company_prefix_length() -> None: sscc = Sscc.parse("376130321109103420") with pytest.raises(ValueError) as exc_info: sscc.as_hri(company_prefix_length=11) assert (str(exc_info.value) == "Expected company prefix length between 7 and 10, got 11.")
def test_parse() -> None: sscc = Sscc.parse("376130321109103420") assert sscc == Sscc( value="376130321109103420", prefix=GS1Prefix(value="761", usage="GS1 Schweiz, Suisse, Svizzera"), extension_digit=3, payload="37613032110910342", check_digit=0, )
def _parse_sscc( value: str, *, config: ParseConfig, queue: ParseQueue, result: ParseResult, ) -> None: if result.sscc is not None: return # pragma: no cover try: result.sscc = Sscc.parse(value) result.sscc_error = None except ParseError as exc: result.sscc = None result.sscc_error = str(exc)
def test_as_hri_with_unknown_gs1_prefix() -> None: # GS1 prefix 671 is currently unassigned. sscc = Sscc.parse("367130321109103428") assert sscc.as_hri() == "3 6713032110910342 8"
def test_as_hri(prefix_length: Optional[int], expected: str) -> None: sscc = Sscc.parse("376130321109103420") assert sscc.as_hri(company_prefix_length=prefix_length) == expected
def test_parse_strips_surrounding_whitespace() -> None: sscc = Sscc.parse(" \t 376130321109103420 \n ") assert sscc.value == "376130321109103420"
def parse( value: str, *, rcn_region: Optional[RcnRegion] = None, separator_chars: Iterable[str] = DEFAULT_SEPARATOR_CHARS, ) -> ParseResult: """Identify data format and parse data. The current strategy is: 1. If Symbology Identifier prefix indicates a GTIN or GS1 Message, attempt to parse and validate as that. 2. Else, if not Symbology Identifier, attempt to parse with all parsers. Args: value: The data to classify and parse. rcn_region: The geographical region whose rules should be used to interpret Restricted Circulation Numbers (RCN). Needed to extract e.g. variable weight/price from GTIN. separator_chars: Characters used in place of the FNC1 symbol. Defaults to `<GS>` (ASCII value 29). If variable-length fields in the middle of the message are not terminated with a separator character, the parser might greedily consume the rest of the message. Returns: A data class depending upon what type of data is parsed. Raises: ParseError: If parsing of the data fails. """ value = value.strip() result = ParseResult(value=value) # Extract Symbology Identifier if value.startswith("]"): result.symbology_identifier = SymbologyIdentifier.extract(value) value = value[len(result.symbology_identifier):] # Select parsers parsers: List[ParserType] = [] if result.symbology_identifier is not None: if (result.symbology_identifier.gs1_symbology in GS1Symbology.with_gtin()): parsers.append(Gtin) if (result.symbology_identifier.gs1_symbology in GS1Symbology.with_ai_element_strings()): parsers.append(GS1Message) if not parsers: # If we're not able to select a subset based on Symbology Identifiers, # run all parsers in the default order. parsers = [Gtin, Sscc, GS1Message] # Run all parsers in order for parser in parsers: if parser == Gtin: try: result.gtin = Gtin.parse(value, rcn_region=rcn_region) except ParseError as exc: result.gtin_error = str(exc) if parser == Sscc: try: result.sscc = Sscc.parse(value) except ParseError as exc: result.sscc_error = str(exc) if parser == GS1Message: try: result.gs1_message = GS1Message.parse( value, rcn_region=rcn_region, separator_chars=separator_chars, ) except ParseError as exc: result.gs1_message_error = str(exc) else: ai_00 = result.gs1_message.get(ai="00") if ai_00 is not None: # GS1 Message contains an SSCC result.sscc = ai_00.sscc # Clear error from parsing full value a SSCC. result.sscc_error = None ai_01 = result.gs1_message.get(ai="01") if ai_01 is not None: # GS1 Message contains a GTIN. result.gtin = ai_01.gtin # Clear error from parsing full value as GTIN. result.gtin_error = None if result._has_result(): return result else: raise ParseError( f"Failed to parse {value!r}:\n{result._get_errors_list()}")
def _set_sscc(self: GS1ElementString) -> None: if self.ai.ai != "00": return self.sscc = Sscc.parse(self.value)
def _set_sscc(self) -> None: if self.ai.ai != "00": return self.sscc = Sscc.parse(self.value)