Add testing support for Pyodide and MicroPython environments#17
Add testing support for Pyodide and MicroPython environments#17
Conversation
- Update tox and github actions workflow config to support `micropython` and `pytest-pyodide`. - Refactor core classes to replace reliance on missing standard libraries (`inspect`, `abc`, `collections.abc`, `itertools`, `copy`, `numbers`, `logging`) with robust `try...except ImportError` blocks to ensure execution under MicroPython or PyScript. - Add minimal testing suite tailored for MicroPython core features `test_micropython_core.py`. - Patch typing errors induced by fallback MicroPython abstractions using conditional `type: ignore` comments. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
- Removed unused `docs/tooling_evaluation.md` path from mdformat check in github actions. - Fixed `ruff` warning for unused `typing.Any` import. - Modified fallback types in MicroPython logic to properly define `TypeVar` signatures so they mirror standard library variants closely, preventing mypy "All conditional function variants must have identical signatures" errors. - Restored `fix_type_hints.py` which was inadvertently deleted. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
- Removed the nonexistent `docs/tooling_evaluation.md` path from the `mdformat` check command in the GitHub Actions workflow, which was causing the `lint` CI job to fail. - Fixed a `ruff` warning for an unused `typing.Any` import in `src/closure_collector/util.py`. - Ignored pyupgrade rule `UP047` in `flock/core.py` and `closure_collector/core.py` for generic functions like `abstractmethod` and `copy` since MicroPython does not natively support PEP 695 generic function syntax (`def abstractmethod[_FuncT](...)`). - Adjusted `collections.abc.Callable` import handling to pass `ruff` `UP035` and appropriately ignore `E402` rules for dependent library imports following fallback standard library feature detection. - Formatted affected files using `ruff format`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
|
|
||
| @abstractmethod | ||
| def shear(self, record_errors=False): | ||
| """ |
There was a problem hiding this comment.
Why did you remove this docstring?
There was a problem hiding this comment.
Sorry about that! It was accidentally removed during the refactoring process for the MicroPython feature detection fallbacks. I've restored the docstrings in both closure_collector/core.py and flock/core.py to correctly preserve the documentation for check, shear, __call__, __dir__, and clear_cache.
src/closure_collector/core.py
Outdated
|
|
||
| def make_callable(self, value): | ||
| if callable(value) and len(inspect.signature(value).parameters) == 0: | ||
| if callable(value): |
There was a problem hiding this comment.
@jules extract this logic into a function. Define the function differently depending on whether inspect is available
- Restored the docstrings for `check`, `shear`, `__call__`, `__dir__`, and `clear_cache` methods in `src/closure_collector/core.py:CCBase`. - Restored the docstrings for `check`, `shear`, and `__call__` methods in `src/flock/core.py:FlockBase`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
Added explanatory comments to all `except ImportError:` blocks that are designed to handle missing standard library modules in MicroPython or PyScript environments. This clarifies when and why these dummy replacements are injected. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
src/closure_collector/core.py
Outdated
| for closure in value.__closure__: | ||
| if isinstance(closure.cell_contents, DynamicClosureCollector): | ||
| closure.cell_contents.peers.add(self) | ||
| try: |
There was a problem hiding this comment.
Is this handling for different python interpreters? If so split it out into a function.
There was a problem hiding this comment.
Yes! This logic is required because MicroPython's function objects lack an __code__ attribute natively. I have extracted this logic into an is_zero_arg function within closure_collector/util.py (which is defined conditionally based on the availability of inspect). This cleans up make_callable and removes the need for repeated exception handling inline.
src/closure_collector/util.py
Outdated
| FunctionType = type(lambda: None) # type: ignore[assignment,misc] | ||
|
|
||
|
|
||
| if inspect is not None: |
There was a problem hiding this comment.
Does this need a separate if? Could it be done in the try/except?
There was a problem hiding this comment.
@jules Does this need a separate if? Could it be done in the try/except?
There was a problem hiding this comment.
Excellent point. I have refactored this block directly into a single try: ... import inspect ... except ImportError: structure, placing both implementations of the functions tightly within their respective branches. This is much cleaner, thank you for the suggestion!
- Extracted the environment-specific zero-argument detection logic from `make_callable` into a new `is_zero_arg` function in `closure_collector/util.py`, simplifying `make_callable` across both `FlockDict` and `ClosureCollector`. - Extracted the environment-specific cell-content retrieval/assignment from `make_callable`, `is_rule`, and `rebind` into `get_cell_contents` and `set_cell_contents` in `closure_collector/util.py` for cleaner code and encapsulated standard library fallbacks. - Corrected mypy typing for `FlockBase` and `CCBase` class fallback definitions in `closure_collector/core.py` and `flock/core.py`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
Addresses code review feedback by directly tying the declaration of interpreter-specific helper functions (`is_zero_arg`, `get_cell_contents`, `set_cell_contents`) into the single `try...import inspect` feature detection block inside `closure_collector/util.py` instead of importing it separately and then branching via `if inspect is not None`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
| from collections.abc import Iterable, Mapping | ||
| from itertools import chain | ||
| from pprint import pformat | ||
| try: |
There was a problem hiding this comment.
@jules are there cases where only some of these are available or can we combine all of these into one try/except?
… modules - Moved all standard library feature detection (`inspect`, `collections`, `types`, etc.) and fallback dummy/shim objects from `src/closure_collector/core.py`, `src/closure_collector/util.py`, `src/flock/core.py`, and `src/flock/util.py` into new internal compatibility modules: `src/closure_collector/compat.py` and `src/flock/compat.py`. - Replaced monolithic `try/except` chains with cleanly separated blocks so partial standard library subsets (such as a device having `collections` but lacking `inspect`) appropriately leverage what is available before falling back. - Suppressed MyPy `[misc]` generic constraints via configuration locally to better support the stripped-down PEP 695 workarounds for MicroPython in `compat.py`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
Addresses GitHub Actions CI failure where `ruff format --check src test` failed due to unformatted modifications inside `src/flock/compat.py`. Co-authored-by: Ciemaar <1388496+Ciemaar@users.noreply.github.com>
This PR adds testing support for Pyodide and MicroPython runtime environments by extending the tox configuration and the GitHub Actions CI workflow to install and run tests using
pytest-pyodideandmicropython.To make the library compatible with these lightweight Python runtimes, it refactors the
closure_collectorandflockcore components. It adds robust exception fallback patterns for importing standard libraries that are absent in MicroPython (such asinspect,abc,collections.abc,itertools,copy,types,numbers, andlogging). For example, sinceinspect.signatureis unavailable,make_callablenow gracefully falls back to inspecting__code__.co_argcount, and ultimately assumes a zero-argument callable if introspection fails (which is the designed use case).A tailored MicroPython test runner script and specialized test suite (
test_micropython_core.py) have also been implemented, providing test coverage for core features under MicroPython. Mypy type definitions have been adjusted to tolerate the dummy fallback objects when standard library typing is unavailable.PR created automatically by Jules for task 7835868847287141344 started by @Ciemaar