Improve error messages for unsupported Python objects in user-facing APIs#9607
Open
jhonabreul wants to merge 9 commits into
Open
Improve error messages for unsupported Python objects in user-facing APIs#9607jhonabreul wants to merge 9 commits into
jhonabreul wants to merge 9 commits into
Conversation
… and add QuoteBarConsolidator.FromResolution
5 tasks
Martin-Molinero
approved these changes
Jul 10, 2026
Martin-Molinero
approved these changes
Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Passing an unsupported Python object to several user-facing APIs surfaces pythonnet's raw conversion error, which gives the user no hint about what went wrong or how to fix it. For example:
fails with:
Since none of the constructor overloads accept a
Resolution, the call binds to thePyObjectoverload, whose handling inPeriodCountConsolidatorBase.GetPeriodSpecificationFromPyObjectonly supports atimedeltaor a callable returning aCalendarInfo. The fallbackpyObject.As<TimeSpan>()conversion throws a rawInvalidCastException.This change catches these conversion failures and throws descriptive exceptions instead, stating the given value and its Python type and listing the available overloads, keeping the original exception as inner exception:
The overloads are rendered as Python signatures (snake_case names,
name: typeannotations, Python types). ThePyObjectoverloads — the ones that just rejected the value — are excluded from the hint.The overload list is rendered by
MethodSignatureFormatter, the helper exposed by QuantConnect/pythonnet#136 (the same formatting pythonnet uses for its "No method matches given arguments" hint). This PR therefore depends on that pythonnet PR being merged and released as 2.0.61 (the reference is already bumped here) — CI will fail until the package is published.A new
PyObject.ToDisplayString()extension centralizes the value-and-type rendering, and the same pattern is applied to the other user-facing conversion sites that surfaced the same raw error:PeriodCountConsolidatorBase(PyObject)— all period-based consolidator constructors (TradeBarConsolidator,QuoteBarConsolidator,TickConsolidator, etc.)QCAlgorithm.SetBenchmark(PyObject)— non-callable, non-Symbol benchmark argumentsDynamicData.SetProperty— assigning incompatible Python values to the reservedtime/end_time/value/symbolproperties of custom data, now naming the offending propertySecurity.Get<T>/TryGet<T>/Remove<T>custom properties — reading a Python-stored property with an incompatible type now names the property key and target type (stillInvalidCastException, as documented)ScheduledUniverse/ScheduledUniverseSelectionModelPython constructors — a non-callable selector now throws a descriptiveArgumentExceptioninstead of failing later with aNullReferenceExceptionAdditionally,
QuoteBarConsolidator.FromResolution(Resolution)is added, matching the existing helper inTradeBarConsolidator,BaseDataConsolidatorandOpenInterestConsolidator, so a quote bar consolidator can be created directly from aResolution.Related Issue
N/A
Related PR: QuantConnect/pythonnet#136 — exposes the
MethodSignatureFormatterhelper this PR uses to render the overload lists. TheQuantConnect.pythonnetreference is already bumped to 2.0.61 here (the version being released by QuantConnect/pythonnet#135); CI will pass once that package is published with #136 included.Motivation and Context
The raw pythonnet error
cannot convert object to target typesurfaces directly to Python algorithm users during algorithm initialization and gives them no information about which argument is wrong, why, or what to use instead. This is a common stumbling block since other APIs (e.g.self.consolidate) do accept aResolution, making it natural for users to try passing one to the consolidator constructors.Requires Documentation Change
No.
How Has This Been Tested?
PeriodCountConsolidatorTests.PyObjectConstructorThrowsDescriptiveErrorForUnsupportedPeriodTypePeriodCountConsolidatorTests.QuoteBarConsolidatorFromResolutionCreatesConsolidatorWithExpectedPeriodAlgorithmBenchmarkTests.PythonSetBenchmarkThrowsDescriptiveErrorForUnsupportedBenchmarkTypeDynamicDataTests.SettingReservedPropertyWithUnsupportedPythonValueThrowsDescriptiveErrorSecurityTests.GettingPythonCustomPropertyWithIncompatibleTypeThrowsDescriptiveErrorScheduledUniverseTests.PythonConstructorThrowsDescriptiveErrorWhenSelectorIsNotAFunctionPeriodCountConsolidatorTests,CalendarConsolidatorsTests,DynamicDataTestsandScheduledUniverseTestssuites, which cover the supported conversion paths (Python callables,timedelta, valid property values), to verify no behavior change.Types of changes
Checklist:
bug-<issue#>-<description>orfeature-<issue#>-<description>