Skip to content

Prefer pythonnet's structured bind-failure data over message parsing - #9663

Closed
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:feature-structured-bind-failure-hints
Closed

Prefer pythonnet's structured bind-failure data over message parsing#9663
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:feature-structured-bind-failure-hints

Conversation

@jhonabreul

Copy link
Copy Markdown
Collaborator

Description

NoMethodMatchPythonExceptionInterpreter now prefers the structured data pythonnet attaches to the bind-failure TypeError — _clr_method_name and _clr_overloads_hint attributes on the exception instance — over parsing them out of the exception message. When the attributes are absent (any pythonnet version released so far) or cannot be read, the interpreter silently falls back to the existing message parsing, which is left intact. The rendered user-facing message is unchanged in both paths.

Pairs with QuantConnect/pythonnet#148, which attaches the attributes; this PR degrades gracefully without it, so it can be merged independently and does not require a pythonnet version bump.

Related Issue

Part of the error-surface improvements from the fleet-evidence study (QuantConnect/Agents#305, improvement 1): the interpreter's string parsing of pythonnet's message has garbled user-facing errors before (#9573, #9594); reading structured fields removes that coupling going forward.

Motivation and Context

Lean currently reconstructs the failed method name and the overloads hint by string-parsing pythonnet's TypeError message, a contract that has silently drifted before and produced garbled messages like required by the 'int'>) method. With pythonnet attaching the underlying data as exception attributes, the interpreter reads fields instead of parsing prose, and only falls back to parsing for older pythonnet versions.

Requires Documentation Change

None.

How Has This Been Tested?

  • New tests in NoMethodMatchPythonExceptionInterpreterTests: one verifying the structured attributes take precedence over the message contents when present, one verifying the fallback to message parsing when they are absent. Both use synthesized TypeErrors from the Test_PythonExceptionInterpreter fixture, so they run against the currently referenced pythonnet package.
  • Existing NoMethodMatchPythonExceptionInterpreterTests (real bind failures through the referenced pythonnet) still pass, covering the fallback path end-to-end.
  • The structured path was also verified end-to-end against a locally built pythonnet from Attach structured bind-failure data to the no-method-matches TypeError pythonnet#148 copied into the test output.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My branch follows the naming convention bug-<issue#>-<description> or feature-<issue#>-<description>

NoMethodMatchPythonExceptionInterpreter now reads the method name and
overloads hint from the attributes pythonnet attaches to the bind-failure
TypeError (_clr_method_name, _clr_overloads_hint) instead of parsing them
out of the exception message. When the attributes are absent (older
pythonnet versions) or unreadable, it silently falls back to the existing
message parsing. The rendered user-facing message is unchanged.
@jhonabreul
jhonabreul marked this pull request as ready for review August 11, 2026 17:50
@jhonabreul
jhonabreul requested review from Martin-Molinero and a lite review from Copilot and removed request for Martin-Molinero and Copilot August 11, 2026 17:50
@jhonabreul
jhonabreul marked this pull request as draft August 11, 2026 17:50
@jhonabreul jhonabreul closed this Aug 11, 2026
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