KEMBAR78
Add flag to output error if a typed function is used with an untyped decorator by ilinum · Pull Request #3555 · python/mypy · GitHub
Skip to content

Conversation

ilinum
Copy link
Collaborator

@ilinum ilinum commented Jun 15, 2017

No description provided.

Copy link
Collaborator

@ddfisher ddfisher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before merging, can you run this against our internal codebases and make sure that there aren't too many errors and that the errors seem like they really should be fixed?

mypy/checker.py Outdated
def is_typed_callable(c: Optional[Type]) -> bool:
if not c or not isinstance(c, CallableType):
return False
return all(not isinstance(t, AnyType) or not t.implicit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think this would be much clearer as not any(isinstance(t, AnyType) and t.implicit).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If you disagree, feel free to leave as-is.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think that's better!

mypy/checker.py Outdated
func: FuncDef,
dec_type: Type,
dec_expr: Expression) -> None:
def is_typed_callable(c: Optional[Type]) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to not define subfunctions unless they actually use variables from the parent function. I'd make these top-level instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, that makes sense.

@gvanrossum
Copy link
Member

The main concern is that this will be seen as a regression by people who have carefully annotated (part of) their codebase but are using untyped decorators (maybe from another part of their codebase). On the one hand these people have a problem (unannotated code persists, and the call sites may have further errors), on the other hand they may not have the bandwidth to solve it quickly, and until it's solved they can no longer use the --disallow-untyped-defs flag at all to require that all functions to be annotated. Which is why I would prefer this to be a separate flag (e.g. --disallow-untyped-decorators).

@ilinum
Copy link
Collaborator Author

ilinum commented Jul 6, 2017

After thinking about this some more, I agree with you, this change would discourage use of --disallow-untyped-defs, which is something we definitely we want to avoid.

I think it would be reasonable to have a new flag --disallow-untyped-decorators.

Just a note that there is --disallow-any=decorator (460a13b) that disallows functions that have Any in their signature after decorator transformation.

@gvanrossum
Copy link
Member

gvanrossum commented Jul 6, 2017 via email

@ddfisher
Copy link
Collaborator

(The flag is actually --disallow-any=decorated, which is definitely better than --disallow-any=decorator.)

@ddfisher
Copy link
Collaborator

ddfisher commented Jul 12, 2017

I think a new flag is the right way forward here. @ilinum can you make that change?

@ilinum ilinum changed the title Output error if a typed function is used with an untyped decorator and the --disallow-untyped-defs flag is enabled Flag to output error if a typed function is used with an untyped decorator Jul 20, 2017
@ddfisher ddfisher changed the title Flag to output error if a typed function is used with an untyped decorator Add flag to output error if a typed function is used with an untyped decorator Jul 20, 2017
@ddfisher
Copy link
Collaborator

(Minor note: PR/commit names should be actions.)

Copy link
Collaborator

@ddfisher ddfisher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some functionality and testing changes needed.

mypy/checker.py Outdated
def is_typed_callable(c: Optional[Type]) -> bool:
if not c or not isinstance(c, CallableType):
return False
return not any(isinstance(t, AnyType) and t.implicit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is checking for a fully typed callable, but we should check for a callable with that has any annotations. This case should have appeared in tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

return i

[case testDisallowUntypedDefsMultipleUntypedDecorators]
# flags: --disallow-untyped-decorators --disallow-untyped-defs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the --disallow-untyped-defs part of this test testing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, my original thinking was to make sure to interacts well with --disallow-untyped-defs but I think that the flags don't have that much in common. I removed the test and added another one for multiple decorators.

z.py:1: error: Function is missing a type annotation
x.py:1: error: Function is missing a type annotation

[case testDisallowUntypedDefsUntypedFunc]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't this test be in check-flags.test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure of the original reason.
Moved to check-flags.test.


@d # no error
def f(): pass

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for partially typed functions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@ilinum
Copy link
Collaborator Author

ilinum commented Aug 3, 2017

Okay, code review feedback should be addressed now!

Copy link
Collaborator

@ddfisher ddfisher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Tiny tiny nit -- feel free to merge if you disagree, otherwise fix and then merge.

mypy/checker.py Outdated

self.check_for_missing_annotations(fdef)
if 'unimported' in self.options.disallow_any:
if fdef.type and isinstance(fdef.type, CallableType):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think this may be slightly clearer as not all(... and ...)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yep, I think that's better!
I will make the change, make sure it passes the tests and then merge.

@ilinum ilinum merged commit 7d7c71d into python:master Aug 3, 2017
@ilinum ilinum deleted the disallow-untyped-defs-decorated branch August 3, 2017 19:37
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

Successfully merging this pull request may close these issues.

3 participants