Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

stubgen: include __all__ in output#16356

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
JelleZijlstra merged 5 commits intopython:masterfromJelleZijlstra:stubgenall
Oct 30, 2023

Conversation

@JelleZijlstra
Copy link
Member

Fixes#10314

__version__ = ''

[out]
from m import __version__ as __version__
Copy link
Member

@AlexWaygoodAlexWaygoodOct 28, 2023
edited
Loading

Choose a reason for hiding this comment

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

This was a problem before your PR, but I'm not sure what the justification is for not importing__about__ and__author__ in the generated stub here, given that they're included in__all__ at runtime

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Yes, they're in IGNORED_DUNDERS in stubutil.py. It generally makes sense to exclude these names as they're not useful in stubs, but we shouldn't ignore them if they're in__all__.

AlexWaygood reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Pushed a change so that IGNORED_DUNDERS aren't ignored if they're in__all__.

AlexWaygood reacted with thumbs up emoji
class C:
def g(self): ...
[out]
__all__ = ['f', 'x', 'C', 'g']
Copy link
Member

Choose a reason for hiding this comment

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

Hmm. Maybe it's problematic if stubgen adds__all__ to the generated stub, even though a symbol in__all__ at runtime (in this case,g) isn't actually defined at runtime. On the other hand, maybe it's outside of stubgen's purview to worry about such things; maybe it should just copy the runtime__all__ faithfully into the stub even when__all__ is weird at runtime, as you're doing now.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

It's probably better to omit the undefined names so the generated stub won't create errors for type checkers, so I pushed that change. Could go either way though.

AlexWaygood reacted with thumbs up emoji
Copy link
Member

Choose a reason for hiding this comment

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

(For future readers of this thread: we decided to go back on this; see the discussion in#16356 (comment) for why)

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment on lines +764 to +770
ifnotname.startswith("_"):
returnFalse
ifself._all_andnameinself._all_:
returnFalse
ifname.startswith("__")andname.endswith("__"):
returnnameinself.IGNORED_DUNDERS
returnTrue
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 I prefer stubtest's heuristic here, which IIRC is something like:

  1. If the runtime has__all__:
    a. If a name is included in__all__, treat it as public
    b. Else, treat the name as private
  2. If the runtime doesn't have__all__:
    a. If the name doesn't start with_, treat it as public
    b. Else, if the name is a dunder, treat it as public unless it's one of the ones in the "excluded dunders" list
    c. Else, treat it as private

The key difference is that (IIUC) the current algorithm you have here would treatbar as a public name in this situation, whereas stubtest would treat it as private:

__all__= ["foo"]foo=2bar=3

Copy link
Member

@AlexWaygoodAlexWaygoodOct 28, 2023
edited
Loading

Choose a reason for hiding this comment

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

If we changed this algorithm in the way I'm suggesting, though, it would have an impact on existing tests such astestIncludeClassNotInAll_inspect. It would be a fairly big behavioural change. Probably best to leave it to another PR!

JelleZijlstra reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Possibly we should change this, but that feels out of scope for this PR; the logic is mostly as it was before, except that names in__all__ are now not treated as private. Your suggested change might be right, but it's better handled as an independent change.

AlexWaygood reacted with thumbs up emoji
Comment on lines 751 to +758
[case testExportPackageOfAModule_import]
import urllib.parse
__all__ = ['urllib']

[out]
import urllib as urllib

__all__ = ['urllib']
Copy link
Member

@AlexWaygoodAlexWaygoodOct 28, 2023
edited
Loading

Choose a reason for hiding this comment

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

kinda cool that stubgen has sophisticated enough inference to do this. Didn't realise that it had this capability!

class C:
def g(self): ...
[out]
__all__ = ['f', 'x', 'C']
Copy link
Member

Choose a reason for hiding this comment

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

Not sure about this. Stubtest would emit an error here if it encountered this, since__all__ is different in the stub to what it is at runtime. Rather than trying to synthesise a "corrected version of__all__", I think stubgen should just omit it from the generated stub in this situation

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Omitting it also feels wrong though, and should generate a stubtest error (not sure if it currently does). Maybe the best option is to just emit__all__ as it is at runtime, even if it includes some undefined names.

Copy link
Member

Choose a reason for hiding this comment

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

Stubtest doesn't complain if__all__ is omitted at runtime, no (though I think itshould -- see#13300).

We're in a bit of a catch-22 here if the runtime__all__ has members that don't exist at runtime. In terms of typeshed's CI:

  1. If__all__ is different in the stub to what it is at runtime, then stubtest will complain.
  2. If__all__ in the stub contains members that don't exist in the stub, pyright will complain.
  3. If__all__ is present at runtime but omitted in the stub, then neither will complain but, as you say, maybe stubtestshould complain...

I think you're right that emitting__all__ as it is at runtime is probably the least opinionated thing to do. Maybe we should just add a comment in the test cases to say that we know this is weird, but there's no obviously correct solution for this situation

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Agree, and both stubtest and pyright are correct in those errors. Ultimately if__all__ contains a name that doesn't exist, that's a bug in the runtime library, and it seems right that to work around it in typeshed we'll have to ignore an error (either through the stubtest allowlist or a type ignore).

AlexWaygood reacted with thumbs up emoji
Copy link
Member

@AlexWaygoodAlexWaygood left a comment

Choose a reason for hiding this comment

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

Looks great, thanks!

@github-actions
Copy link
Contributor

Diff frommypy_primer, showing the effect of this PR on open source code:

discord.py (https://github.com/Rapptz/discord.py): typechecking got 1.08x slower (148.6s -> 160.4s)(Performance measurements are based on a single noisy sample)

@JelleZijlstraJelleZijlstra merged commit0ff7a29 intopython:masterOct 30, 2023
@JelleZijlstraJelleZijlstra deleted the stubgenall branchOctober 30, 2023 18:48
@JelleZijlstraJelleZijlstra restored the stubgenall branchSeptember 10, 2024 23:37
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

1 more reviewer

@AlexWaygoodAlexWaygoodAlexWaygood approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Maybe __all__ should be added explicitly in stubgen

2 participants

@JelleZijlstra@AlexWaygood

[8]ページ先頭

©2009-2025 Movatter.jp