Ok, so this is just one of many examples but the most immediate one is where I don't care about the immutable sanctity of the variable I have just declared.
I often use Python for data munging and I'll frequently write code that goes
Where the type of the value being assigned to foo is different each time. Now, obviously (in this simplistic example that misses subtleties) I could declare a new variable for each transformation step or do some composite type building type thing or refactor this into separate functions for each step that requires a different type but all of those options are unnecessary busy work for what should be a few simple lines of code.
Thanks, now I get why you feel like the type system is fighting your style of programming.
> all of those options are unnecessary busy work for what should be a few simple lines of code
If you re-type your variable often, then how do you make sure you’re really keeping track of all those types?
If you re-type it only a few times, then I’m not entirely convinced that declaring a few additional variables really constitutes busywork.
Small example with additional variables instead of re-typing the same variable:
# pylint: disable=disallowed-name, missing-function-docstring, missing-module-docstring, redefined-outer-name
from typing import NewType
NEEDS_CHECKING = True
NotCleaned = NewType("NotCleaned", str)
Checked = NewType("Checked", str)
Cleaned = NewType("Cleaned", str)
original_foo = ["SOME ", "dirty ", " Data"]
annotated_foo = [NotCleaned(item) for item in original_foo]
cleaned_foo = [
Cleaned(item.lower().strip().replace("dirty", "tidy"))
for item in annotated_foo
]
foo: list[Checked | Cleaned]
if NEEDS_CHECKING:
for idx, item in enumerate(cleaned_foo):
if item and (item[0] == " " or item[-1] == " "):
raise RuntimeError(f"Whitespace found in item #{idx}: {item=}")
if "dirt" in item:
raise RuntimeError(f"Item #{idx} is dirty: {item=}")
foo = [Checked(item) for item in cleaned_foo]
else:
foo = list(cleaned_foo)
print(foo)
# => ['some', 'tidy', 'data']
This survives strict type checking (`mypy --strict`). I don’t feel that renaming the variables introduces much noise or busywork here? One might argue that renaming even adds clarity?
Can you help me out with an example of a Python usage pattern against which the type system seems to be fighting?