I have an overloaded method with different return types per below;
@ overload
def __get_db_key(self, key_suffix: str, decode_result: str) -> str: ...
@ overload
def __get_db_key(self, key_suffix: str, decode_result: None) -> bytes: ...
@ overload
def __get_db_key(self, key_suffix: str) -> bytes: ...
def __get_db_key(self, key_suffix: str, decode_result: str | None = None) -> str | bytes:
"""return a value directly from the db by key"""
max_tries = 3
key = self._key_prefix + key_suffix
for _ in range(max_tries):
try:
result: bytes = self._db.get(key.encode('utf8'))
return result if decode_result is None else result.decode(decode_result)
except plyvel.CorruptionError:
print(traceback.format_exc())
self.__repair()
continue
sys.exit(1)
I'm calling this method as below;
db = json.loads(self.__get_db_key('s', 'utf8')[1:])
for key in db:
self._namespace_keys.append(str(key[0]))
if len(self._namespace_keys) == 0:
self._namespace_keys.append('1')
for key in self._namespace_keys:
result = self.__get_db_key(f"-{key}")
if result is not None:
if any(x in result[:1] for x in [b'\x00', b'\x01']):
self._collections[key] = self.__unserialize(result)
When run, this code all works fine, however PyLint is telling me that self.__get_db_key('s', 'utf8')[1:]
and result[:1]
are unsubscriptable even though the method can only return str or bytes, so the return value should be "slice-able".
If I remove the overloaded methods from __get_db_key the PyLint error goes away but I instead get the below MyPy error:
Unsupported operand types for in ("bytes" and "Union[str, bytes]")
Argument 1 to "__unserialize" of "LDBService" has incompatible type "Union[str, bytes]"; expected "bytes"
These two errors are specified for the two below lines of code;
if any(x in result[:1] for x in [b'\x00', b'\x01']):
self._collections[key] = self.__unserialize(result)
Thanks.
I have no idea why this was required but it got rid of the PyLint errors..
keys = str(self.__get_db_key('s', 'utf8'))[1:]
for key in json.loads(keys):
self._namespace_keys.append(str(key[0]))
if len(self._namespace_keys) == 0:
self._namespace_keys.append('1')
for key in self._namespace_keys:
result = bytes(self.__get_db_key(f"-{key}"))
if result is not None:
if any(x in result[:1] for x in [b'\x00', b'\x01']):
self._collections[key] = self.__unserialize(result)
I simply wrapped the calls in str/bytes as required before attempting to slice... even though the method was already returning those types.