My view on typing in Python (a language I have used for decades) is that if I wanted types I would use a language designed from the ground up with strong and consistent typing built-in. Not bolt on a sort of type system which actively fights against the way I use the language on a day to day basis.

I use plenty of statically typed languages, Python's type hinting does not bring me joy.

> Not bolt on a sort of type system which actively fights against the way I use the language on a day to day basis.

Can you help me out with an example of a Python usage pattern against which the type system seems to be fighting?

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

  foo = initial_value
  ...
  foo = paritally_cleaned_up_value
  ...
  if check:
   foo = fianllylikethis
  else:
   foo = orlikethis
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?

pyright will accept this. mypy should accept this when using --allow-redefinition-new as well

> mypy should accept this when using --allow-redefinition-new as well

TIL, thank you!