Skip to content

optype.string

The string standard library contains practical constants, but it has two issues:

  • The constants contain a collection of characters, but are represented as a single string. This makes it practically impossible to type-hint the individual characters, so typeshed currently types these constants as a LiteralString.
  • The names of the constants are inconsistent, and doesn't follow PEP 8.

So instead, optype.string provides an alternative interface, that is compatible with string, but with slight differences:

  • For each constant, there is a corresponding Literal type alias for the individual characters. Its name matches the name of the constant, but is singular instead of plural.
  • Instead of a single string, optype.string uses a tuple of characters, so that each character has its own typing.Literal annotation. Note that this is only tested with (based)pyright / pylance, so it might not work with mypy (it has more bugs than it has lines of codes).
  • The names of the constant are consistent with PEP 8, and use a postfix notation for variants, e.g. DIGITS_HEX instead of hexdigits.
  • Unlike string, optype.string has a constant (and type alias) for binary digits '0' and '1'; DIGITS_BIN (and DigitBin). Because besides oct and hex functions in builtins, there's also the builtins.bin function.
string._ optype.string._
constant char type constant char type
missing DIGITS_BIN DigitBin
octdigits LiteralString DIGITS_OCT DigitOct
digits DIGITS Digit
hexdigits DIGITS_HEX DigitHex
ascii_letters LETTERS Letter
ascii_lowercase LETTERS_LOWER LetterLower
ascii_uppercase LETTERS_UPPER LetterUpper
punctuation PUNCTUATION Punctuation
whitespace WHITESPACE Whitespace
printable PRINTABLE Printable

Each of the optype.string constants is exactly the same as the corresponding string constant (after concatenation / splitting), e.g.

>>> import string
>>> import optype as opt
>>> "".join(opt.string.PRINTABLE) == string.printable
True
>>> tuple(string.printable) == opt.string.PRINTABLE
True

Similarly, the values within a constant's Literal type exactly match the values of its constant:

>>> import optype as opt
>>> from optype.inspect import get_args
>>> get_args(opt.string.Printable) == opt.string.PRINTABLE
True

The optype.inspect.get_args is a non-broken variant of typing.get_args that correctly flattens nested literals, type-unions, and PEP 695 type aliases, so that it matches the official typing specs. In other words; typing.get_args is yet another fundamentally broken python-typing feature that's useless in the situations where you need it most.