How to type annotate length of string?

Viewed 1079

I want to type annotate a function that only accepts a single character in python, take this example: (s: str) -> int

As Python doesn't have a type for a single char, you can't just do something like (s: char) -> int.

Is there any way to type that the s: str should only be one character?

I could see this being useful in hinting when writing code.

Here's my full example:

import unicodedata

roman_numeral_lookup = {"I": 1, "V": 5, "X": 10, ...}

def exact_roman_numeral(s: str) -> int:
    """Return the value of a single Roman numeral. Dosen't support multicharacter roman numerals such as 'XII' or Apostrophus."""

    # Convert Unicode Roman numerals into to their normalised text version. e.g. Ⅹ -> X, ⅰ -> I
    s = unicodedata.normalize("NFKC", s).upper()

    if s in roman_numeral_lookup:
        return roman_numeral_lookup[s]

    else:  # Some form of invalid value.
        if not isinstance(s, str):
            raise TypeError("Argument must be of type str.")
        elif len(s) != 1:
            raise ValueError("Must be a single Roman numeral.")
        else:
            raise ValueError("Not a valid/supported Roman numeral.")

(I know the errors aren't the best)

1 Answers

Well, in theory type-annotations shouldn't be used like you want them to - meaning, not every constraint in your code should be expressed by a type-annotation.

Now, to answer your question, you can, of course, build your own type-annotation but that would be, IMO, too much work for too less outcome.

There are other answers on SO which describe how a custom annotation can be defined

You can, at any point:

  • describe in your docstring that your variable is supposed to be 1-char long
  • do a sanity/validation check and raise a proper exception.
  • use something like Marshmallow to sanitize/serialize your data
Related