1,447 bytes · the Python implementation · view raw
from typing import Sequence
def _clean(part: str) -> str:
# Keep ASCII letters and digits only, then uppercase. Filtering first# matters: "ß".upper() is "SS", which would make the SKU depend on how each# language's Unicode tables treat one letter.return"".join(c for c in part if ("A" <= c <= "Z") or ("a" <= c <= "z") or ("0" <= c <= "9")).upper()
def generate_sku(prefix: str, attributes: Sequence[str], segment_length: int) -> str:
"""A deterministic SKU: the cleaned prefix and attributes, joined by hyphens. Each attribute is cut to ``segment_length`` characters (0 keeps it whole). """if isinstance(segment_length, bool) ornot isinstance(segment_length, int) or segment_length < 0:
raise ValueError("segmentLength must be 0 or more, received %r" % (segment_length,))
if len(attributes) == 0:
raise ValueError("a SKU needs at least one attribute")
parts = []
if prefix != "":
cleaned = _clean(prefix)
if cleaned == "":
raise ValueError('prefix ("%s") has no letters or digits' % prefix)
parts.append(cleaned)
for index, attribute in enumerate(attributes):
cleaned = _clean(attribute)
if cleaned == "":
raise ValueError('attribute %d ("%s") has no letters or digits' % (index + 1, attribute))
parts.append(cleaned if segment_length == 0else cleaned[:segment_length])
return"-".join(parts)