Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support module-level __getattr__ #3647

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

Merged
merged 4 commits into from
Jul 18, 2017

Conversation

JelleZijlstra
Copy link
Member

@JelleZijlstra JelleZijlstra commented Jul 2, 2017

Fixes #2496

PEP 484 specifies that stubs can add a global __getattr__ function to indicate that they have arbitrary other attributes. See python/typeshed#5 and python/typing#181.

This implementation goes beyond the spec in one way:

  • If the module-level __getattr__ has a more precise return type than Any, we use it.

@JelleZijlstra
Copy link
Member Author

I think the Travis failure is a flake.

@emmatyping
Copy link
Member

The Travis flakiness is rather annoying. I think I will get in touch with them and see if they have any ideas of why it is doing that. As for the PR, I left a couple of comments, I think the only big question is the scope of support for this, how limited/free we want to make that. I think the PEP might need some clarification either way.

reveal_type(has_getattr.any_attribute) # E: Revealed type is 'Any'

[file has_getattr.py]
__getattr__ = 3
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should allow this to mean Any. The text of the PEP specifies a function;

To make type checkers aware of this, the file can contain the following code:

def __getattr__(name) -> Any: ...

Furthermore, based on the context of the PEP, I think this should only be allowed in stub files. If people want to Any attributes in Python files, it is less intrusive and cleaner imo to have them # type: ignore the file, but I think this needs discussion.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point; I'll just make it ignore __getattr__ if it's not a function.

I'd prefer to keep allowing __getattr__ in .py files, not stubs, too. It's potentially useful (you might use it if you were to write annotated code for the user module from python/typeshed#1454) and it makes the implementation simpler if we don't have to check whether we're in a stub.

Copy link
Member

Choose a reason for hiding this comment

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

I think it is an okay change as long as the PEP text is modified, as it does specify it to be used for stubs. I can see the benefit of using it in Python files too.


[case testModuleLevelGetattribute]

def __getattribute__(): ... # E: __getattribute__ is not valid at the module level
Copy link
Member

Choose a reason for hiding this comment

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

Another potential test: an untyped __getattr__, and if the implementation is changed to refuse it in Python files, a test for that of course.

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding the first one.

- Ignore __getattr__ if it's not a function.
- Test for untyped __getattr__ (and treat it as returning Any).

Thanks for the comments!
@emmatyping
Copy link
Member

I approved changes, but I think it'd be good to hear from @JukkaL or @gvanrossum on clarifying the PEP.
(See discussion here). The question is that the PEP states:

  • Stub files may be incomplete. To make type checkers aware of this, the file can contain the following code:
    def __getattr__(name) -> Any: ...
    Any identifier not defined in the stub is therefore assumed to be of type Any .

The implementation here adds support for it in not just stubs but also Python files. I think this is okay as long as the PEP clarifies this, or we think it is okay for MyPy to go beyond the PEP. Thoughts?

@gvanrossum
Copy link
Member

In stubs you can can lie about various things. But I don't think we should allow __getattr__ outside stubs, because this most definitely doesn't work (it will not be called when you ask for an attribute on the module object).

@JelleZijlstra
Copy link
Member Author

Just pushed a change to only allow module-level __getattr__ in stubs.

@ilevkivskyi
Copy link
Member

It looks like this now conforms to what Guido said, so I am going to merge this.

@ilevkivskyi ilevkivskyi merged commit 3814b1a into python:master Jul 18, 2017
@JelleZijlstra JelleZijlstra deleted the modulegetattr branch July 18, 2017 15:13
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.

4 participants