Skip to content

Check that literal strings/int/float belong to /is excluded from a set/range of values #478

Closed
@sametmax

Description

@sametmax

Opened in python/mypy#4040, but moved here after @JukkaL 's advice.

Some debate took place in there, but I'll copy the original post here for context:


It's a common practice to pass literal strings as arguments. In Python, it's even more important, as strings are often used instead of byte flags, constants or enums.

You often end up checking if those literals are passed correctly so you can give some debug information:

  • sorry, the parameter mode except a string among "started, paused, cancelled";

  • you can only used an integer between 0 and 16.

etc.

The problem with that is it's done at runtime despite the fact those argument are completely static ones. So the IDE can't use this information to help you write code. Typically, I would have code completion and linting helping me with "started/pause/cancelled" if it was an enum, but not if it's a string.

With this concept I could do:

MODES = ('started', 'paused', 'cancelled')
LEVELS = (
    range(0, 5),
    range(40, float('+inf')), 
)

def foo(mode: typing.Among(MODES), levels: typing.Among(LEVELS)):
    pass

So that mypy could alert my users if they do:

def foo("Start", 6):

Of course, it's only for strings/ints/floats literals, maybe bytes and tuple, as we need the information to be immutable and simple to be usable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions