Skip to content

Keep PathAccessError printable for Scope/S paths (#249)#298

Merged
mahmoud merged 1 commit into
mahmoud:masterfrom
gaoflow:fix-249-pae-scope-printable
Jun 29, 2026
Merged

Keep PathAccessError printable for Scope/S paths (#249)#298
mahmoud merged 1 commit into
mahmoud:masterfrom
gaoflow:fix-249-pae-scope-printable

Conversation

@gaoflow

@gaoflow gaoflow commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #249.

A PathAccessError raised from a Scope/S access cannot stringify itself — str(exc) renders as <exception str() failed>:

import glom
glom.glom({}, glom.S['X'], scope={'x': 'y'})
glom.core.PathAccessError: <exception str() failed>

Cause

PathAccessError.get_message() does Path(self.path).values()[self.part_idx]. When the access originates from a scope, self.path is not a plain T-based path, and Path(...) raises ValueError: path segment must be path from T, not S. Because get_message() is called from GlomError.__str__, that exception escapes and the error can no longer be printed (and get_message() itself crashes).

Fix

Guard the Path(self.path) lookup and fall back to self.path when it can't be turned into a plain path, so the message stays readable instead of raising:

glom.core.PathAccessError: could not access T['X'], part 0 of T['X'], got error: KeyError('X')

An exception should always be able to produce a string and never crash its own formatter, so this restores the documented "readable error message" contract for the S/scope case without changing the normal T-path output.

Tests

Added test_pae_scope_printable in glom/test/test_error.py, asserting the scope-originated PathAccessError is printable (no <exception str() failed>) and that get_message() returns a string. It is RED without the fix and GREEN with it. The error and scope suites pass (test_error.py, test_scope_vars.py: 27 passed); the only failing tests in the repo are pre-existing test_cli.py environment failures unrelated to this change.

Disclosure: I prepared this fix with AI assistance under my direction; I reviewed and verified the change and the test myself.

@mahmoud mahmoud force-pushed the fix-249-pae-scope-printable branch from 76c2d0b to da92fe0 Compare June 28, 2026 22:48
@codecov

codecov Bot commented Jun 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.22%. Comparing base (64141ba) to head (7583a20).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #298      +/-   ##
==========================================
- Coverage   98.25%   98.22%   -0.04%     
==========================================
  Files          27       27              
  Lines        4364     4384      +20     
  Branches      612      612              
==========================================
+ Hits         4288     4306      +18     
- Misses         52       53       +1     
- Partials       24       25       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mahmoud mahmoud force-pushed the fix-249-pae-scope-printable branch 2 times, most recently from 539abb1 to 8c8f395 Compare June 29, 2026 01:17
@mahmoud

mahmoud commented Jun 29, 2026

Copy link
Copy Markdown
Owner

This is a really good catch. I think I found a slightly simpler approach since all .path attribute accesses are actually Path instances. Wish I had typing to enforce this, but in the meantime I put a fallback in there. Pushed the adapted fix to the branch here and looks good now. Thanks a bunch!

@mahmoud mahmoud force-pushed the fix-249-pae-scope-printable branch from 8c8f395 to ec70055 Compare June 29, 2026 03:01
PathAccessError.get_message() called Path(self.path) which re-wraps an
already-Path object. For S-rooted paths, Path() rejects the S root with
ValueError, crashing __str__ and producing '<exception str() failed>'.

Fix: call self.path.values() directly — self.path is already a Path at
every call site. Keep a lightweight AttributeError/IndexError fallback
for safety in case of unexpected .path types.

Test asserts the message content (key name, part index, error type),
not just that it doesn't crash.
@mahmoud mahmoud force-pushed the fix-249-pae-scope-printable branch from ec70055 to 7583a20 Compare June 29, 2026 03:09
@mahmoud mahmoud merged commit e515fb3 into mahmoud:master Jun 29, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

unprintable PathAccessError when using Scope/S

2 participants