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

Type for classes expecting a certain generic parameter #7791

Closed
ntninja opened this issue Oct 24, 2019 · 5 comments
Closed

Type for classes expecting a certain generic parameter #7791

ntninja opened this issue Oct 24, 2019 · 5 comments

Comments

@ntninja
Copy link

ntninja commented Oct 24, 2019

  • Request Type: Feature Request

  • Mock-up repro (more detailed mock-up here):

    import abc
    import typing
    
    
    # Define two similar base types `ABase` & `BBase` doing their thing
    class ABase(metaclass=abc.ABCMeta):
    	@abc.abstractmethod
    	def get_some_value(self) -> str: ...
    
    class BBase(metaclass=abc.ABCMeta):
    	@abc.abstractmethod
    	def get_some_value(self) -> bytes: ...
    
    
    # Define generic type over the two types defined above
    AnyBase = typing.TypeVar("AnyBase", ABase, BBase)
    
    
    # Define function that accepts a class as a parameter and generates two classes
    # based on the above types using the received class as a mixin
    def generate_subclasses(cls: typing.Type[typing.Generic[AnyBase]]) -> (ABase, BBase):
    	class AClass(cls[ABase], ABase): ...
    	class BClass(cls[BBase], BBase): ...
    	return AClass, BClass
    
    
    # Usage of the above
    class Mixin(typing.Generic[AnyBase]): ...
    A, B = generate_subclasses(Mixin)
  • Actual behaviour: There does seem to be any way in mypy to define a parameter as expecting “a class that is generic over some known TypeVar T”. Instead mypy lets me know that “Variable "typing.Generic" is not valid as a type” and at runtime “TypeError: typing.Generic[~AnyBase] is not valid as type argument” is raised.

  • Expected behaviour: Some way to do this.

  • mypy version: 0.730

  • Python version: 3.7 (Debian)

  • mypy flags: None

It makes more sense when you see this in full as part of a cooperative multiple inheritance scheme involving #7790 and #7191… This example is indeed not very strongly motivated on its own, but it should work as nevertheless.

@msullivan
Copy link
Collaborator

I don't fully understand the proposed use here, but I think you are proposing higher kinded types?

Surprisingly we don't have an issue open for that.

They are something I think we would like but are not on the roadmap for implementing currently.

@ntninja
Copy link
Author

ntninja commented Oct 26, 2019

While I'm not very well acquainted with type theory lingo, I'm pretty sure what I describe above is indeed higher kindedness.

Essentially what I'm trying to do is expect a class that is generic over some known type variable. As such I need the type over of such classes, which afaik is indeed what higher kindedness is is used for (currently mypy just gives an error that you cannot take the type of a class).

The reason I want to do this is that I have two similar ABCs that are close enough that, in simple cases, one can write one can write an implementation that is compatible with both at the same time. The function generate_subclasses then takes this implementation (ie: any class abstract of the type variable AnyBase) and generates actual class implementations for each of these ABCs by using the given implementation as a mixin for each of them.

(Of course the real code of of generate_subclasses is a bit longer, but the above is the essence of it.)

@ntninja
Copy link
Author

ntninja commented Oct 26, 2019

Also generate_subclasses would have to return the type (typing.Type[ABase], typing.Type[BBase]) if this were implemented I guess?

[I renamed generate_superclasses to generate_subclasses since the first name was pretty much completely wrong.]

@ilevkivskyi
Copy link
Member

@msullivan

Surprisingly we don't have an issue open for that.

This is mostly because there is already python/typing#548, I am however fine with having our own place for discussions. There are however two other (specific) feature requests that are closely related: #2354 and #6066

@hauntsaninja
Copy link
Collaborator

Closing as a duplicate of python/typing#548

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants