pyre-check icon indicating copy to clipboard operation
pyre-check copied to clipboard

Instantiating implementations of an abstract class from Type fails type validation

Open aspin opened this issue 5 years ago • 3 comments

Basically, if T is abstract, then pyre seems to assume that any variable annotated with Type[T] is also abstract. According to docs, Type[T] accepts subclasses of T, so I don't think this is correct behavior.

Here's a code sample demonstrating:

from abc import ABCMeta, abstractmethod
from typing import Dict, Type


class Abstract(metaclass=ABCMeta):
    @abstractmethod
    def run(self) -> None:
        pass


class FirstImpl(Abstract):
    def run(self) -> None:
        print("first")


class SecondImpl(Abstract):
    def run(self) -> None:
        print("second")


impl_mapper: Dict[str, Type[Abstract]] = {"first": FirstImpl, "second": SecondImpl}

impl_mapper["first"]().run()

And the error:

type_test.py:23:0 Invalid class instantiation [45]: Cannot instantiate abstract class `Abstract` with abstract method `run`.

aspin avatar May 21 '20 22:05 aspin

I've the same need. Is there any workaround for this? For now I'm simply suppressing the warning.

Ragsboss avatar Sep 29 '20 15:09 Ragsboss

I don't think the typechecker is wrong here--Type[T] does accept concrete subclasses of T, but it also accepts T itself--they may be instantiable, but the typechecker doesn't know that they are. What you want is a metatype that accepts concrete subtypes of Abstract but not it (or also-abstract subtypes).

isturdy avatar Mar 23 '21 17:03 isturdy

I don't think this is a correct behavior. In a statically typed language I could have a Factory method that returns an abstract class and it's not a problem.

class Foo { virtual void bar() = 0; };

std::function<std::unique_ptr<Foo>()) baz;

and calling

auto foo = baz();

wouldn't be a problem.

gruszczy avatar Jan 20 '24 22:01 gruszczy