Live data from Hacker News

Why if TYPE_CHECKING?

vickiboykis.com

41–50 of 74 posts

Re: Why if TYPE_CHECKING?

#41

I rarely butt into practices for languages that I don’t use.[1] But having a flag for “are we type-checking” is a, well, huge red flag. [1] Except some light scripting

Yeah, the article explains in depth why we are this stage with Python ...

There is always a history. Which does not imply a good reason.

Re: Why if TYPE_CHECKING?

#42

PEP 649 “Deferred Evaluation Of Annotations Using Descriptors” should result in vastly reducing the need for TYPE_CHECKING. https://peps.python.org/pep-0649/

I think in practice that increases the need for TYPE_CHECKING. If you use deferred annotations, and you don't import the types you use, type checkers and IDEs will complain, and go to definition won't work. But if you import the types outside of a TYPE_CHECKING block it's wasteful, since you don't actually need the import for your code to run. So you need TYPE_CHECKING to satisfy your linter without impacting runtime performance.

Re: Why if TYPE_CHECKING?

#43

I rarely butt into practices for languages that I don’t use.[1] But having a flag for “are we type-checking” is a, well, huge red flag. [1] Except some light scripting

doesn't Typescript have something similar?

``` import type {foo} from ... ```

Re: Why if TYPE_CHECKING?

#44

> However, Python doesn’t have the compile-time check, because it’s an interpreted language that is dynamically-typed, which means its only real place to check is at runtime Pet peeve: Python is compiled (into bytecode), so it could theoretically do checks at compile time. The "dynamically-typed" part is correct and is the real reason.

The problem for Python with type checking is that the language has essentially no compile-time constructs at all, just a bunch of assignment operators with different syntax: `def` assigns a function object to a variable when it's executed, `import` assigns a module, `class` assigns a class object. This means that everything involving names in Python is just a variable lookup (incidentally, this is why a function call must follow the declaration in Python: the variable is unbound if you haven't executed the function definition yet). The reason `Sequence` fails in the example in the article is simply that the code is trying to read an unassigned variable, no different from writing `vairable` instead of `variable` in your code.

Re: Why if TYPE_CHECKING?

#45

> However, Python doesn’t have the compile-time check Yes it does. All Python source code is parsed and compiled into bytecode. SyntaxError is raised before runtime.

It's arguable whether a SyntaxError happens as a compile-time check. It's true that it is raised before runtime. But a document that can be parsed according to the syntax definition is a necessary precondition to all checks of any static program property. Syntactic correctness in itself is not a static property of a program. A program is, by definition, syntactically correct.

Without a correct syntax there is no way to assign meaning or execute or interpret, etc.

Re: Why if TYPE_CHECKING?

#46

Small but important correction required in point 3 of the TL;DR: > Python doesn’t care about types at runtime This should say "Python doesn't care about type annotations at runtime." Python _does_ care about types at runtime - but it doesn't use type annotations to compute them. That doesn't detract from what's otherwise a really clear and helpful post. Python is living through a schizophrenic period in its evolution…

I agree with the gist of your comment.

I will add that, in my experience, having type annotations that are unreliable, cumbersome, with so many edge cases and requiring this kind of magic (e.g. "if TYPE_CHECKING", etc) which is beyond most "casual" Python users effectively means type annotations are a very hard sell for most non-hardcore team mates.

I've been in a position to try improving processes and code quality of the Python codebase, and introducing mypy and type annotations has always been a very hard sell. The team just won't accept the benefits, given the difficulties in using it. If only Python made it easier and more reliable, but the current state is a mess.

I come from the static typing world, so of course I see the benefits. But most/all of my team mates don't, and so they see this as some really odd hoops I want them to jump through, for minimal benefit (in their eyes).

Re: Why if TYPE_CHECKING?

#47
post #5
post #3

One question comes to mind: isn't cyclic dependencies something to be resolved at the root cause (remove the cycle)? It's an issue that causes various pains down the line, like type checking in this case.

The issue is that, often, without type annotations there would be no cyclic dependency (because any type matching the implicit interface would work). So by introducing type annotations (which means extra imports), you end up having to refactor quite a lot of code and the end game is a one-type-per-module-with-separate-interface-definition system of the sort encountered in, well, statically-typed languages. If you don…

Aside from type checking being a clusterfuck in python, wouldn't checking against a protocol be the right thing?

Re: Why if TYPE_CHECKING?

#48

Earlier quoted context omitted.

Yeah, the article explains in depth why we are this stage with Python ...

There is always a history. Which does not imply a good reason.

It's a work in progress, the article didn't say the current situation is ideal, nor am I.

Re: Why if TYPE_CHECKING?

#50
post #43

I rarely butt into practices for languages that I don’t use.[1] But having a flag for “are we type-checking” is a, well, huge red flag. [1] Except some light scripting

doesn't Typescript have something similar? ``` import type {foo} from ... ```

Not really. `import type` just means that this import is guaranteed to be removed when compiling to JS. TS already fully erases types during compilation, and this is just a way to guarantee that the imports of types are guaranteed to be erased as well.

E.g. for `import { SomeType } from "backend-server"`, you don't want to include your entire server code in the frontend just because you imported the response type of some JSON API. `import type` neatly solves this issue, and it even enforces that you can't import anything but types from your backend.

I also want to state that TS already removes regular `import`s that only import types. `import type` is mostly used to help bundlers. https://www.typescriptlang.org/docs/handbook/release-notes/t...

Post reply on HN