-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Allow __init__ with signature but no return type #604
Comments
Hm, I think the return type for init should be None. A "return " inside an init is almost certainly caused by a misunderstanding. (Maybe you're thinking of new, which does return the object it created?) |
Ah, the issue is that the error message is wrong. The message should say that the return type must be None? The message may be a relict from times before Python-compatible syntax. |
But why do I have to specify the return type at all? Can't it default to On Wednesday, March 18, 2015, Jukka Lehtosalo notifications@github.com
--Guido van Rossum (on iPad) |
Because of consistency. Consider
Would this be dynamically typed or statically typed? The current approach is to treat any function that has no annotation (no argument or return types) as dynamically typed, and statically typed (i.e. type checked) otherwise. The Same goes for functions in general:
|
Hm. I think it'd suck if we'd have to develop the habit of adding explicit On Thu, Mar 19, 2015 at 8:11 PM, Jukka Lehtosalo notifications@github.com
--Guido van Rossum (python.org/~guido) |
Okay, let's reopen this. Here's a proposed new spec. Let me know if it matches your thinking.
(In my Python corpus, these account for about 15% of all An What about other functions and methods that have arguments with types but don't have an explicit return type? Should they always default to an
|
It's a tricky issue, since we need to balance the desire to catch errors in the body of the function (what if a return type was intended but accidentally omitted?) with the need to derive the most useful return type for the benefit of checking call sites, as well as making the system be pleasant to use. I think for methods in general the status quo is fine, but (2) and (3) have some slight advantage, and some even slighter downside. However I still think |
I'm leaning towards using the same convention everywhere (2) -- missing return type (if the signature has argument types) is the same as Still, a convention of using an explicit Here's some more stats (these are actually pretty interesting): In my corpus about half of all methods have signature |
I'm assuming those argument-less None-returning methods are some kind of pattern to set/clear specific flags? E.g. set_debug(). Would be interesting to look at these a bit more, since the stats look a bit suspicious. OTOH it's understandable that there aren't many top-level functions like that -- changing global state is frowned upon more than changing instance state. |
I also realized that I'm not sure what your proposal is, exactly. Do you propose to assume ->None for all functions and methods that don't have an explicit return annotation? Or only for those that have at least one argument annotation? Or only for those that have no "return " in their body? (And how would the latter differ?) |
Sorry for being vague. Here's a more explicit version of my proposal: If a function or method has at least one argument annotation and no return type annotation, the return type would implicitly be The body of a function is not type checked, if it has no argument type annotations and no return type annotation. All the argument types and the return type are implicitly Here's a sample of 40 method names with only
I didn't look at the implementations, but I'd guess about |
OK, the proposal looks good. Unit tests are a rather special case in a sense -- the TestCase class encourages having lots of parameter-less None-returning functions (all test functions, of course, but also setUp and tearDown, and often code shared between tests is also written in this style). Do you have a sample that excludes tests? |
Here's a sample where test, setUp and tearDown methods are filtered out:
Now it's actually a bit tricky to figure out which of these will return a value, but it seems that a fairly small fraction would have |
As far as I can understand it, what was proposed here doesn't seem to have been implemented. Consider this test case (from check-classes.test)
This suggests that an explicit return type of This appears to go against the proposal here which was (as far as I understand it) to only enforce this for As @gvanrossum points out above, it's a bit cumbersome to have to add "-> None" to all init methods just to make mypy happy. Can anyone comment? |
We decided to require the explicit |
It's a real shame to have to add http://pylint-messages.wikidot.com/messages:e0101 and a https://docs.python.org/2/reference/datamodel.html#object.__init__ ...Is there a way to, at least, suppress these errors? EDIT: Actually, I think I can live with this and agree with the reasoning. Thanks for the awesome tool! |
You can also use the following regexp's to find and replace offending For init's on a single line --> find: For init's accross multiple lines --> find: |
Has there been any discussion about an |
There has been a lot of discussion about various tools for automatically generating annotations. A tool that would automatically improve annotations by inserting missing |
@gvanrossum I'm little bit confused. Is it possible to return value by |
No, |
Oh, ok. I don't understand why mypy requires explicit type declaration for |
@rostislav-simonik -- I would imagine because if you have an Basically, we add a little bit of redundancy in exchange for consistency -- as the Zen of Python says, "In the face of ambiguity, refuse the temptation to guess". |
What is the status? Is final decision made? Is somebody assigned with the implementation? I can work on it, if there is no one available. |
@onlined We are happy to accept a PR that implements the proposal. Nobody is working on this yet. |
…_subclass__ (#5677) Implements #604 (comment).
…_subclass__ (python#5677) Implements python#604 (comment).
As discussed in python/mypy#604, functions with at least one argument type annotation are allowed to omit the return type annotation, in which case it defaults to `None`. However, functions with no arguments cannot have argument type annotations, so the return type of `None` must be explicitly specified.
As discussed in python/mypy#604, functions with at least one argument type annotation are allowed to omit the return type annotation, in which case it defaults to `None`. However, functions with no arguments cannot have argument type annotations, so the return type of `None` must be explicitly specified.
As discussed in python/mypy#604, functions with at least one argument type annotation are allowed to omit the return type annotation, in which case it defaults to `None`. However, functions with no arguments cannot have argument type annotations, so the return type of `None` must be explicitly specified.
Although sometimes found unintuitive, the reutrn type of a class's __init__ method is best annotated as None, as in other functions that return implicitly or by operand-less return statements. Note that this is only a minor improvement, effectively just a style fix, because mypy treats __init__ specially and, *when at least one parameter is annotated*, its return type is implicitly None rather than implicitly Any like other functions. All the __init__ methods modified here did already have one or more annotated parameters. However, having __init__ methods without the return type makes it easier to introduce a bug where an __init__ method with no parameters besides self -- which itself should almost always be unannotated and is properly inferred -- is written and the return annotation needed to get mypy to regard it as statically typed, so it checks it at all, is omitted. (It is also inelegant when one considers the meaning of __init__ and the distinction between it and __new__.) This commit does not add any return type annotations to functions in the test suite, since the test suite doesn't currently use static typing. Further reading: - https://peps.python.org/pep-0484/#the-meaning-of-annotations - python/mypy#604 - gitpython-developers#1755 (comment)
Code:
Error:
The return type is
Any
(implicitly), andAny
should be a valid return type for__init__
.This was reported by Guido.
The text was updated successfully, but these errors were encountered: