Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: use os.walk to build custom components on Python 3.10 and 3.11 - #6760

Merged
FarhanAliRaza merged 2 commits into
reflex-dev:mainfrom
anxkhn:patch-1
Jul 29, 2026
Merged

fix: use os.walk to build custom components on Python 3.10 and 3.11#6760
FarhanAliRaza merged 2 commits into
reflex-dev:mainfrom
anxkhn:patch-1

Conversation

@anxkhn

@anxkhn anxkhn commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired change?

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

What

reflex component build crashes on Python 3.10 and 3.11 with:

AttributeError: 'PosixPath' object has no attribute 'walk'

_make_pyi_files in reflex/custom_components/custom_components.py generates the
.pyi stubs for a custom component by walking its source tree. That loop used
pathlib.Path.walk(), which was only added in Python 3.12. Since the project
supports requires-python = ">=3.10,<4.0", every custom-component author on 3.10
or 3.11 hits a hard crash when building their component.

Why / root cause

Path.walk() does not exist before Python 3.12, and there is no version guard or
fallback around the call. The sibling helper _walk_files in
packages/reflex-base/src/reflex_base/utils/pyi_generator.py already avoids
Path.walk() for exactly this reason (its comment notes it can only be used once
the floor is 3.12), so this second call site had regressed relative to the rest
of the codebase.

Fix

Switch the walk to os.walk() (os is already imported in the module) and read
the directory basename via Path(dir).name for the __pycache__ skip.
PyiGenerator.scan_all normalizes its targets with Path(...), so the directory
strings that os.walk yields work unchanged. This mirrors the existing
_walk_files approach and keeps the behavior identical on 3.12+.

Tests

Added tests/units/custom_components/test_custom_components.py. It deletes
Path.walk via monkeypatch to reproduce the 3.10/3.11 environment on any
interpreter (so the guard also holds on 3.12+, where a naive test would silently
pass), then asserts _make_pyi_files recurses into component directories,
skips __pycache__, and skips top-level dotdirs, without raising.

  • Fails before the fix with the reported AttributeError; passes after.
  • uv run pytest tests/units -> 6617 passed, 18 skipped (no regressions).
  • uv run ruff check . / uv run ruff format --check clean;
    uv run pyright reflex tests -> 0 errors.

Towncrier / CHANGELOG fragment

Committed news/6714.bugfix.md (placeholder number 6714) to satisfy the
CHANGELOG CI gate (.github/workflows/changelog.yml), which requires a towncrier
fragment for any change under reflex/. Verified locally:
uv run towncrier check --config pyproject.toml --dir . --compare-with origin/main
-> exit 0.

ACTION AFTER OPENING THE PR: rename news/6714.bugfix.md to
news/<real-PR-number>.bugfix.md and amend/commit. 6714 was the plausible next
number at draft time (latest activity was #6711-#6713), but the true PR number
is only known once the PR exists. Note news/6710.bugfix.md already exists in the
tree, so if the real PR lands on a number already taken by another fragment,
pick the actual PR number regardless.

Greptile Summary

This PR restores custom-component builds on Python 3.10 and 3.11. The main changes are:

  • Delegates recursive stub generation to PyiGenerator.scan_all().
  • Excludes hidden and cache directories from top-level scan targets.
  • Adds a compatibility test that removes Path.walk().
  • Adds a changelog fragment for the fix.

Confidence Score: 5/5

This looks safe to merge.

  • The updated code removes the unsupported Path.walk() call.
  • The existing scanner handles recursive traversal for the collected targets.
  • The new test covers the reported compatibility failure and target filtering.
  • No blocking issue remains in the changed code.

Important Files Changed

Filename Overview
reflex/custom_components/custom_components.py Replaces the unsupported directory walk with one recursive scan over eligible component directories.
tests/units/custom_components/test_custom_components.py Tests the Python 3.10-compatible scan path and top-level directory filtering.
news/6760.bugfix.md Documents the custom-component build compatibility fix.

Reviews (3): Last reviewed commit: "fix: delegate custom component stub trav..." | Re-trigger Greptile

Context used:

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)

`reflex component build` generates .pyi files for the custom component by
walking its source tree in `_make_pyi_files`. That loop used
`pathlib.Path.walk()`, which was only added in Python 3.12, so on Python
3.10 and 3.11 (both supported by `requires-python = ">=3.10,<4.0"`) the
build crashed with `AttributeError: 'PosixPath' object has no attribute
'walk'`.

Switch the walk to `os.walk()`, mirroring the existing `_walk_files`
helper in reflex-base whose comment already notes `Path.walk()` cannot be
used until the floor is 3.12. `PyiGenerator.scan_all` accepts str or Path
targets, so the yielded directory strings work unchanged.

Signed-off-by: Anas Khan <[email protected]>
@anxkhn
anxkhn requested a review from a team as a code owner July 14, 2026 07:47
@greptile-apps

greptile-apps Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR restores custom-component builds on Python 3.10 and 3.11. The main changes are:

  • Replaces Path.walk() with os.walk() during stub generation.
  • Adds tests for recursive scanning and excluded directories.
  • Adds a changelog fragment for the fix.

Confidence Score: 5/5

This looks safe to merge.

  • os.walk() avoids the unsupported Python API.
  • PyiGenerator.scan_all converts string targets to Path objects.
  • The added test exercises the affected build helper.
  • No blocking issues were found in the changed code.

Important Files Changed

Filename Overview
reflex/custom_components/custom_components.py Uses os.walk() while preserving the target handling expected by PyiGenerator.scan_all.
tests/units/custom_components/test_custom_components.py Tests compatibility without Path.walk, recursive scanning, and directory exclusions.
tests/units/custom_components/init.py Initializes the new custom-components unit-test package.
news/6714.bugfix.md Documents the supported-Python build fix.

Reviews (2): Last reviewed commit: "fix: use os.walk to build custom compone..." | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jul 14, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing anxkhn:patch-1 (002613c) with main (9936fcf)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Alek99 Alek99 closed this Jul 15, 2026
@Alek99 Alek99 reopened this Jul 15, 2026
@FarhanAliRaza FarhanAliRaza added the In Review Actively being reviewed by reflex team member label Jul 29, 2026
@FarhanAliRaza
FarhanAliRaza merged commit 015f28f into reflex-dev:main Jul 29, 2026
107 checks passed
benedikt-bartscher pushed a commit to benedikt-bartscher/reflex that referenced this pull request Jul 30, 2026
…eflex-dev#6760)

* fix: use os.walk to build custom components on Python 3.10 and 3.11

`reflex component build` generates .pyi files for the custom component by
walking its source tree in `_make_pyi_files`. That loop used
`pathlib.Path.walk()`, which was only added in Python 3.12, so on Python
3.10 and 3.11 (both supported by `requires-python = ">=3.10,<4.0"`) the
build crashed with `AttributeError: 'PosixPath' object has no attribute
'walk'`.

Switch the walk to `os.walk()`, mirroring the existing `_walk_files`
helper in reflex-base whose comment already notes `Path.walk()` cannot be
used until the floor is 3.12. `PyiGenerator.scan_all` accepts str or Path
targets, so the yielded directory strings work unchanged.

Signed-off-by: Anas Khan <[email protected]>

* fix: delegate custom component stub traversal

---------

Signed-off-by: Anas Khan <[email protected]>
Co-authored-by: Farhan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

In Review Actively being reviewed by reflex team member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants