Skip to content

Raise a proper TypeError when a property assignment cannot be performed#141

Open
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:bug-property-set-silent-conversion-failure
Open

Raise a proper TypeError when a property assignment cannot be performed#141
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:bug-property-set-silent-conversion-failure

Conversation

@jhonabreul

@jhonabreul jhonabreul commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What does this implement/fix?

Fixes a property-assignment bug that surfaced when a Lean Python algorithm assigned a pure-Python object to self.universe_manager (which snake-cases onto QCAlgorithm.UniverseManager { get; private set; }) and got the opaque SystemError: error return without exception set instead of an actionable error:

Converter.ToManagedValue could fail without setting a Python error even when called with setError: true. Three exits returned false silently: the final fall-through (plain Python object with no conversion to an arbitrary CLR class), the reflected-class-object case (converting a CLR class object to something other than Type), and non-MethodBinding managed types (method/module objects). PropertyObject.tp_descr_set trusts setError: true and returns -1, so CPython's release-build eval loop raises SystemError: error return without exception set at the assignment. These exits now set the same '{type}' value cannot be converted to {obType} TypeError the type_error label already uses, preserving any more specific error a probing sub-path (e.g. a throwing implicit operator) left pending.

With the fix, the Lean repro turns from SystemError: error return without exception set into TypeError: 'UniverseManager' value cannot be converted to QuantConnect.Securities.UniverseManager, pointing straight at the offending assignment.

The fix carries its own regression tests, verified red before the fix and green after.

Does this close any currently open issues?

No open issue; root-caused from a Lean user report of error return without exception set during algorithm initialization.

Any other comments?

Python assignment to CLR properties with private setters (via reflection) is intentionally left untouched by this PR.

End-to-end verification against Lean master (the original repro): self.universe_manager = <pure python object> in a Python algorithm now fails with a clear TypeError at the offending line instead of SystemError: error return without exception set.

@jhonabreul jhonabreul force-pushed the bug-property-set-silent-conversion-failure branch from d8e51db to f039e68 Compare July 15, 2026 21:59
Converter.ToManagedValue had three exits that reported failure without
setting a Python error: the final fall-through when a plain Python object
has no conversion to the target CLR class, the ClassBase exit when a
reflected class object is converted to something other than Type, and the
exit for managed values that are neither CLRObject, ClassBase, nor
MethodBinding (e.g. a MethodObject). Callers that pass setError true, such
as PropertyObject.tp_descr_set, trust the failure to carry a pending error
and return -1, so CPython raised "SystemError: error return without
exception set" instead of a useful message. Assigning a pure Python object
to a C# property of a CLR class type reproduced this. These exits now set
the conventional TypeError ("'<type>' value cannot be converted to
<target>") when setError is true and no more specific error is already
pending from a probing sub-path; setError false behavior is unchanged.
@jhonabreul jhonabreul force-pushed the bug-property-set-silent-conversion-failure branch from f039e68 to f069ab4 Compare July 15, 2026 22:44
@jhonabreul jhonabreul marked this pull request as ready for review July 15, 2026 22:51
Bump package <Version>, AssemblyVersion/AssemblyFileVersion and the
perf-test baseline reference to 2.0.64.
@jhonabreul jhonabreul force-pushed the bug-property-set-silent-conversion-failure branch from c651aee to 760e346 Compare July 16, 2026 13:01
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.

1 participant