Skip to content

Tweak scope of # type: ignore in PEP 484 #292

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

Closed
gvanrossum opened this issue Oct 5, 2016 · 9 comments
Closed

Tweak scope of # type: ignore in PEP 484 #292

gvanrossum opened this issue Oct 5, 2016 · 9 comments

Comments

@gvanrossum
Copy link
Member

PEP 484 currently says:

A # type: ignore comment on a line by itself disables all type checking for the rest of the file.

I think that's excessive. It should probably be limited to the current indented block, e.g.

if blargh():
    # type: ignore
    1 + 'a'  # No error here
2 + 'b'  # Should be an error
@ilevkivskyi
Copy link
Member

ilevkivskyi commented Oct 5, 2016

I agree, while placing #type: ignore at top indentation level would prohibit type checking for the rest of the file.

@JukkaL
Copy link
Contributor

JukkaL commented Oct 5, 2016

Agreed.

@markshannon
Copy link
Member

Refining the extent to the enclosing scope (module/function/class) makes sense, but any narrower might be tricky.
Is it meaningful to infer types with a # type: ignore block?
What about

if cond:
    # type: ignore
    1 + 'a'  # No error here
else:
    1 + 'a'  #Is this an error?

@gvanrossum
Copy link
Member Author

gvanrossum commented Oct 5, 2016

I think that in Mark's example the second 1 + 'a' (in the else block) should not be an error. That seems easy.

The trickier bit is whether assignments still get inferred:

if cond:
    # type: ignore
    x = 42
else:
    x = 'z'

What's the type of x here? Union[int, str]? If this would work the same as just adding an inline # type: ignore to each line of the block, that's what it would mean, and that seems a fine rule.

@markshannon
Copy link
Member

if-else may be relatively easy but what about try-except-finally?

What is the motivation for this?
I can see why I might want the checker to ignore a whole function. I struggle to think of a case where I might want it to ignore just a part of a function.

@gvanrossum
Copy link
Member Author

I would definitely like to ignore a conditional block full of platform-specific imports. (E.g. if I have no stubs for them.)

I wouldn't want to have a syntax where a # type: ignore placed anywhere in a function had the effect of ignoring the entire function body.

The motivation is to define a syntax that is easy to understand and syntactically orthogonal. Given that we have at least two use cases (ignore a while function, ignore a branch of a conditional), the best approach seems to be to define the scope of # type: ignore as the remainder of the current "block" as determined by indentation. A block is a well-understood syntactic construct in Python, and used in many places. So whenever you see a block containing # type: ignore you will be able to understand the scope of that directive.

@dmoisset
Copy link
Contributor

dmoisset commented Oct 5, 2016

I'm not sure if it's abusing it a bit, but what about making no_type_check also a context manager? In that way you can write:

with no_type_check():
    'a' + 1

Here the block scope is very obvious to a reader (because context managers are conceptually tied to a block). I think this eliminates all ambiguity about else branches or try/except being covered or not. OTOH it adds an indentation level, and it's mixing a bit with a run-time concept like context managers with something that is very not run-time.

@JukkaL
Copy link
Contributor

JukkaL commented Oct 5, 2016

# type: ignore is nice in that it has no runtime overhead. It can be important in a tight loop or in a function that gets called a lot.

@gvanrossum
Copy link
Member Author

gvanrossum commented Oct 5, 2016 via email

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

5 participants