I'm attempting to write a generic class in Python 3.11 that should be able to process a list of elements using different processing classes (A
or B
in this example). My goal is to use the type variable T
to specify the processing class that should be used.
Clarification: Each element x
within the list X
requires an individual initialization of the subclass A
or B
, so initializing is only possible withing the process()
method.
Here's my code:
from typing import List, Self, TypeVar, Generic
class A:
def __init__(self):
pass
def process(self, x):
return x + 1
class B:
def __init__(self):
pass
def process(self, x):
return x + 2
T = TypeVar("T", A, B)
class ListProcessor(Generic[T]):
"""Apply a Transformer to the individual list elements."""
def __init__(self, processor: T):
self.processor_class = processor
self.processors: List[T] = [] # <- Pylance complains! see error message (1)
def process(self, X) -> List:
x_processed = []
for x in X:
proc: T = self.processor_class() # <- Pylance complains! see error message (2)
result = proc.process(x)
x_processed.append(result)
self.processors.append(proc)
return x_processed
lp = ListProcessor(B)
lp.process([1, 2, 3])
The output of the above is:
[3, 4, 5]
which is what I expect. But while the code runs, Pylance type checker complains in VSCode.
For the line self.processors: List[T] = []
, I get:
Variable not allowed in type expression PylancereportGeneralTypeIssues
T: ~T
(constant) T: Unknown
For the line proc: T = self.processor_class()
, I get:
Object of type "A*" is not callablePylancereportGeneralTypeIssues
Object of type "B*" is not callablePylancereportGeneralTypeIssues
I'm struggling to understand these error messages. Could someone help clarify why these errors occur and how I can fix them?
Inded I totaly miss read self.processors: List[T] = []
, sorry :')
Though it seems like vscode is not complaining about anything here, I think changing the processor: T
by processor: Type[T]
and the process function to proc: T = self.processor_class()
to proc = self.processor_type()
should do the job.