Upgrade dev tooling and fix docstring style - #6893
Conversation
Greptile SummaryThis PR upgrades the locked development tooling and updates the codebase for the resulting lint and type-checking requirements.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| pyproject.toml | Updates development-tool constraints and Ruff ignores to accommodate the upgraded linting behavior. |
| uv.lock | Refreshes locked development dependencies, including Ruff, Pyright, and Typer. |
| reflex/reflex.py | Casts Typer’s generated command to Click’s command interface for registration with the root CLI. |
| reflex/compiler/compiler.py | Adds a type-only cast around the untyped libsass API without changing runtime behavior. |
| packages/reflex-base/src/reflex_base/vars/base.py | Widens field default annotations to represent the existing possibility of a None default. |
| packages/reflex-base/src/reflex_base/vars/dep_tracking.py | Restructures the IMPORT_NAME guard without changing bytecode-scanner behavior. |
| packages/reflex-base/src/reflex_base/event/processor/base_state_processor.py | Aligns the chain_updates input annotation and documentation with its existing runtime validation. |
| tests/units/reflex_cli/v2/utils.py | Introduces a shared helper for adapting Typer applications to Click commands in CLI tests. |
Reviews (2): Last reviewed commit: "Upgrade ruff, pyright, and typer; fix th..." | Re-trigger Greptile
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
All reported issues were addressed across 59 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
uv.lock: ruff 0.15.12 -> 0.16.3, pyright 1.1.408 -> 1.1.411, typer 0.25.1 -> 0.27.1. ruff 0.16.4 published inside the 7 day exclude-newer window, so 0.16.3 is the newest resolvable release. ruff 0.16 (preview rules are enabled repo-wide): - D421 property-docstring-starts-with-verb: reword 55 property docstrings from "Get the X." / "Return the X." to "The X.", per the Google style guide the repo already follows. - PT003: drop the redundant scope="function" from five pytest_asyncio.fixture calls, which 0.16 now recognizes. - ASYNC119, RUF075: ignored. Both fire on deliberate patterns -- background handlers hold `async with self` across `yield`, and the state managers skip write-back when the `with` body raises. - RUF105, RUF201: ignored. Both are stylistic; RUF105's own docs call it opinionated, and migrating 190 `noqa` comments to `ruff: ignore` would drop them for other tooling and for older ruff. RUF201 would leave the config half codes, half names, since prefix selectors have no name form. pyright 1.1.411 narrows `x is None` on an `Any` value to `Any | None`, where it previously stayed `Any`. That surfaced two dead guards, both removed: `cls is not None` in `_isinstance()` (the line above already returns for None) and `instruction.argval is not None` in the dependency-tracking scanner, where the check moves inside the branch so it stops leaking None into the sibling branches. Its bundled typeshed also types `inspect.isgenerator`/`isasyncgen` as yielding `object`, so `chain_updates()` now declares `events: Any`, matching the runtime validation it delegates to. It also caught a real gap in Field: when an annotated type has no computed default, the field is given a `None` default and its recorded `annotated_type` is widened to match, but the static FIELD_TYPE cannot follow. `Field.default`, `Field.default_factory`, and `Field.default_value()` now admit None rather than asserting a type the value need not inhabit. Also: cast untyped `sass.compile()` to str, cast `log_file_stream()`'s eagerly-opened handler stream to TextIO, and import `ImportVar`/`unionize` from the modules that define them rather than re-exporting them through `reflex_base.vars.base`. typer 0.27 vendors its own copy of click, so `typer.main.get_command()` no longer returns a nominal `click.Command`. The objects stay structurally compatible (`reflex cloud` and the hosting CLI tests pass), so the conversion is cast at its two call sites; the six test modules that duplicated the Typer-to-click preamble now share an `as_click_command()` helper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLumacyNrCZDqvyptaVxkE
08c78da to
e1544df
Compare
…-context-refactor-jv3pig One conflict, in `reflex/experimental/client_state.py`: main reworded a property docstring there (#6893, the ruff/pyright/typer upgrade) while this branch had replaced the whole file with a deprecation shim over `reflex_base.client_state`. Resolved in favor of the shim -- the implementation that docstring belonged to no longer exists here. That upgrade also brought the rule behind the reword, and this branch's own `ClientStateVar.value` tripped it. Fixed the same way main fixed theirs. Verified against the merged base with the upgraded tooling (ruff 0.16.3, pyright 1.1.411): pre-commit 7/7, 7762 unit tests, 40 vitest, 24 Playwright. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017DE4XVgDNtq2i89CMVspJ9
#6918 was branched before #6939 and #6893 landed, so merging it left main failing both pre-commit and the unit tests. - `reflex_cli.v2.auth` imported `reflex_base.utils.log` at module scope. #6939 made reflex-base optional, because it does not exist on the reflex versions the CLI advertises support for, and `reflex_cli.v2.deployments` imports auth unconditionally — so importing any hosting CLI command raised ImportError on reflex older than 0.9, failing `test_cli_imports_without_reflex_base[reflex_cli.v2.deployments]`. It now resolves `log` through `reflex_cli.utils.log`, the shim the rest of the CLI uses, which falls back to its own SUCCESS level when reflex-base is absent. `reflex_cli.v2.auth` joins that test's module list so the guard names the module directly instead of catching it only through deployments. - `tests/units/reflex_cli/v2/test_auth.py` resolved the CLI with an inline `get_command(...) if isinstance(hosting_cli, Typer)`, which types as `Group | Command`; since the typer upgrade in #6893 vendored click, that is not assignable to `click.Command`, so every `runner.invoke` call was a pyright error (22 in total). It now uses the `as_click_command` helper #6893 added for exactly this, which casts once. No behavior change: on reflex 0.9 and up `reflex_cli.utils.log.SUCCESS` is the same object the module imported before. Claude-Session: https://claude.ai/code/session_01QNTSjh5JBcVFfTx7Jvn3DT Co-authored-by: Claude <noreply@anthropic.com>
Type of change
Changes To Core Features:
Description
This PR upgrades locked dev tooling and addresses linting issues introduced by the new versions:
Tooling upgrades:
ruff0.15.12 → 0.16.2pyright1.1.408 → 1.1.411typer0.25.1 → 0.27.1Key changes:
Property docstring style (ruff D421): Updated all property docstrings from imperative form ("Get the ...", "Return the ...") to noun phrases ("The ..."). This applies across:
reflex/app.pyreflex/compiler/compiler.pyreflex/experimental/client_state.pyreflex/istate/packages/reflex-base/src/reflex_base/(vars, event, config, registry, plugins)packages/reflex-components-core/src/reflex_components_core/packages/reflex-docgen/src/reflex_docgen/packages/reflex-components-internal/src/reflex_components_internal/Type safety improvements:
cast()calls inreflex/compiler/compiler.pyandreflex/reflex.pyfor untypedlibsassandtyperAPIspackages/reflex-base/src/reflex_base/vars/base.pyfordefault_valuewith explanatory commentEventSpecimport from TYPE_CHECKING block inpackages/reflex-base/src/reflex_base/event/processor/base_state_processor.pychain_updates()parameter type fromEventSpec | list[EventSpec] | NonetoAnywith updated docstring explaining runtime validationCode quality fixes:
packages/reflex-base/src/reflex_base/utils/types.py(removed redundantcls is not Nonecheck)packages/reflex-base/src/reflex_base/vars/datetime.py(movedImportVarto correct location)packages/reflex-base/src/reflex_base/vars/dep_tracking.py(split compound condition for clarity)Test infrastructure:
tests/units/reflex_cli/v2/utils.pywithas_click_command()helper to reduce duplication across CLI testsscope="function"parameter frompytest_asyncio.fixturedecorators (already set byloop_scope)Linting configuration:
ASYNC119to ignore list (background event handlers holdasync with selfacrossyieldby design)RUF075to ignore list (state managers deliberately skip write-back whenwithbody raises)RUF105andRUF201to ignore list (preservenoqacomment readability)Test Plan
Existing unit tests pass. The changes are primarily:
All changes maintain backward compatibility and improve code quality without altering runtime behavior.
https://claude.ai/code/session_01RLumacyNrCZDqvyptaVxkE