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
Literaltype 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.stringuses atupleof characters, so that each character has its owntyping.Literalannotation. 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_HEXinstead ofhexdigits. - Unlike
string,optype.stringhas a constant (and type alias) for binary digits'0'and'1';DIGITS_BIN(andDigitBin). Because besidesoctandhexfunctions inbuiltins, there's also thebuiltins.binfunction.
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.