I have following class
class ProcessRunner:
def __init__(self, network: nn.Module) -> None:
self.network: nn.Module = network
def run(self, processes: List[Process]):
for process in processes:
process.network = self.network
self.network = process.update()
Which shows in function run for self.network and process.update() following Errors:
Cannot assign member "network" for type "Process"
Type "Module | None" cannot be assigned to type "Module"
"None" is incompatible with "Module"PylancereportAttributeAccessIssue
and
Cannot assign member "network" for type "ProcessRunner*"
"None" is incompatible with "Module"PylancereportAttributeAccessIssue
I think I understand that those issues a are partial coming from my Protocol Class Process, which looks like this:
@runtime_checkable
class Process(Protocol):
network: nn.Module
def update(self, **kwargs):
...
But I do not understand completely what causes the issue here:
- The second issue might appear because, the
updatemethod doesn't return the network here. Okay solution could be that the network is only part of theProcessRunnerclass. But how can a method access it in this case? - I have no clue what the first issues triggers. The object in the Protocol class as well in the
ProcessRunnerclass are both of typenn.Module. Why is it not satisfied then? or is this an issue which appears by the second issue?
The main problem is that you are assigning the result of
process.update()toself.network, which is inferred to beNone.self.networkhas the type of, as you would expect,Module.Noneclearly isn't of the same type, hence the first error:Now that you have assigned
Nonetoself.network, Pyright thinks that it is of typeModule | None. However,Process.networkis of typeModule, so a second error is reported:One solution is to explicitly specify the types:
(playground link)
If
.update()is not intended to return anything, then don't assign that toself.network:(playground link)
You could also define a more ergonomic
Processinterface:(playground link)