Skip to content

Improve error messages for datetime vs date operations in Python algorithms - #9659

Open
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:feature-datetime-date-error-hints
Open

Improve error messages for datetime vs date operations in Python algorithms#9659
jhonabreul wants to merge 2 commits into
QuantConnect:masterfrom
jhonabreul:feature-datetime-date-error-hints

Conversation

@jhonabreul

@jhonabreul jhonabreul commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Description

Python algorithms mixing datetime.datetime and datetime.date values (typically DTE math like (contract.id.date - self.time.date()).days) fail with TypeErrors that don't tell the user how to fix their code:

Trying to perform a summation, subtraction, multiplication or division between 'datetime.datetime' and 'datetime.date' objects throws a TypeError exception. To prevent the exception, ensure that both values share the same type.
can't compare datetime.datetime to datetime.date

Cause: the summation/subtraction message never says how to make the types match, and the comparison TypeError is not intercepted by any exception interpreter at all (UnsupportedOperandPythonExceptionInterpreter only matches "unsupported operand type").

The fix:

  • UnsupportedOperandPythonExceptionInterpreter.Interpret appends a hint when the offending operands are a datetime.datetime/datetime.date mix (either order): use the date part of the datetime value, e.g. (expiry.date() - today).days or self.time.date().
  • New DatetimeDateComparisonPythonExceptionInterpreter intercepts the can't compare datetime.datetime to datetime.date TypeError (raised for both comparison orders) and rewrites it with the same .date() guidance plus the parsed Python stack trace. It is auto-discovered by StackExceptionInterpreter.CreateFromAssemblies.
  • Message text lives in Messages.Exceptions.cs, following the existing per-interpreter message-class pattern.

This is a user-facing-message backstop: the companion QuantConnect/pythonnet#143 makes .NET DateTime values converted to Python coerce against pure date operands, which removes most of these failures at the root.

This PR also updates the QuantConnect.pythonnet package reference to 2.0.65 (the version carrying that coercion change) in the 11 consuming csproj files. Do not merge until QuantConnect/pythonnet#143 is merged and 2.0.65 is indexed on NuGet — restore fails before then.

Related Issue

N/A — recurring user-facing runtime errors reported from production backtests.

Motivation and Context

DTE filtering ((expiry - today).days) is one of the most common lines in options/futures Python algorithms, and today's errors leave users without an actionable fix.

Requires Documentation Change

No — error message improvements only.

How Has This Been Tested?

  • UnsupportedOperandPythonExceptionInterpreterTests: new tests assert the .date() hint is appended for datetime - date and date - datetime (real PythonExceptions raised from Test_PythonExceptionInterpreter.py), and not appended for unrelated operand pairs (None + str). Proven red before the fix (3 failed / 12 passed), green after.
  • New DatetimeDateComparisonPythonExceptionInterpreterTests: CanInterpret matrix (claims only the datetime/date comparison PythonException; rejects other exception types and the unsupported-operand TypeError, and vice versa), Interpret throw matrix, message content + Python stack line assertions, and an end-to-end StackExceptionInterpreter.CreateFromAssemblies test proving the new interpreter is discovered and applied.
  • Touched fixtures: 27 passed, 0 failed. Full QuantConnect.Tests.Common.Exceptions namespace: 147 passed, 0 failed. PythonUtilTests: 18 passed, 0 failed.
  • With the 2.0.65 Python.Runtime.dll (built from Support subtraction and ordering between converted DateTime values and datetime.date pythonnet#143) injected over this branch's test output, mirroring pythonnet's Lean CI workflows: Python unit tests 16045 passed / 0 failed / 9 skipped; Python regression algorithms 324/324 passed.

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>

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.

2 participants