Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
sametmax opened this issue Oct 1, 2017 · 3 comments

Comments

@sametmax
Copy link

sametmax commented Oct 1, 2017

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.

@ilevkivskyi
Copy link
Member

But why you don't want using Enums? I know TypeScript has a similar feature so that string literals can act similar to enums, but mypy has reasonable support for Enum, so I don't think we should do this.

(If you are using an older Python version, so that you need to install the backported enums from PyPI, then we can consider a support for the bacported module in a separate issue.)

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 2, 2017

Legacy interfaces (including stdlib and 3rd party modules) feel like the most interesting potential use case for the proposed feature. For other code Enum should be fine? In order to support legacy interfaces, we'd need to use these types in typeshed. Typeshed is used by multiple tools, so we'd need standardization before the feature would be available. I don't think that a mypy-only feature would be very useful.

Creating an issue at https://github.com/python/typing would be a way to move this forward. Another useful thing would be finding real-world examples (in stdlib, for example) where this would be useful. Without further evidence this feels like a pretty marginal feature to me.

@sametmax
Copy link
Author

sametmax commented Oct 2, 2017

@ilevkivskyi, @JukkaL: a lot of people don't use enum. It's very overkill when you start a project, especially with Python and its simple syntax. But later down the road, one of your project may grow to the extend that some part its the API needs a more robust approach and start using type hints.

When I read you, I understand you see that from the dev point of view. But remember, a lot of Python users are geographers, data scientists, mathematicians, hobbyists and the like. They don't start with tooling. Or a a master plan in mind. However what they produce might become more popular, or they get more skilled, and decide to use Mypy.

Also, for many API, having to import an Enum and type it every time is very verbose. You don't use Python because you want verbose. The first example coming to mind is an abserver (e.g: your own version of django/QT signals). I really don't want to force the user to subscribe with an Enum value.

Besides, enum's won't help for int ranges. You don't want your "quality" parameters going from 0 to 100 to be a 100 attribute large enum.

Anyway, i'll open that in typing, let's carry on the discussion here.

@sametmax sametmax closed this as completed Oct 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants