-
Notifications
You must be signed in to change notification settings - Fork 234
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
@overload outside stubs #72
Comments
I don't understand your claim. Can you show me exactly what the implementation of plus1() should look like? Where do I put the |
So the problem with (I've fixed the markup ... github's markdown docs don't tell the truth) |
Yes, the problem is exactly to stay within the current Python3 syntax. (You can preview the markup easily by clicking on the Preview tab.) |
How about this?
This allows as many This technique can also be applied to any stub annotation, so for example (if we want to support exceptions):
To avoid mistakes, we might want to have a |
Well, if we allow
But making this work with the given syntax ( Is there any particular reason you want |
You seem to be describing My only point is that it's trivial to define an It's a matter of taste: do we want a separate "header" file (like C++ .h and .cc); or do we want everything together (like Java)? It seems that the "modern" tendency is to minimize the number of files and to not use separate header files, relying on other tools (like I'm not proposing that we get rid of stub files (they have legitimate reasons for existing); just pointing out that there's no reason to require |
I think you hit the nail on the head. For inline use I would like to have a single multiple-dispatch mechanism that also acts as an overloaded type. But coming up with a good design and implementation for that is out of scope (Łukasz wants to work on it for a separate PEP). In the meantime having |
SGTM I hope to have some answers in the next few months about what kinds of signatures we see in ordinary production code (outside the core libraries). |
I've considered the approach proposed by @pludemann (using I don't have enough data to estimate how often this would be useful in production code. All the instances of overloading in mypy codebase (from the time when overloading implied multiple dispatch) were easy to refactor to use union types or multiple functions (with different names) instead. We can always fall back to |
I'm currently working around it by using a I'm perfectly happy writing the dispatcher function myself. A rule of "a series of I do think that, in the long run (Python 4?), generics and overloaded functions are important enough language features that they should have their own syntax. But we're not there yet. |
The rule "a series of
|
I don't think that it would be difficult to implement in mypy -- maybe at most a day's work. |
I've thought this over and I don't think it's worth it. We need to wait for a working proposal for multi-dispatch first. Otherwise we'll just end up having to support this interim syntax and whatever the new multi-dispatch is. Keeping |
This came up again in the context of Tornado. Reopening. |
So I am now thinking that we should implement this proposal. The Tornado utf8() function could look like this: @overload
def utf8(value: None) -> None: ...
@overload
def utf8(value: bytes) -> bytes: ...
@overload
def utf8(value: str) -> bytes: ... # or (unicode)->bytes, in PY2
def utf8(value):
# Real implementation goes here. At runtime the def overload(func):
def overload_dummy(*args, **kwds):
raise NotImplemented("You should not call an overloaded function. "
"A series of @overload-decorated functions "
"outside a stub module should always be followed "
"by an implementation that is not @overloaded.") UPDATE: That should be |
BTW that proposal would require a change to PEP 484 (that's possible, it's provisional) and a change to typing.py in Python 3.5.2 (that's also possible, but we may need to act somewhat quickly). |
I've posted a link to this issue to python-ideas, so hopefully we can move quickly if it's uncontroversial, or we'll get a better proposal soon. |
Just +1, (and nitpicking but I think you ment |
Given the prior discussion regarding function annotations in Python 2/3 compatible code, my proposed near term workaround for this problem was to allow multiple comments in that style in order to indicate signature overloads inline:
|
I appreciate that you're trying to avoid fixing a syntax that we might want to change again in the future. However your proposal also has to be changed in the future. So from the POV of early adopters of whatever syntax we end up agreeing on here there's little difference -- either way they will eventually have to rewrite it. But I still really don't like that that requires you to use the Python-2 style "fallback annotations" (in comments) even when using Python 3, nor that it's so different from the PEP 484 syntax for stubs. In the case of Tornado's utf8(), it would stick out as a sore thumb because Ben's plan there is to release a version that has inline annotations (for use with PY3 only). As to the confusion between |
I forgot one more thing.
Using my proposal we could move this to a .py file and add an implementation, like this:
If we were to rewrite this using your proposal, we'd lose two things:
Anyway, while I totally agree that my proposal isn't ideal (note that this issue was closed once before without action and the PEP specifically forbids overloading in .py files), I disagree that your proposal is better. |
For a long time we weren't even sure whether this would be a useful feature to have, so the elegance and compactness of the syntax isn't as important as intuitiveness and ease of use -- most users would use this only rarely, if ever. If we'd use almost the same syntax in .py files and .pyi files usability would likely be better compared to inventing a new syntax as there would be less to learn and remember. |
Also, @overload can use keyword args to pick the right signature, e.g.
|
The variable signature + keyword arg examples are persuasive, so I'm happy to withdraw the idea of using the comment based fallback notation. |
OK, let's do it!
|
So in py2-compatible mode (using comments), it would look like this? @overload
def utf8(value):
# type: (None) -> None
pass
@overload
def utf8(value):
# type: (bytes) -> bytes
pass
@overload
def utf8(value):
# type: (unicode_type) -> bytes
pass
def utf8(value): That's clunky, but it works and I can live with it for the few cases where this comes up. One concern I have with this change to |
Yes, that's what it would look like.
The 3.5.0 (and 3.5.1) problem is inherent to provisional features. But
yes, it is unfortunate. AFAIK mypy doesn't mind if you have something
inside "if False", it will still type-check it.
(Anyway, we haven't implemented this yet. But I'm pretty sure this is
what it will look like -- the python-dev/ideas discussion seems to
have settled.)
|
If you like this we should (again) push the discussion on python-dev.
|
I've updated the PEP (both here and in the peps repo) to describe this. The typing.py module in this repo also supports it, but I haven't pushed it to PyPI (there's a queue of things to do still). mypy doesn't support it yet, we'll track that at python/mypy#1136 . |
PEP 484 says that
@overload
is only allowed in stubs.But if I have a function like this:
then the most precise type is an overload:
This particular case could, of course, be handled by
But I can easily construct other examples that can't be solved by type variables.
I don't think that
@overload
requires any additional dispatch machinery in Python (despite what the PEP says) -- it merely describes what the function can do in a more precise way than this:The text was updated successfully, but these errors were encountered: