You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
abstract dataclass inheritance gives Only concrete class can be given where "Type[Abstract]" is expected #5374
importabcfromdataclassesimportdataclass@dataclass# error: Only concrete class can be given where "Type[Abstract]" is expectedclassAbstract(metaclass=abc.ABCMeta):
a: str@abc.abstractmethoddefc(self) ->None:
pass@dataclassclassConcrete(Abstract):
b: strdefc(self) ->None:
passinstance=Concrete(a='hello', b='world')
Note that this error only occurs if at least one abstract method is defined on the abstract class. Removing the abstract method c (or making it non-abstract) makes the error go away.
On Wed, Jul 18, 2018 at 9:01 PM Jonas Obrist ***@***.***> wrote:
mypy 0.620, --strict.
Sample code:
import abcfrom dataclasses import dataclass
@DataClass # error: Only concrete class can be given where "Type[Abstract]" is expectedclass Abstract(metaclass=abc.ABCMeta):
a: str
@abc.abstractmethod
def c(self) -> None:
pass
@dataclassclass Concrete(Abstract):
b: str
def c(self) -> None:
pass
instance = Concrete(a='hello', b='world')
Note that this error *only* occurs if at least one abstract method is
defined on the abstract class. Removing the abstract method c (or making
it non-abstract) makes the error go away.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#5374>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACwrMmnqdQS-PT-Ppma35aXOsPpD6X7vks5uIASAgaJpZM4VVt0v>
.
A possible simple solution is to type dataclass in typeshed as roughly (S) -> S with S = TypeVar('S', bound=Type[Any]). Another option is to consider relaxing the restriction that mypy has for Type[T] with abstract classes, but I am not sure where to draw the line.
Reacted by Jaanus Varus, Ivan Smirnov, Petr Motejlek, Brian Armstrong, Andreas Schuderer, Roberto Prevato, Rahix, Niklas Rosenstein, Jona Klemenc, Łukasz Langa and 14 more
Just a bit of context why this is prohibited: mypy always allows instantiation of something typed as Type[...], in particular of function arguments, for example:
fromtypingimportType, TypeVarfromabcimportabstractmethodT=TypeVar('T')
classC:
@abstractmethoddeff(self) ->None: ...
deffun(x: Type[T]) ->T: ...
returnx() # mypy allows this, since it is a very common patternfun(C) # this fails at runtime, and it would be good to catch it statically,# what we do currently
I am still not sure what is the best way to proceed here. Potentially, we can only prohibit this if original function argument (or its upper bound) is abstract (so function actually expects implementations to be passed). This will be a bit unsafe, but more practical, as all examples provided so far would pass.
Reacted by solstice333, Andy Jordan, Mathias Ertl, Felipe S. S. Schneider, Chris Havlin, E. M. Bray and Zev Isert
Another option is to consider relaxing the restriction that mypy has for Type[T] with abstract classes, but I am not sure where to draw the line.
I'm leaning towards allowing abstract classes to be used without restriction. Type[x] is already unsafe since __init__ can be overriden with a different signature, and I expect that the extra unsafety from allowing abstract classes would be marginal in practice. We just need to document the potential issues clearly.
Reacted by Vito De Tullio, Ryan Morshead, happy-monk, Maciej "RooTer" Urbański, Brian Armstrong, Jakub Stasiak, Neil Girdhar, Johan Olsson, Nate McMaster, Christian Grotheer and 18 more
I'm having a similar error and I don't know if it's the same problem or a different, related problem (or perhaps I'm doing something wrong), related to abstract classes and Attrs.
On the line with attr.validators.instance_of, I'm getting this error:
error: Only concrete class can be given where "Type[MetricsRecorder]" is expected
What's interesting is that this only happens with today's released Attrs 19.2.0 and last week's released MyPy 0.730. If I downgrade to Attrs 19.1.0 and keep the latest MyPy, the error goes away. If I downgrade to MyPy 0.720 and keep the latest Attrs, the error goes away.
I'm able to get around the problem by adding # type: ignore at the end of the line with attr.validators.instance_of, so I'm good for now, but I would like to know if I need to file a separate issue or if this is related or if this is a bug with Attrs.
This is really sad, given that dataclasses are being pushed as a go-to class container in 3.7+, having abstract dataclasses is not such a rare occasion. But mypy in the current state basically prohibits using it.
Given that this issue is 1.5 years old, wonder if there's any known workarounds?
Reacted by Seiya, the-vindicar, edA-qa mort-ora-y, Chris Prosser, Ben Kovitz, Peter Matula, Mischa Lisovyi, Flávio Veloso Soares, Sole Ahab, Judy and 15 more
it fails mypy with error: Only concrete class can be given where "Type[Student]" is expected. Full reproducible example here (not worth cluttering the discussion here with the total_ordering implementation). It only errors if both total_ordering and abstract_method are used. (Edit: I'm fine adding type: ignore[misc] to the @functools.total_ordering line, just thought it was worth mentioning the occurrence in this thread).
This error assumes a specific usage of the passed in type, which may be common, but still not the only way a passed in class can be used, so it is an incorrect assumption. The actual error, which is trying to instantiate an abstract class is not reported in this case.
The example in this comment highlights this assumption (#5374 (comment)):
deffun(x: Type[T]) ->T: ...
returnx() # mypy allows this, since it is a very common patternfun(C) # this fails at runtime, and it would be good to catch it statically,# what we do currently
I may have a method that reads YAML configuration that checks the expected types for returned values or the code may call static/class methods for passed in types, etc.
Here's a simplified example. In actual code, B could be Mapping or MutableMapping and get_origin would be used to figure out the underlying types or class methods could be used in a meaningful way.
fromtypingimportTypeVar, TypefromabcimportabstractmethodclassB:
@classmethoddefcm(cls, i: int) ->str:
returnstr(i) +"_ABC"@abstractmethoddefam(self) ->int: ...
classX(B):
@classmethoddefcm(cls, i: int) ->str:
returnstr(i) +"_XYZ"defam(self) ->int:
return123T=TypeVar("T", bound=B)
deffn(c: Type[T]) ->int|str:
print(c.cm(222))
return1ifc==Belse"ABC"assert(fn(B) ==1) # error: Only concrete class can be given where# "Type[B]" is expected [type-abstract]assert(fn(X) =="ABC")
A useful error would be if the code within the flagged function actually tries to call a constructor for an abstract type, not that an abstract type was passed in. It is unfortunate that this issue was closed.
Reacted by Neil Girdhar, Christian Ciach, Jan Kowalleck, Fabian Keller and Ludwik Trammer
Activity
gvanrossum commentedon Jul 19, 2018
ojii commentedon Jul 19, 2018
Removing the metaclass still triggers it. Minimal code to get that error:
ilevkivskyi commentedon Jul 19, 2018
The underlying cause is this:
A possible simple solution is to type
dataclassin typeshed as roughly(S) -> SwithS = TypeVar('S', bound=Type[Any]). Another option is to consider relaxing the restriction that mypy has forType[T]with abstract classes, but I am not sure where to draw the line.antdking commentedon Nov 6, 2018
Lifting this constraint would be great for fetching implementations to interfaces (abstracts/protocols).
ilevkivskyi commentedon Nov 7, 2018
Just a bit of context why this is prohibited: mypy always allows instantiation of something typed as
Type[...], in particular of function arguments, for example:I am still not sure what is the best way to proceed here. Potentially, we can only prohibit this if original function argument (or its upper bound) is abstract (so function actually expects implementations to be passed). This will be a bit unsafe, but more practical, as all examples provided so far would pass.
JukkaL commentedon Nov 8, 2018
I'm leaning towards allowing abstract classes to be used without restriction.
Type[x]is already unsafe since__init__can be overriden with a different signature, and I expect that the extra unsafety from allowing abstract classes would be marginal in practice. We just need to document the potential issues clearly.ilevkivskyi commentedon Nov 8, 2018
This will be false negative, so probably OK.
ZeeD commentedon Mar 23, 2019
Sorry to bother, but is there some ETA on this issue?
gvanrossum commentedon Mar 23, 2019
There is no concrete work planned for this issue yet, we are focusing on high-priority issues.
nickwilliams-eventbrite commentedon Oct 1, 2019
I'm having a similar error and I don't know if it's the same problem or a different, related problem (or perhaps I'm doing something wrong), related to abstract classes and Attrs.
I have this abstract class: https://github.com/eventbrite/pymetrics/blob/ab608978/pymetrics/recorders/base.py#L38-L39
Then I have this constant:
And this Attrs class:
On the line with
attr.validators.instance_of, I'm getting this error:What's interesting is that this only happens with today's released Attrs 19.2.0 and last week's released MyPy 0.730. If I downgrade to Attrs 19.1.0 and keep the latest MyPy, the error goes away. If I downgrade to MyPy 0.720 and keep the latest Attrs, the error goes away.
I'm able to get around the problem by adding
# type: ignoreat the end of the line withattr.validators.instance_of, so I'm good for now, but I would like to know if I need to file a separate issue or if this is related or if this is a bug with Attrs.aldanor commentedon Oct 28, 2019
This is really sad, given that dataclasses are being pushed as a go-to class container in 3.7+, having abstract dataclasses is not such a rare occasion. But mypy in the current state basically prohibits using it.
Given that this issue is 1.5 years old, wonder if there's any known workarounds?
35 remaining items
Converts `Spectrum` to a dataclass.
chrishavlin commentedon Mar 17, 2022
I'm seeing the same issue with an abstract class wrapped by
@functools.total_ordering. If you have something of the form:it fails mypy with
error: Only concrete class can be given where "Type[Student]" is expected. Full reproducible example here (not worth cluttering the discussion here with thetotal_orderingimplementation). It only errors if bothtotal_orderingandabstract_methodare used. (Edit: I'm fine addingtype: ignore[misc]to the@functools.total_orderingline, just thought it was worth mentioning the occurrence in this thread).gitpushdashf commentedon Jul 29, 2022
Hi! Does anyone have an update or simple workaround for this?
Allow generic decorators on abstarct classes (#13398)
kokumura commentedon Sep 28, 2022
Is there any further discussions about this use case?
Rahix commentedon Sep 28, 2022
@kokumura, I think the correct issue for this topic is #4717. Still unresolved, though.
gh-andre commentedon May 26, 2023
This error assumes a specific usage of the passed in type, which may be common, but still not the only way a passed in class can be used, so it is an incorrect assumption. The actual error, which is trying to instantiate an abstract class is not reported in this case.
The example in this comment highlights this assumption (#5374 (comment)):
I may have a method that reads YAML configuration that checks the expected types for returned values or the code may call static/class methods for passed in types, etc.
Here's a simplified example. In actual code,
Bcould beMappingorMutableMappingandget_originwould be used to figure out the underlying types or class methods could be used in a meaningful way.A useful error would be if the code within the flagged function actually tries to call a constructor for an abstract type, not that an abstract type was passed in. It is unfortunate that this issue was closed.
NeilGirdhar commentedon May 26, 2023
@gh-andre The issue discussing leaving/removing the error for passing abstract types to functions that accept types is #4717.
gh-andre commentedon May 26, 2023
@NeilGirdhar Thanks for pointing out the new issue. Will keep an eye on it.
Switch from dataclasses to attrs
Remove TODOs regarding Type[T] issue in mypy
Remove TODOs regarding Type[T] issue in mypy