Skip to content

Report a non-bool user-defined TYPE_CHECKING constant#3846

Open
markselby9 wants to merge 1 commit into
facebook:mainfrom
markselby9:feat/3756-typechecking-constant
Open

Report a non-bool user-defined TYPE_CHECKING constant#3846
markselby9 wants to merge 1 commit into
facebook:mainfrom
markselby9:feat/3756-typechecking-constant

Conversation

@markselby9

Copy link
Copy Markdown
Contributor

Closes #3756.

Summary

A user-defined module-level TYPE_CHECKING constant is treated as True by type checkers and False at runtime, so it must be a bool (conventionally TYPE_CHECKING = False). A definition like TYPE_CHECKING: str = "" is internally consistent yet wrong, and was previously accepted silently. This mirrors ty's invalid-type-checking-constant.

When solving a module-scope name assignment to a type-checking constant (TYPE_CHECKING or TYPE_CHECKING_WITH_PYREFLY), this checks that its type is assignable to bool and otherwise emits a new invalid-type-checking-constant error. Imports of typing.TYPE_CHECKING, function locals, and class attributes that merely share the name are unaffected.

Test Plan

New tests in pyrefly/lib/test/sys_info.rs: TYPE_CHECKING: str = "" / = 1 (and TYPE_CHECKING_WITH_PYREFLY) are flagged; the canonical import + if TYPE_CHECKING:, = False, : bool = False, class attributes, and function locals are not. cargo test passes; full lib test suite is green.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Type checkers treat `TYPE_CHECKING` as `True` while the runtime sees `False`, so
a user-defined module-level `TYPE_CHECKING` (or pyrefly's
`TYPE_CHECKING_WITH_PYREFLY`) constant must be a `bool` (conventionally
`TYPE_CHECKING = False`). A definition like `TYPE_CHECKING: str = ""` is
internally consistent yet wrong, and was previously accepted silently.

When solving a module-scope name assignment to a type-checking constant, check
that its type is assignable to `bool`, otherwise emit the new
`invalid-type-checking-constant` error. The check is restricted to module scope
(tracked via a new `NameAssign::is_module_scope` flag) and skips stub files, so
imports of `typing.TYPE_CHECKING`, function locals, class attributes that merely
share the name, and `.pyi` placeholder values are unaffected.

Closes facebook#3756
@markselby9 markselby9 force-pushed the feat/3756-typechecking-constant branch from e451215 to fdfd078 Compare June 17, 2026 10:17
@github-actions github-actions Bot added size/m and removed size/m labels Jun 17, 2026
@github-actions

Copy link
Copy Markdown

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new rule - invalid assignment to TYPE_CHECKING

1 participant