1. 30
    1. 16

      It’s worth pointing out that there was for a while (not sure if there stil is) a bit of a divide between people who were writing typing PEPs, and the people who were doing interesting things at runtime with them. For example, this Pydantic issue where they sort of had to plead with the Python Steering Council and discussion turned up that the PEP author(s) weren’t really aware of the growing and popular ecosystem of tools doing things at runtime with type hints.

      And just to be clear for people who skim this comment or the OP article, runtime use of type hints has gone way beyond simple enforcement of type checks. As the OP mentions, several libraries let you declare objects with type-hinted members and automatically derive validation rules and serialization/deserialization from the type hints – Pydantic is the most popular, but alternatives like msgspec are out there too. There’s also a whole new generation of web frameworks like FastAPI and Starlite which use type hints at runtime to do not just input validation and serialization/deserialization but also things like dependency injection.

      Personally, I’ve seen more significant gains in productivity from those runtime usages of Python’s type hints than from any static ahead-of-time type checking, which mostly is only useful to me as documentation (and is just a simplification – I always used to explicitly list expected types in my documentation anyway, now I just have a shortcut since all the good docs tools understand type hints now).

      1. 7

        now I just have a shortcut [for documenting types]

        And a way to automatically check they are correct!

        1. 2

          Like I said, I don’t use that aspect of Python type hints.

          Partly it’s because Python is a dynamically-typed language and I use it as one. A lot of the code I write these days is “framework”-type stuff that’s intended for other people to use and to make their jobs easier, and that ends up using a fair bit of dynamism that’s hard to fully internally type hint in a way a checker will accept.

          Partly it’s because of lingering distaste for the way Python type checking was initially implemented – Python, insofar as it wants a typing discipline, wants something more on the structural end of the spectrum, but for years the available implementations were all very much nominal typing. For example, even if you went to the trouble of using things like typing.Iterable, for many years the type checker literally could only check “yup, that subclassed Iterable” rather than “yup, that actually implements the necessary interface”. It’s gotten better with support for interfaces (though officially they’re called protocols) available now, but there are still a lot of bits of the type-hinting ecosystem that have that nominal flavor to them.

          Partly it’s because another thing I do fairly often is write higher-order functions, particularly decorators, and type-hinting those is still not fun at all, even when accurately type-hinting them is possible at all.

          And partly it’s that I’ve never really bought into static typing in the first place. There are some statically-typed languages I like, but I always prefer dynamically-typed languages and am generally more productive and comfortable in them.

    2. 5

      Just to add data points to the “Runtime behavior” section, they can also be used for:

      • Dependency injection
      • Validating that a pandas / Spark dataframe conforms to a static schema (I don’t know any library that does it, but I’ve implemented it at work).
    3. 0

      typing.Any is ready.