fix(tests): fix Python 3.10-only mock.patch AttributeError in fknm fallback tests - #539
Merged
Merged
Conversation
…llback tests
roboticstoolbox/robot/ETS.py defines a class also called ETS, and
robot/__init__.py's `from ...ETS import ETS` rebinds the "ETS"
attribute on the roboticstoolbox.robot package to the class, shadowing
the submodule of the same name. Python 3.10's unittest.mock resolves
dotted-string patch targets via plain getattr (falling back to import
only on AttributeError), so patch("...ETS.ETS_fkine", ...) resolved
"ETS" to the shadowing class and failed with AttributeError; 3.11+
uses pkgutil.resolve_name and isn't fooled by the same shadowing. This
is why it only ever showed up on Python 3.10 in CI.
Not a real code bug - the actual fknm/facade fallback machinery was
always fine, only the test's patch target resolution was broken on
3.10. Fixed by looking up the real module via sys.modules directly
(the only lookup with no getattr involved) and patching against that
with patch.object() instead of a dotted string.
Rehearsed: all 41 tests in test_fknm_fallback.py pass under both
Python 3.10 and 3.13.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cross-references the fknm fallback test fix in this same branch. Python 3.10 reaches EOL October 2026 — flag this specific workaround for removal (and a general 3.10-specific-code sweep) at that point. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root-caused the Python-3.10-only
AttributeError: <class 'roboticstoolbox.robot.ETS.ETS'> does not have the attribute 'ETS_jacob0'(and jacobe/hessian0/hessiane/fkine) seen onmain's CI. Not a real code bug — the actual fknm C-extension/pure-Python fallback machinery was fine the whole time.The actual cause:
roboticstoolbox/robot/ETS.pydefines a class also calledETS, androbot/__init__.py'sfrom ...ETS import ETSrebinds the"ETS"attribute on theroboticstoolbox.robotpackage to the class, shadowing the submodule of the same name. Python 3.10'sunittest.mockresolves dotted-stringpatch()targets via plaingetattr(falling back to import only onAttributeError), sopatch("...ETS.ETS_fkine", ...)resolved"ETS"to the shadowing class and failed. Python 3.11+ rewrote this to usepkgutil.resolve_name, which isn't fooled by the same shadowing — hence it only ever showed up on 3.10.Fix: look up the real module via
sys.modules["roboticstoolbox.robot.ETS"](a plain dict keyed by the literal string, nogetattrinvolved — evenimport ... as xdoesn't avoid the shadowing, since that's defined asimport ...; x = ..., still attribute access) and usepatch.object()against that instead of a dotted string.Test plan
test_fknm_fallback.pypass under Python 3.10🤖 Generated with Claude Code