I'm using Pylance on VSCode and I'm getting this reportUnknownMemberType warning/error for this variable, even though I can see that it knows the type.
I'm pretty new to classes so if there's a better way to do this, please let me know. My aim is to extend a parent class dict with some more keys in a subclass. The program is actually working, the parent dict gets the new key, value pair, but I want to know why I'm getting the Pylance error.
The following is the inheritance chain for these classes, the names are simplified but the structure is real. There's 3 classes involved, inheriting like Base > SubClass > SubSubClass. The Base class is found in a separate file:
#base.py
class Base:
def __init__(self, param0: str) -> None:
self.param0 = param0
self.exportable = dict[str, object]()
The 2 other classes are found in a second file:
# subclasses.py
class SubClass(Base):
def __init__(self, param0: str, param1: str, param2: str,
param3: str, param4: str,
param5: bool=True) -> None:
super().__init__(param0)
self.param1 = param1
self.param2 = param2
self.param3 = param3
self.param4 = param4
self.param5 = param5
self.exportable = {
self.param0: {
'param1': self.param1,
'param2': self.param2,
'param3': self.param3,
'param4': self.param4,
'param5': self.param5
}
}
class SubSubClass(SubClass):
def __init__(self, param1: str, param3: str) -> None:
super().__init__(name='hardcodedparam0', param1=param1, type='hardcodedparam2', param3=param3,
param4='hardcodedparam4')
self.properties = {
'name': {
'type': "string"
},
'contentBytes': {
'type': 'string',
'format': 'byte'
}
}
# this is where I get the error
new_exportable = self.exportable.copy()
self.exportable = {**new_exportable, **self.properties}
My original plan was to just use self.exportable[self.name]['properties'] = self.properties
instead of that dict merge, but I get this cannot assign error.
I also tried in SubSubClass to access SubClass's self.exportable
with super().exportable
, although I don't think it should be necessary, but when I run the program, I get an error saying that super() has no attribute 'exportable'. For what it's worth, this super()
attempt also gives the same 'cannot assign' error from above when not running the program.
With the first option (the dict merge) and the second option (assigning the new properties key and value), the program works and self.properties
dict is successfully tacked on to the inherited self.exportable
dict. But I want to know if I'm doing something wrong anyway or if Pylance is just getting confused. I think it's confused because in SubClass it saw the dict was just dict[str,Union[str,bool]]
but then SubClass B, instead of that Union[str,bool]
value, tries to add the properties
dict, which is a set of dict's itself?
Of course, I can just silence the reportUnkownMemberType error in the Pylance config, but I'm worried I'm masking something I don't know about.
Thanks
I think I may have solved this by being a little more flexible with SubClass's exportable. That is, creating an empty dict, tacking on the initial properties, and in SubSubClass tacking on any additions:
# subclasses.py
class SubClass(Base):
def __init__(self, param0: str, param1: str, param2: str,
param3: str, param4: str,
param5: bool=True) -> None:
super().__init__(param0)
self.param1 = param1
self.param2 = param2
self.param3 = param3
self.param4 = param4
self.param5 = param5
# The following two lines are a bit different
self.exportable = {}
self.exportable[self.param0] = {
'param1': self.param1,
'param2': self.param2,
'param3': self.param3,
'param4': self.param4,
'param5': self.param5
}
class SubSubClass(SubClass):
def __init__(self, param1: str, param3: str) -> None:
super().__init__(name='hardcodedparam0', param1=param1, type='hardcodedparam2', param3=param3,
param4='hardcodedparam4')
self.properties = {
'name': {
'type': "string"
},
'contentBytes': {
'type': 'string',
'format': 'byte'
}
}
# Now I can assign a key and value with no Pylance error
self.exportable[self.name]['properties'] = self.properties
The difference seems to be between
param0
) and value (subdict of param1
, param2
, param3
, etc.)param0
key and value, and then in SubSubClass just assigning a new key valueI'm not sure if this is just a workaround, if I'm just managing to trick Pylance into not complaing, or if this is the actual solution. In any case, I no longer get the Pylance errors and the program (still) works.