Skip to content
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

use getattr to lazy load aiohttp and trio #15878

Merged
merged 8 commits into from
Jan 6, 2021
Merged

use getattr to lazy load aiohttp and trio #15878

merged 8 commits into from
Jan 6, 2021

Conversation

xiangyan99
Copy link
Member

No description provided.

@ghost ghost added the Azure.Core label Dec 18, 2020
@xiangyan99 xiangyan99 marked this pull request as ready for review December 19, 2020 00:25
try:
from ._aiohttp import AioHttpTransport
if 'AioHttpTransport' not in __all__:
__all__.extend([
Copy link
Member

Choose a reason for hiding this comment

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

__all__ is a pre-declaration of what exists, mostly to help IDE and doc to know what they would show. This means that I think this should be available even if the actualy import is not done. But putting this inside the __getattr__, it means dir is now not accurate:
image

I believe it should be possible to have __all__ correct, with a static list of strings outside of the __getattr__ but inside your if sys.version_info >= (3, 7), in order to get the regular tooling able to list the possible importable types.

Copy link
Member

Choose a reason for hiding this comment

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

@xiangyan99 I see your latest commit, doesn't fix dir, so read the spec this time and not guessing and there is a __dir__:
https://www.python.org/dev/peps/pep-0562/#specification

We're close :)

Copy link
Member

Choose a reason for hiding this comment

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

Something like:

if python > 3.7:
    ...
    def __dir__():
        return __all__

Copy link
Member Author

Choose a reason for hiding this comment

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

image

Now it works. :)

Copy link
Member

Choose a reason for hiding this comment

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

You still get the perf improvement right? None of the previous commits breaks anything?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. We still get the perf improvement with the changes.

Copy link
Member

Choose a reason for hiding this comment

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

@lmazuel I figured since I wrote a proof-of-concept of this 2.5 years ago with you in mind 😄 https://pypi.org/project/modutil/ (which also touches on __all__ and dir() as you are discovering 😁 ).

And to be clear about __all__, it exists to control from ... import * specifically, but has come to mean for some what the public API is.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, we (the azure client libraries) are part of the "assume __all__ means what the public API surface area is crowd". Primarily this is because that is what sphinx/autodoc, by default, uses it as well. So it's convenient.

@brettcannon, I'm not aware of any downsides of making this assumption - are there gotchas that we should look out for? I personally don't find the import * as a mechanism to import the "recommended"/most commonly used subset of the full public API surface area for a package/module to be a common (or good) practice.

Copy link
Member

Choose a reason for hiding this comment

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

import * is most definitely not meant to convey "recommended/commonly used"; it is entirely to make it easier to play with things in the REPL and you can't make that judgement call for people as to what is common (and import * one of the things I would remove from the language if I could).

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the "most commonly used" argument is probably the only argument that I had heard from people recommending the use of import *. But I don't think it is a common argument. The use in REPL is a much better argument, but I would agree that, given a time machine, I would still personally support a quick trip back in time and remove the support for it altogether.

@xiangyan99
Copy link
Member Author

/azp run python - storage - ci

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@xiangyan99
Copy link
Member Author

#9399

@xiangyan99
Copy link
Member Author

/azp run python - storage - ci

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@xiangyan99 xiangyan99 merged commit 9376c2f into master Jan 6, 2021
@xiangyan99 xiangyan99 deleted the core_getattr branch January 6, 2021 17:35
rakshith91 pushed a commit to rakshith91/azure-sdk-for-python that referenced this pull request Jan 8, 2021
* use getattr to lazy load aiohttp and trio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants