LWN: Comments on "Wrangling the typing PEPs" https://lwn.net/Articles/878675/ This is a special feed containing comments posted to the individual LWN article titled "Wrangling the typing PEPs". en-us Thu, 16 Oct 2025 09:34:28 +0000 Thu, 16 Oct 2025 09:34:28 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Missing the point of loose languages https://lwn.net/Articles/879860/ https://lwn.net/Articles/879860/ smurf <div class="FormattedComment"> IMHO the best thing about explicit typing is documentation. I can see what a variable/parameter is supposed to be without checking external and possibly-out-of-date docs (including broken comments right above the function in question …).<br> <p> A decent set of test cases is great for checking that the expected cases work as expected. The problem is that some [ft]ools insist on tests for each and every unexpected case, even if logically impossible to reach, while the real problems (i.e. those conditions you didn&#x27;t even think of being remotely possible when you wrote the code) slip under the radar.<br> </div> Mon, 27 Dec 2021 09:59:31 +0000 Missing the point of loose languages https://lwn.net/Articles/879857/ https://lwn.net/Articles/879857/ NAR <div class="FormattedComment"> Erlang is one language where the type system was added later. In my experience it&#x27;s most useful for documentation - now there&#x27;s a standard way to specify the type of the arguments in an API function. There&#x27;s a tool (dialyzer) that checks for type errors: I worked on a project where the type annotations were added on later, about 95% of the errors it found were in dead code (so not covered by unit tests - one such example was a branch that only executed if the current date was before 2000, and we were adding the type specs in 2010). If there is a decent test coverage, there&#x27;s little (but not zero!) value the type system can add.<br> </div> Mon, 27 Dec 2021 08:26:01 +0000 Missing the point of loose languages https://lwn.net/Articles/879388/ https://lwn.net/Articles/879388/ tbelaire <div class="FormattedComment"> I hear you, but then I had to deal with upgrading some email lib from 2 to 3 which was mixing bytes and strings and it was so much easier to do in stages by first annotating the functions with types, and fixing mistakes, then doing the py3 upgrade.<br> <p> Until I started annotating with types, I was dealing with &quot;Oh, that&#x27;s a bytes regex, doesn&#x27;t work on str&quot;, on line xxx. And other errors, where as being careful and making sure the encoding/decoding happened exactly once, and using the types to check that across all the functions and not playing wack-a-mole with errors is so much nicer.<br> <p> <p> And when I&#x27;m working with pandas, I do want to know if I have a DF with only one column vs a Series, as the operations are different, but it&#x27;s just `df[&#x27;col&#x27;] ` vs `df[[&#x27;col&#x27;]]` to get each one. (I think). So I already need to check and keep the types separate, why not ask the compiler for help?<br> </div> Tue, 21 Dec 2021 18:55:14 +0000 Missing the point of loose languages https://lwn.net/Articles/879137/ https://lwn.net/Articles/879137/ smurf <div class="FormattedComment"> Haskell is one of these &quot;you need to wrap your head around these new concepts, otherwise you&#x27;ll feel like bashing your noggin against a brick wall is the saner option when you actually start coding in it&quot; languages.<br> <p> That takes more up-front time and effort than most people want to spend. Plus everybody else in your team needs to do the same thing.<br> <p> I was looking into using Elm (a Haskell-ish language for client-side web programming; transpiles to Javascript of course) recently. Great idea, but where do I get the month that&#x27;s not in the calendar from, so that I can be up to speed on it?<br> </div> Sun, 19 Dec 2021 10:15:56 +0000 Wrangling the typing PEPs https://lwn.net/Articles/879079/ https://lwn.net/Articles/879079/ smitty_one_each <div class="FormattedComment"> <font class="QuotedText">&gt; Those are valuable resources, obviously, but they do tend to reinforce the message that the future of Python is typed.</font><br> <p> I don&#x27;t see a two-tier ecosystem consisting of:<br> 1. Traditional python for scripting/exploratory work<br> 2. Typed libraries for medium-large projects<br> ...as a bad thing.<br> <p> As with the 2-to-3 transition, there is just a turbulent crossover period. Welcome to reality.<br> <p> Maybe it&#x27;s a big enough deal to call it python 4 when codified and formalized.<br> </div> Sat, 18 Dec 2021 00:46:04 +0000 Missing the point of loose languages https://lwn.net/Articles/879056/ https://lwn.net/Articles/879056/ Wol <div class="FormattedComment"> <font class="QuotedText">&gt; I highly welcome a generic type annotation system that codes like Cython make use of. But imposing a mandatory rigid typing system is the wrong approach. If strong static typing is needed, there is a big choice of other languages out there (go, rust, C++, Java, Haskell, ....ML).</font><br> <p> The problem with my favourite language is everything is of type string (or variant). The advantage of this same language is that everything is of type variant. It would be lovely if I could just restrict things by having the default as variant, but options like &quot;integer&quot;, &quot;number&quot;, and stuff like that available ...<br> <p> (Said favourite language being DataBASIC, btw)<br> <p> Cheers,<br> Wol<br> </div> Fri, 17 Dec 2021 19:11:54 +0000 Missing the point of loose languages https://lwn.net/Articles/879047/ https://lwn.net/Articles/879047/ mpr22 <div class="FormattedComment"> <font class="QuotedText">&gt; Why not use Haskell right away?</font><br> <p> My understanding is that a lot of people who love static typing etc. still bounce off of Haskell.<br> <p> (Partly because a lot of the literature around Haskell has a reputation for using terminology that even many CS graduates are unfamiliar with.)<br> </div> Fri, 17 Dec 2021 16:57:20 +0000 Missing the point of loose languages https://lwn.net/Articles/879040/ https://lwn.net/Articles/879040/ tnoo <div class="FormattedComment"> Exactly my feeling! <br> <p> Python was (still mostly is) so clean and at the same time powerful enough for all my use cases (data analysis, glue language for numerical codes). And just perfect for teaching introductory classes for scientists.<br> <p> I highly welcome a generic type annotation system that codes like Cython make use of. But imposing a mandatory rigid typing system is the wrong approach. If strong static typing is needed, there is a big choice of other languages out there (go, rust, C++, Java, Haskell, ....ML). <br> <p> But of course, this also comes with a high cost. Besides the need for compilation, for C++ we have the Design Patterns (Gang of Four) with Facade, Adapter, Decorator patterns etc that are not necessary in Python because of Duck-Typing. <br> <p> For me Python is getting less and less attractive if more line noise is added, and simple code is becoming unreadable. From a comment above<br> <p> def foo(a: object, b: type[T]) -&gt; TypeGuard[T]:<br> <p> does not look and feel like Python anymore. Why not use Haskell right away?<br> </div> Fri, 17 Dec 2021 15:56:56 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878988/ https://lwn.net/Articles/878988/ mathstuf <div class="FormattedComment"> <font class="QuotedText">&gt; Perhaps this is one of the few times PHP has something to teach the wider community. </font><br> <p> There&#x27;s always been things to learn. This is just one of the times where it&#x27;s not following a &quot;eh…maybe let&#x27;s not do it *that* way&quot; pattern. ;)<br> </div> Fri, 17 Dec 2021 12:26:20 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878981/ https://lwn.net/Articles/878981/ atnot <div class="FormattedComment"> Yes, that is my point.<br> </div> Fri, 17 Dec 2021 10:28:17 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878965/ https://lwn.net/Articles/878965/ LtWorf <div class="FormattedComment"> It&#x27;s not like mypy ever had any regard for consistency.<br> <p> For example running the same mypy version with the same identical flags, but using different python versions will give different errors in a way that it might be impossible to use both on the same codebase.<br> <p> Also in general every new version of mypy will require code changes to pass on a codebase. Especially if you enable the error on the # type: ignore comments, so as it gets better and requires less and less of them they need to be removed.<br> </div> Fri, 17 Dec 2021 07:05:33 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878964/ https://lwn.net/Articles/878964/ NYKevin <div class="FormattedComment"> Runtime type checkers will probably be perfectly happy with that, but I am not aware of a single static type checker that actually evals the annotations in a full Python environment for you.<br> </div> Fri, 17 Dec 2021 06:39:08 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878962/ https://lwn.net/Articles/878962/ NYKevin <div class="FormattedComment"> You can&#x27;t just make up new dunder methods. Standard dunder methods are recognized by the Python compiler and (ultimately) converted into struct fields at the C level. Strictly speaking, if a dunder method is not recognized, it will be left alone, but a future version of Python might decide to use that name, and if it does, you get no backcompat guarantees (see <a href="https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers">https://docs.python.org/3/reference/lexical_analysis.html...</a>). You don&#x27;t even get a DeprecationWarning, either, it will just silently break one day.<br> <p> However, classes are first class in Python, so you can absolutely do this already without using dunder names. Just write a.into(MyType), and it will pass the class object. Now the only hard part is convincing everyone that .into() should be spelled like that (more common is .as_foo() where the type is hard-coded into the method name).<br> </div> Fri, 17 Dec 2021 06:34:30 +0000 Missing the point of loose languages https://lwn.net/Articles/878956/ https://lwn.net/Articles/878956/ rdeforest <div class="FormattedComment"> I&#x27;ve only read the intro paragraph of the article and the first comment, so this may be redundant or already refuted elsewhere, BUT!<br> <p> Languages like Python, PHP and JavaScript gained enormous popularity BECAUSE the users didn&#x27;t have to deal with types. The barriers to entry were low and the things type information help with didn&#x27;t matter enough. Adding type information to these languages after they&#x27;ve become popular misses the point of how they got popular in the first place. I would even posit that it objectively worsens them. The eventual of triumph of TypeScript over JavaScript would refute my claim, if it happens.<br> <p> I would suggest as an alternative to extending existing dynamic languages, that those seeking these features instead choose languages built around them. But those languages (Haskel, I&#x27;m looking at you) don&#x27;t have the enormous communities and the network effects they bring...<br> <p> In other words, Richard P Gabriel was right all along: &quot;Worse Is Better&quot;.<br> </div> Fri, 17 Dec 2021 01:38:36 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878954/ https://lwn.net/Articles/878954/ jkingweb <div class="FormattedComment"> <font class="QuotedText">&gt; It seems to me that dynamically and/or weakly typed languages like Python are struggling a bit in adding optional typing in general.</font><br> <p> The introduction of a type system in PHP has been a great success. It has been gradual, optional, and backwards compatible across heterogeneous programs—and essentially universally adopted. <br> <p> Perhaps this is one of the few times PHP has something to teach the wider community. <br> </div> Fri, 17 Dec 2021 01:12:34 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878947/ https://lwn.net/Articles/878947/ atnot <div class="FormattedComment"> It&#x27;s my fault for not explaining this better, but Rusts&#x27;s Into/From system is quite a bit more capable than that. In a python constructors, the set of things that can be converted is defined only in the constructor. With Into/From, it can be implemented on any type, even foreign ones.<br> <p> So for example, you could have Into&lt;String&gt; implemented for Paths, or From&lt;Path&gt; implemented for Strings, it works exactly the same either way. There is no common way to do this in python right now. Although it could probably be built from two existing features:<br> <p> - The constructor/dunder pair I mentioned previously. Functions like float() will attempt to convert the object into bytes using predefined conversions. If that fails it will ask the object to convert itself using __float__.<br> - Operators, where a + b will attempt to call a.__add__(b) and if that fails b.__radd__(a). Similarly, it could call a.__into__(MyType) and MyType.__from__(a) or even MyType(a) as you mentioned.<br> </div> Thu, 16 Dec 2021 23:23:56 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878946/ https://lwn.net/Articles/878946/ NYKevin <div class="FormattedComment"> List absolutely does not mean &quot;object with list protocol.&quot; That&#x27;s spelled collections.abc.MutableSequence (see this table: <a href="https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes">https://docs.python.org/3/library/collections.abc.html#co...</a>). As of Python 3.9, typing.List is just a deprecated alias for list. Previously, it was &quot;a list that can have type parameters,&quot; but now that functionality has been moved into the builtin.<br> <p> (Strictly speaking, it is possible to create an object with the mutable sequence protocol which is not a subclass of MutableSequence, but this is significantly more work and there&#x27;s no obvious benefit to doing so, so I would like to believe that nobody would do it.)<br> </div> Thu, 16 Dec 2021 22:48:32 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878934/ https://lwn.net/Articles/878934/ NYKevin <p> In general, type[T] is only supposed to match reified types (types that you can pass as the second argument to isinstance()), which neither of those examples is. The intention is that it represents a runtime type object - but at runtime, list[int] is mostly useless because it does not actually check its constructor arguments (i.e. list[int](['x', 'y', 'z']) is perfectly happy to give you a list of strings), so you might as well just use list instead, or so the thinking went when they were designing this feature. <p> However, some people want to use parameterized types as a convenient way of representing the schema of some structured data which you e.g. want to unserialize. This is not what type[T] was designed to do, but that does not make it an invalid use case for type[T]. Unfortunately, allowing such parameterized types to inhabit type[T] now would create backcompat issues, because mypy would need to flag this function as possibly unsafe: <pre> T = TypeVar('T', bound=SomeGenericClass) def foo(a: object, b: type[T]) -&gt; TypeGuard[T]: if not isinstance(a, b): return False # Do additional checks here... </pre> <p> (Specifically, if b is a parameterized type object, this throws a TypeError at runtime - but mypy considers it OK because type[T] is not allowed to match such types.) Thu, 16 Dec 2021 22:35:56 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878926/ https://lwn.net/Articles/878926/ NYKevin <div class="FormattedComment"> This is because Python doesn&#x27;t have a standard &quot;into&quot; method. Instead, the canonical way to convert type X into type Y is to call Y&#x27;s constructor on an instance of X (just like in C++, except that Python never implicitly calls a constructor when the types don&#x27;t match - so it&#x27;s like C++ if all single-argument constructors were explicit). But in Python, the values which are acceptable to Y&#x27;s constructor are annotated on Y&#x27;s constructor (or more commonly, on its __init__ method, which is technically not a constructor, but whatever), not on X, so there&#x27;s simply no obvious way to statically annotate &quot;anything that Y can accept as a constructor argument.&quot; Perhaps there should be - but ideally, we would generalize this to support all functions, not just __init__, so that you could instead write &quot;anything that is acceptable to the foo function as an argument,&quot; with Y.__init__ being one possible value of &quot;the foo function.&quot;<br> <p> If you are writing Y yourself, you can fix this by using whatever annotation you used on Y&#x27;s constructor, and you can even set up a convenient TypeAlias for it if desired.<br> </div> Thu, 16 Dec 2021 21:44:10 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878920/ https://lwn.net/Articles/878920/ pj <div class="FormattedComment"> <font class="QuotedText">&gt; I&#x27;ve seen libraries that enforce filenames to be &quot;str&quot; with a check, just to then call the python open function which would have gladly accepted pathlib.Path and bytes as well.</font><br> <p> I feel like the correct way to do this would be to explicitly infer the type. Which meand we need some way to refer to &#x27;the type that open()&#x27; takes as its first argument, but that&#x27;s somewhat complicated to obtain:<br> <p> ```<br> import inspect<br> <p> def mywrapper(filename: list(inspect.signature(open).parameters.values())[0].annotation):<br> ...<br> ```<br> <p> ...doesn&#x27;t exactly flow from the fingertips. And I&#x27;m not sure if the if the value to the annotation is valid as an annotation itself. *sigh* IWBNI there was like an `infer(open, 1)`. <br> <p> <p> </div> Thu, 16 Dec 2021 21:11:18 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878882/ https://lwn.net/Articles/878882/ atnot <div class="FormattedComment"> It would be really nice if python could figure out something comparable to e.g. Rust&#x27;s Into/From there.<br> <p> Basically the way it works is that you can declare a parameter to be say, Into&lt;MyType&gt;. This means you may pass any value on which .into::&lt;MyType&gt;() can be called to convert it. From&lt;MyType&gt; being the reverse.<br> <p> Python kind of already has this by convention for a few types like __bytes__, __bool__, __iter__, __str__ (which is also overloaded for other uses), __int__, __float__, etc. but it&#x27;s not really widely used or extensibile.<br> </div> Thu, 16 Dec 2021 18:20:16 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878884/ https://lwn.net/Articles/878884/ anselm <blockquote><em>Does Python have the possibility to specify a Procotol as "type" instead of nailing down the type to some specific ones?</em></blockquote> <p> Yes, this is explained in <a href="https://www.python.org/dev/peps/pep-0544/">PEP-544</a>, which deals with “duck typing”. </p> <blockquote><em>There's List, which means object with list procotol, as far as I understand it. But is there something similar for paths?</em></blockquote> <p> The <tt>os</tt> module implements <tt>PathLike</tt> as an “abstract base class” for classes that implement path-like behaviour (such as <tt>pathlib.Path</tt>). Basically this means that such classes support the <tt>__fspath__()</tt> method, which is supposed to return a representation of the object that is a <tt>str</tt> suitable to use as a file system path. If you wanted to say that a function accepts a parameter that is either a <tt>str</tt> to begin with, or a <tt>PathLike</tt> object, you could define it as <pre> from os import fspath, PathLike def do_something_with_path(path: str | PathLike) -&gt; …: … f = open(fspath(path)) … </pre> (where <tt>os.fspath(s)</tt> will return <tt>s</tt> outright if <tt>s</tt> is of type <tt>str</tt>, or else <tt>s.__fspath__()</tt>). Of course you could also define a type variable like <pre> PathOrStr = TypeVar('PathOrStr', str, PathLike) </pre> and then simply use this as <pre> def do_something_with_path(path: PathOrStr) -&gt; ...: … </pre> <blockquote><em>Can the developer create new such types for his own protocols?</em></blockquote> <p> Absolutely. See <a href="https://docs.python.org/3/library/typing.html#typing.Protocol">here</a>. </p> Thu, 16 Dec 2021 17:50:53 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878879/ https://lwn.net/Articles/878879/ smurf <div class="FormattedComment"> <font class="QuotedText">&gt; This is a misuse of the type system.</font><br> <p> It is just plain stupid. Why do some people write useless code like that?<br> </div> Thu, 16 Dec 2021 16:20:36 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878855/ https://lwn.net/Articles/878855/ gdiscry <p>A correct annotation would use something like <code>Union[str, bytes, <a href="https://docs.python.org/3/library/os.html#os.PathLike">os.PathLike</a>[str], os.PathLike[bytes]]</code> or <code>Union[<a href="https://docs.python.org/3/library/typing.html#typing.AnyStr">AnyStr</a>, os.PathLike[AnyStr]]</code>.</p> <p>Like mentioned in the article, the typeshed project is a good resource if one needs some inspiration, in this case <a href="https://github.com/python/typeshed/blob/d84a03829f52c1dd972440db56a84a7a75e33cca/stdlib/os/__init__.pyi#L405"><code>os.fspath()</code></a> or similar and the <a href="https://github.com/python/typeshed/blob/d84a03829f52c1dd972440db56a84a7a75e33cca/stdlib/_typeshed/__init__.pyi#L91">type aliases defined by typeshed</a> could be useful.</p> Thu, 16 Dec 2021 15:48:02 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878851/ https://lwn.net/Articles/878851/ mb <div class="FormattedComment"> How do I spell out a correct type annotation for a filesystem path?<br> <p> Does Python have the possibility to specify a Procotol as &quot;type&quot; instead of nailing down the type to some specific ones? Similar to Traits in Rust. There&#x27;s List, which means object with list procotol, as far as I understand it. But is there something similar for paths? Can the developer create new such types for his own protocols?<br> </div> Thu, 16 Dec 2021 15:13:42 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878821/ https://lwn.net/Articles/878821/ ballombe <div class="FormattedComment"> <font class="QuotedText">&gt; I&#x27;ve seen libraries that enforce filenames to be &quot;str&quot; with a check, just to then call the python open function which would have gladly accepted pathlib.Path and bytes as well </font><br> <p> This is a misuse of the type system.<br> </div> Thu, 16 Dec 2021 14:12:45 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878820/ https://lwn.net/Articles/878820/ LtWorf <div class="FormattedComment"> Maybe interesting to the readers but a function like<br> <p> def f(i: Type[T]) -&gt; T: ...<br> <p> that basically is a factory, returning an instance of the passed type, will not work in all cases with mypy.<br> <p> A List[int] will work fine, but a Tuple[int] won&#x27;t work. In general from that definition mypy will understand &quot;Any&quot; or error out.<br> <p> <a href="https://github.com/python/mypy/issues/9003">https://github.com/python/mypy/issues/9003</a><br> </div> Thu, 16 Dec 2021 09:58:26 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878817/ https://lwn.net/Articles/878817/ LtWorf <div class="FormattedComment"> Well people knew that PEP 563 was going to break my library (I had complained), but didn&#x27;t seem to care until they got complaints from someone making a very similar library (obviously a worse one, but with a million more users) complained.<br> <p> So I&#x27;m a bit surprised now about the interest for those not using annotation in the approved way.<br> <p> Anyway for library writers… yes I prefer if libraries have (meaningful) annotations… but I miss a bit the duck typing days.<br> <p> I&#x27;ve seen libraries that enforce filenames to be &quot;str&quot; with a check, just to then call the python open function which would have gladly accepted pathlib.Path and bytes as well.<br> <p> So hints are nice, but unnecessarily restricting to one type just means the users have to do unneeded type conversions just to make the linters (or the runtime checks) happy.<br> </div> Thu, 16 Dec 2021 09:50:16 +0000 Wrangling the typing PEPs https://lwn.net/Articles/878816/ https://lwn.net/Articles/878816/ taladar <div class="FormattedComment"> It seems to me that dynamically and/or weakly typed languages like Python are struggling a bit in adding optional typing in general.<br> <p> There are probably a few reasons for this, some technical and some social.<br> <p> On the one hand it is just hard to add a type system later to an API designed without one since a lot of the APIs in dynamic languages are a bit &#x27;sloppy&#x27; from a typed perspective, often accepting different types for the same parameter and/or returning different types (and null/nil like values). This makes it hard to make a high quality typed API the way it would look like in a language that had static types from the start.<br> <p> Obviously having types on just some functions and not others does not exactly help either.<br> <p> The fact that optional typing annotations are not enforced in all situations in some of the optional typing languages also means defensive programming code and unit tests meant to check the same thing as the type system would in a statically typed language can not be removed and add a dual maintenance burden.<br> <p> The social issue I see is that a lot of the people who really know how static typing works and who care about a good static type system have moved on to languages that suit their tastes better, leaving a high percentage of people who do not like static type systems to please for the dynamically typed language community to deal with.<br> <p> At the same time the languages lose relevance as it becomes more and more clear that the whole &#x27;sufficiently disciplined programmer&#x27; does not exist, especially not whole teams of them or even a whole language ecosystem or at least all the people working on your project and all of your project&#x27;s dependencies.<br> <p> Replacing type checks with unit tests also means a lot more work for inferior results (e.g. how do you test that no combination of parameters ever yields a different return type).<br> <p> This means the existing code bases have a higher maintenance burden but most likely fewer maintainers highly motivated to adjust the API to be a great typed API.<br> </div> Thu, 16 Dec 2021 09:16:23 +0000 Greenspun's tenth rule https://lwn.net/Articles/878806/ https://lwn.net/Articles/878806/ ejr <div class="FormattedComment"> I would be interested in a layout of benefits and drawbacks when compared to other optional type annotation systems like Common Lisp. Also with heavily-inferenced typing systems.<br> </div> Thu, 16 Dec 2021 01:29:46 +0000