Skip to content

Use of methods on dynamically loaded instances of abstract base classes raise reportAbstractUsage errors #7105

@joel-wright

Description

@joel-wright

In our project we dynamically load implementations of abstract base classes at runtime based on config. Since pyright 1.1.345 all uses of methods labelled as abstract on the base class of those dynamically loaded instances are detected as calls to unimplemented abstract methods and flagged as errors.

I have tried to provide a minimal reproduction here:

from abc import ABC, abstractmethod
from typing import Type, TypeVar


class ABase(ABC):
    """Base class"""

    @abstractmethod
    def some_a(self) -> int:
        """Simple method"""
        raise NotImplementedError


class AImpl(ABase):
    """Implementation of ABase"""

    def __init__(self):
        self.a = 10

    def some_a(self) -> int:
        """Implementation of simple method"""
        return self.a


T = TypeVar("T")
LOOKUP_FACTORY = {"ABase": AImpl}


def get_me_an_object(clz: Type[T]) -> T:
    if clz.__name__ in LOOKUP_FACTORY:
        factory = LOOKUP_FACTORY[clz.__name__]
        ret = factory()
        if not isinstance(ret, clz):
            raise RuntimeError("wrong type from factory")
        return ret
    raise RuntimeError("Unknown")


def run():
    d_a = get_me_an_object(ABase)
    print(d_a.some_a())


if __name__ == "__main__":
    run()

Pyright versions <=1.1.344 are happy with the above example, but versions >=1.1.345 raise an error on the use of some_a():

testcase.py:41:11 - error: Method "some_a" cannot be called because it is abstract and unimplemented (reportAbstractUsage)

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions