mirror of
https://github.com/python/cpython.git
synced 2025-12-01 07:19:24 +00:00
gh-137967: Restore suggestions on nested attribute access (#137968)
Some checks failed
Tests / Docs (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with AWS-LC (push) Blocked by required conditions
Tests / Android (aarch64) (push) Blocked by required conditions
Tests / Android (x86_64) (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
Tests / Sanitizers (push) Blocked by required conditions
Tail calling interpreter / aarch64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / aarch64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / x86_64-pc-windows-msvc/msvc (push) Waiting to run
Tail calling interpreter / x86_64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / free-threading (push) Waiting to run
Tail calling interpreter / x86_64-unknown-linux-gnu/gcc (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
JIT / Interpreter (Debug) (push) Has been cancelled
JIT / aarch64-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / aarch64-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / i686-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / aarch64-apple-darwin/clang (Release) (push) Has been cancelled
JIT / x86_64-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / x86_64-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / x86_64-apple-darwin/clang (Release) (push) Has been cancelled
JIT / x86_64-unknown-linux-gnu/gcc (Release) (push) Has been cancelled
JIT / x86_64-unknown-linux-gnu/gcc (Debug) (push) Has been cancelled
JIT / i686-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / aarch64-unknown-linux-gnu/gcc (Release) (push) Has been cancelled
JIT / aarch64-apple-darwin/clang (Debug) (push) Has been cancelled
JIT / aarch64-unknown-linux-gnu/gcc (Debug) (push) Has been cancelled
JIT / x86_64-apple-darwin/clang (Debug) (push) Has been cancelled
Some checks failed
Tests / Docs (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with AWS-LC (push) Blocked by required conditions
Tests / Android (aarch64) (push) Blocked by required conditions
Tests / Android (x86_64) (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
Tests / Sanitizers (push) Blocked by required conditions
Tail calling interpreter / aarch64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / aarch64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / x86_64-pc-windows-msvc/msvc (push) Waiting to run
Tail calling interpreter / x86_64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / free-threading (push) Waiting to run
Tail calling interpreter / x86_64-unknown-linux-gnu/gcc (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
JIT / Interpreter (Debug) (push) Has been cancelled
JIT / aarch64-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / aarch64-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / i686-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / aarch64-apple-darwin/clang (Release) (push) Has been cancelled
JIT / x86_64-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / x86_64-pc-windows-msvc/msvc (Debug) (push) Has been cancelled
JIT / x86_64-apple-darwin/clang (Release) (push) Has been cancelled
JIT / x86_64-unknown-linux-gnu/gcc (Release) (push) Has been cancelled
JIT / x86_64-unknown-linux-gnu/gcc (Debug) (push) Has been cancelled
JIT / i686-pc-windows-msvc/msvc (Release) (push) Has been cancelled
JIT / aarch64-unknown-linux-gnu/gcc (Release) (push) Has been cancelled
JIT / aarch64-apple-darwin/clang (Debug) (push) Has been cancelled
JIT / aarch64-unknown-linux-gnu/gcc (Debug) (push) Has been cancelled
JIT / x86_64-apple-darwin/clang (Debug) (push) Has been cancelled
This commit is contained in:
parent
339f5da639
commit
539a4ca1b9
4 changed files with 257 additions and 1 deletions
|
|
@ -1601,6 +1601,34 @@ def _substitution_cost(ch_a, ch_b):
|
|||
return _MOVE_COST
|
||||
|
||||
|
||||
def _check_for_nested_attribute(obj, wrong_name, attrs):
|
||||
"""Check if any attribute of obj has the wrong_name as a nested attribute.
|
||||
|
||||
Returns the first nested attribute suggestion found, or None.
|
||||
Limited to checking 20 attributes.
|
||||
Only considers non-descriptor attributes to avoid executing arbitrary code.
|
||||
"""
|
||||
# Check for nested attributes (only one level deep)
|
||||
attrs_to_check = [x for x in attrs if not x.startswith('_')][:20] # Limit number of attributes to check
|
||||
for attr_name in attrs_to_check:
|
||||
with suppress(Exception):
|
||||
# Check if attr_name is a descriptor - if so, skip it
|
||||
attr_from_class = getattr(type(obj), attr_name, None)
|
||||
if attr_from_class is not None and hasattr(attr_from_class, '__get__'):
|
||||
continue # Skip descriptors to avoid executing arbitrary code
|
||||
|
||||
# Safe to get the attribute since it's not a descriptor
|
||||
attr_obj = getattr(obj, attr_name)
|
||||
|
||||
# Check if the nested attribute exists and is not a descriptor
|
||||
nested_attr_from_class = getattr(type(attr_obj), wrong_name, None)
|
||||
|
||||
if hasattr(attr_obj, wrong_name):
|
||||
return f"{attr_name}.{wrong_name}"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _compute_suggestion_error(exc_value, tb, wrong_name):
|
||||
if wrong_name is None or not isinstance(wrong_name, str):
|
||||
return None
|
||||
|
|
@ -1666,7 +1694,9 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
|
|||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
return _suggestions._generate_suggestions(d, wrong_name)
|
||||
suggestion = _suggestions._generate_suggestions(d, wrong_name)
|
||||
if suggestion:
|
||||
return suggestion
|
||||
|
||||
# Compute closest match
|
||||
|
||||
|
|
@ -1691,6 +1721,14 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
|
|||
if not suggestion or current_distance < best_distance:
|
||||
suggestion = possible_name
|
||||
best_distance = current_distance
|
||||
|
||||
# If no direct attribute match found, check for nested attributes
|
||||
if not suggestion and isinstance(exc_value, AttributeError):
|
||||
with suppress(Exception):
|
||||
nested_suggestion = _check_for_nested_attribute(exc_value.obj, wrong_name, d)
|
||||
if nested_suggestion:
|
||||
return nested_suggestion
|
||||
|
||||
return suggestion
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue