PEP 724: Stricter Type Guards

I generally agree with @NeilGirdhar view. I think there’s very different stability expectation in runtime library vs static analysis tool. I consider it important python runtime type behavior is stable. The type checker inference behavior and what errors are shown I view with same expectation as pylint/ruff/similar tools. All static analysis tools I expect to be pinned to one version in CI. pip similarly pins to mypy==1.0.1. pip type errors are not same on latest version of mypy as current one (very similar differ by ~3 errors). Pip’s type errors are more different if you run it with different type checker.

My code changing behavior and failing is very categorically different to me then my linter/type checker adding 5 new error messages in a release. Often I’ll look at a new error decide it makes sense and correct or disagree/unsure and may type: ignore/revisit later. A few type ignores is pretty normal and while having heavy amount of ignores/cast is bad, python type checking system is not all or nothing affair for value. If most of my code passes type checking and a few places don’t that I ignore/revisit later that’s still value for me.

My experience is also other static analysis tools like pylint it is common for them to have errors change across versions. Pylint has been in usage for years prior to mypy and even know I think pylint/flake8 should have usage pretty comparable in magnitude (maybe larger/smaller) than mypy. Should those libraries also have strong stability expectations and be involved in PEPs for changes? Pylint/similar tools also commonly have IDE integration.

For packaging comparison I’d consider mypy/pyright exact errors closer to poetry/hatch’s configuration choices. Packaging libraries share common standards, but packaging libraries also have freedom to make many of their own maintenance decisions. Poetry deciding to deprecate a config feature in month vs year is their decision. This also similarly applies to pip. Pip has it’s own deprecation policy it follows separate from python deprecation policy. Mypy similarly documents itself as not following SemVar because,

Mypy doesn’t use SemVer, since most minor releases have at least minor backward incompatible changes in typeshed, at the very least. Also, many type checking features find new legitimate issues in code. These are not considered backward incompatible changes, unless the number of new errors is very high.

Quoted directly from mypy release notes. Expecting type error stability across versions directly disagrees with mypy’s maintaince policy and feels similar to saying that packaging libraries should have deprecation policy similar to python language.

Other aspect is in practice as user much of type checking error instability does not come from type checkers. It comes from library stubs/types. For many python libraries their type hints are incomplete. As they evolve it is expected behavior for type checkers to report new errors. Numpy/pandas/matplotlib data science ecosystem in particular it’s types are in a lot of flux/evolution right now. It’s normal for updating matplotlib version to impact type errors reported. And as user whether backwards compatibility is broken due to type checker vs library types changing feels very similar. Either way I need to review new type errors and decide to adjust my code/ignore them.

edit: Another aspect is mypy policy one of several for type checkers. Each type checker has separate maintainers with some overlapping goals, but also separate goals. One type checker may value stability higher than another. Another type checker may choose to update more frequently and have different deprecation policy/standard on what is reasonable change for errors. PEP does not feel suited for deciding maintainance policy of multiple libraries released separate from python language and some by fully separate owners.

4 Likes