Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python and Pylance, cannot access member

please, help me with python typing. I use VSCode, so, by default it uses Pylance (based on Pyright).

In my services there are sometimes situations, where instantiation of a class depends on environment.

Very simple example

class SettingsA():
    ...


class SettingsB(SettingsA):
    param = 10


if os.getenv('env') == 'A':
    settings = SettingsA()
else:
    settings = SettingsB()


print(settings.param)

But Pylance shows me an error

Cannot access member "param" for type "SettingsA"
  Member "param" is unknownPylancereportGeneralTypeIssues
(variable) param: Unknown | int

While developing locally os.getenv('env') is always None or !='A'.

I know I can use # type: ignore. But it seems for me wrong in such situation.

How can I solve this issue?

like image 738
Vadim Avatar asked Sep 12 '26 09:09

Vadim


1 Answers

I think that's because Pylance has to access environment variables and then analyze that condition. Apparently it doesn't do that. You may ask them on Github issues about the reason. (probably because it maybe hard to implement? hits the performance? can be error prone? idk)

All Pylance can say is that the type of settings is the Union of those two classes so it cannot have param, and it's saying the right thing.

One solution would be to define param on SettingsA and assign it to None (which means it doesn't have value). Basically SettingsA would have all the default values (which can be None) and SettingsB overrides them.

Another option beside # type: ignore is cast():

from typing import cast

if os.getenv('env') == 'A':
    settings = SettingsA()
else:
    settings = SettingsB()

settings = cast(SettingsB, settings)

you do it once instead of ignoring the type every time you use param on settings object.

like image 64
SorousH Bakhtiary Avatar answered Sep 13 '26 23:09

SorousH Bakhtiary