You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cache and extend AttributeError member-name suggestions (static members and enum values) (#130)
* Cache AttributeError member-name suggestions per type and (type, name)
Building the "Did you mean ...?" hint for a missing attribute reflected over the
managed type's full member set (GetMembers with FlattenHierarchy), snake_cased
every member, and ran a Levenshtein scan -- on every miss, with no caching.
getattr(obj, name, default) and hasattr trigger it too, since the work happens on
the miss path before CPython suppresses the error. A workload that probes the
same missing names repeatedly (e.g. a per-bar getattr(self, "_optional", None) on
a .NET-derived object) therefore paid the full O(members) reflection + ranking
cost on every access.
Add two caches in ClassBase:
- _candidateNameCache (Type -> string[]): the reflected, deduplicated snake_case
member names, computed once per type.
- _suggestionCache ((Type, name) -> string[]): the ranked suggestion list,
memoized so repeated misses of the same name are a dictionary lookup.
Suggestions and error messages are unchanged; only the repeated computation is
removed. On a real Lean multi-symbol minute backtest the suggestion path
dominated ~93% of OnData CPU; with this change the backtest goes from not
finishing (aborted, >15x slower) to ~93s, on par with the last build without the
suggestion feature (~90s), with identical results.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Cache the built suggestion hint string instead of the member-name list
Store the fully-built " Did you mean: ...?" hint (empty when there is nothing
to suggest) in _suggestionCache rather than the ranked string[]. The hint is
now assembled once inside ComputeSimilarMemberNames and memoized per
(type, missing-name); GetSuggestionHint just returns the cached string and
appends it, dropping the per-miss Count check, Select and string.Join.
Behavior and message text are unchanged; a repeated miss is now a single
dictionary lookup returning the ready-made hint.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Move suggestion caches to the class field block; simplify candidate collection
Move the _candidateNameCache and _suggestionCache declarations up to the class
field block with the other fields. In GetCandidateMemberNames, collect the
snake_case names into a single HashSet (named names) instead of a HashSet plus a
List, and return the set directly; deduplication and storage are the same
collection. Candidate iteration order no longer matters -- suggestions are
ordered by edit distance and then by name.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Extend AttributeError suggestions to type-object (static and enum) misses
A missing attribute on a reflected type object -- a mistyped static member or
enum value such as DayOfWeek.Sundey -- previously raised the bare CPython
"type object 'X' has no attribute 'Y'" with no hint, because the miss hook was
installed on reflected types (governing their instances) but type-object access
is governed by the CLR metatype.
Install the same miss-only __getattr__ hook on the CLR metatype (allowing the
redirect when tp_getattro is type_getattro, not just the generic getattr), so a
type-object miss is enriched the same way instance misses are. BuildMissing
AttributeMessage now resolves the target from either a CLRObject (instance) or a
ClassBase (type object) and uses CPython's "type object 'T'" wording for the
latter.
Suggestions reuse the existing ranking/cache and the snake_case convention
Python exposes members under (ToSnakeCaseMemberName): methods become lower_snake
while enum values, consts and static-readonly members become UPPER_SNAKE, e.g.
DayOfWeek.Sundey -> "Did you mean: 'SUNDAY'?", Math.PII -> 'PI', String.Empy ->
'EMPTY'. All suggested names resolve. Hits, imports and hasattr on type objects
are unaffected (the hook is miss-only).
Adds tests for enum, static const, static-readonly field and static method
misses, the no-similar case and hasattr, in test_enum.py and test_class.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Update version to 2.0.58
Bump the package <Version>, AssemblyVersion/AssemblyFileVersion and the perf-test
baseline reference to 2.0.58 for the AttributeError suggestion caching and the
static/enum suggestion extension in this PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments