My script writes to file chunk by chunk, using pre-generated data patterns:
# Data pattern generator
def get_random_chunk_pattern():
return ''.join(random.choice(ascii_uppercase + digits + ascii_lowercase) for _ in range(8))
....
# DedupChunk class CTOR:
class DedupChunk:
def __init__(self, chunk_size, chunk_pattern, chunk_position=0, state=DedupChunkStates.PENDING):
self._chunk_size = chunk_size # chunk size in bytes
self._chunk_pattern = chunk_pattern
self._chunk_position = chunk_position
self._state = state
self.mapping = None
@property
def size(self):
return self._chunk_size
@property
def pattern(self):
return self._chunk_pattern
@property
def position(self):
return self._chunk_position
@property
def state(self):
return self._state
....
# Here Chunk object is being initialized (inside other class's CTOR):
chunk_size = random.randint(64, 192) * 1024 # in bytes
while (position + chunk_size) < self.file_size: # generating random chunks number
self.chunks.append(DedupChunk(chunk_size, DedupChunkPattern.get_random_chunk_pattern(), position))
....
# Actual writing
with open(self.path, 'rb+') as f:
for chunk in self.chunks:
f.write(chunk.pattern * (chunk.size // 8))
PyCharm
displays "Expected type 'Union[str, bytearray]' got 'int' instead
" warning in write method
But when removing the division in
f.write(chunk.pattern * chunk.size)
, or doing division outside:
chunk.size //= 8
f.write(chunk.pattern * chunk.size)
warning disappeared
What actually happened here?
Thanks
Ignore this warning. The IDE is making a best guess (from limited information) as to what the data type will be at runtime, but it is guessing wrong. That is, it is fairly reasonable to expect that something multiplied by an int
will result in an int
if you don't know what that something actually is.
If you really want to solve this then tell the IDE what you expect chunk.pattern
to be by writing a doc string for your class (or using annotations to provide type hinting).
eg.
class DedupChunk:
"""
:type _chunk_pattern: str
... other fields
"""
... # rest of class
With newer versions of python, then the preferred syntax would be:
class DedupChunk:
def __init__(self,
chunk_pattern: str,
# ... more args
):
self._chunk_pattern = chunk_pattern
... # rest of class
For local variables or class variables you can annotate the variables.
# given f() has an unknown return type
foo: str = f() # annotate as type str and initalise
bar: str # only annotate as type str, but leave uninitialised
class MyClass:
foo: str = f()
bar: str