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

Skip to content

Add __orig_bases__ to Generic #7827

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

Conversation

hmc-cs-mdrissi
Copy link
Contributor

Resolves #7811

I'm unsure why Generic is a _SpecialForm when at runtime it's normal class. I tried to make smallest change to Generic that just adds __orig_bases__.

@github-actions

This comment has been minimized.

@JelleZijlstra
Copy link
Member

Not sure this will make a difference to any type checkers. Generic is not treated like a regular base class.

@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. πŸ€–πŸŽ‰

@hmc-cs-mdrissi
Copy link
Contributor Author

hmc-cs-mdrissi commented May 11, 2022

Hmm, experimenting with pyright I don't see a difference locally with this change. If I try swapping to class and doing

class Generic:
  __orig_bases__: ClassVar[tuple[type, ...]]

It does look like pyright uses it. But downside is it causes other aspects of generic to no longer work.

Alternative that's safer for type checkers is add __orig_bases__ to class type. It's a lie for non generics but would fix some false positives. If that's an acceptable lie I can make that change.

@AlexWaygood
Copy link
Member

Alternative that's safer for type checkers is add __orig_bases__ to class type.

I'm fine with this if we can figure out a way to add it to Generic, but I would be -1 on adding it to type. This attribute is basically an undocumented implementation detail (even the throwaway reference in PEP 560 explicitly warns you against using it). If we add it to type, that doesn't match the runtime, and means it'll start showing up in autocompletions in IDEs for all class objects. All that for a use case that seems fairly niche :/

@hmc-cs-mdrissi
Copy link
Contributor Author

hmc-cs-mdrissi commented May 11, 2022

I'm unsure how to make Generic stub declare this. It looks like each type checker special cases generic in ways that makes me unclear if it's possible to make them happy. Alternative approach I experimented with was,

class Generic:
    def __class_getitem__(cls, params: Any) -> Any: ...
    __orig_bases__: tuple[type, ...]

This approach breaks pyright's type variable binding logic. It does make __orig_bases__ recognized, but it's treated as tuple and all generics end up losing there type arguments. mypy test cases pass, but it doesn't seem to affect mypy.

I also tested adding it to _SpecialForm. That looks to be a noop and does nothing. The current approach of _GenericSpecialForm also looks to be a noop.

Amusingly deleting Generic entirely does affect type checkers and causes mypy to crash (pyright runs, with many thousands of errors).

My guess is to add it to Generic will require each type checker to add some logic for this special case as they likely all have non standard handling for Generic as a type stub. Unsure it's worthwhile doing a feature request to each type checker to handle Generic type stub.

I do agree this use case is pretty niche though and my guess is if type lie isn't worth it is probably better to close pr.

edit: Well I'll mention it to pyright and maybe take a look at mypy eventually if it can be small contribution there.

@hauntsaninja
Copy link
Collaborator

In general, trying to type various aspects of the runtime implementation of typing has been notoriously fragile with little benefit.

  • Type checkers tend to special case these constructs heavily, so you're likely to break a type checker and often unlikely to convince them that things work the way you typed it
  • Historically the runtime implementations have been very unstable, so it's just been busy work
  • Users interested in this kind of thing are often doing things that aren't expressible in the type system anyway

So yeah, nice if you could make it work for cheap, but seems like that's not the case :-) Maybe we should put a comment warning in the file.

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.

Support type.__orig_bases__ as defined in PEP 560
4 participants