-
Notifications
You must be signed in to change notification settings - Fork 258
Declaring type of variable without initializing with a value #20
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
Comments
This is related to #9. |
In Python 3.6 this could become:
or
In case of
|
Łukasz: I don't think we should strive to raise a NameError in that case (the only ways I can think of are truly horrible). I don't even think that printing Undefined(...) should raise an exception -- it should just print 'Undefined(...)' (with the actual argument type instead of the dots). But it should define no other attributes or operations, and it should be unhashable (so you can't put it in a set or use it as a dict key without an error). It should also be runtime introspectable (e.g. The type checker, of course, should flag all uses of Undefined as an error (even printing it or passing it as an argument to a function or assigning it to another variable). Jukka: I prefer |
There are two reasons why mypy supports However, |
@gvanrossum, my worry is exactly that people will have to start expecting "undefined" as a possible edge-case value returned from third-party library functions, next to None and raised exceptions. That's By the time Python 3.6 comes with the I'm all ears for final decision and we can move on. |
Why would you ever have to expect Undefined? The PEP should make it very clear that such a value should never be used or returned or stored, and even though the runtime cannot check this, the static checker can (mypy currently apparently doesn't but I filed python/mypy#551 for that). And why would people use Undefined except to make the type checker happy? |
OK, final decision: The forms below are both allowed. The type checker should verify that no use is made of an undefined (or conditionally undefined) value, and at runtime most uses of undefined values except printing it will raise an exception.
These forms should mean the same thing to the type checker (but the former is faster, since it doesn't have to evaluate List[int]). |
@gvanrossum, my worry comes from the fact that Undefined will bubble up in case of bugs. This might be an unreasonable worry but I think that the following scenario is possible:
Even if you say this is not something we should design against, Undefined will show up during breakpointing in debuggers, etc. Anyway, fixed in e2e6fc4. |
Yeah, I understand it will sometimes show up in the debugger. (That's why I proposed the exception for printing it and probably for eq.) But that doesn't mean it's something that non-debugger code should ever test for -- no API should be documented as returning Undefined in certain circumstances, and that's different from the status of undefined in JavaScript (I don't know about PHP). The only remaining fear would be about people coming from JavaScript or PHP designing unPythonic APIs. I think our community is strong enough to stop that. |
Another use case where programmers may be tempted to use class A:
x = Undefined # type: int
def foo(self):
if self.x is not Undefined:
bar(self.x)
... Note that using If |
I think mypy should actually protest when it sees the "is not Undefined" We really should nip this in the bud. On Wed, Jan 14, 2015 at 10:10 PM, Jukka Lehtosalo [email protected]
--Guido van Rossum (python.org/~guido) |
Added a mypy issue for restricting where |
@ambv still doesn't like Undefined, and presents the following reasoning: 4.a. Undefined changes the runtime in ugly ways (hiding UnboundLocalErrors).
4.d. No support for multiple variables on the same line or reusing the same type. This might be introduced in a future syntax revision. My (Guido's) response is that I'm not yet convinced by this, and the easiest way is certainly to keep Undefined (since mypy already implements it). Hopefully we can decide this in person at PyCon. |
This issue is mostly obsolete. There is no |
Should we close this issue? |
Mypy has the
Undefined
helper that serves two purposes.First, it can be used as a dummy value when declaring the types of variables:
This declares
x
as a list of int, but it doesn't givex
a valid value. Any operation onUndefined
(other than passing it around and operations that can't be overloaded) will raise an exception.Second,
Undefined
can be used to declare the type of a variable without using a comment:The second example is semantically equivalent to the first example.
In my experience, being able to declare the type of a variable without initializing it with a proper value is often useful.
Undefined
is better thanNone
for this purpose sinceNone
is a valid value. If we seeUndefined
values in tracebacks then we know that somebody forgot to initialize a variable, but if we see aNone
value things are murkier. Also,None
are valid for certain operations such as if statements and equality checks (and dict lookups), and thus an unexpectedNone
value can easily go undetected. This is less likely with anUndefined
value.Also, we'd like to be able to type check uses of
None
values (for example, by requiring anOptional[...]
type), butUndefined
is compatible with all types.Some tools/implementations (jython, for example, according to Jim Baker) can't easily access types declared as comments, and the
Undefined(...)
syntax could be used as a workaround.If we decide to support both of the above variants (+ just using a
# type:
comment withoutUndefined
), we have the problem that there is no longer a single obvious way to declare the type of a variable. I don't think that the inconsistency is a major issue, since all of the variants serve useful purposes.The text was updated successfully, but these errors were encountered: