Repository navigation
Hide engine-only extension methods and the OrderTicket int conversion from Python - #9988
Conversation
There was a problem hiding this comment.
Approving. The change is small and does what the description says. I verified it myself:
- CI: all checks pass. The unit test job ran 39,185 tests with 0 failures.
- The new test catches the regression: I reverted only the
EditorBrowsablecommit and ranEditorBrowsableNeverExtensionMethodsAreNotBoundToPythonInstances. It fails (hasattr(symbol, 'requires_mapping')is True). It passes on the head commit, along with the other 485 tests inExtensionsTests,ContingentOrder*andOrderTicket*. - Mechanism: pythonnet 2.0.67 (already on master since #9964) skips
EditorBrowsable(Never)members when it binds extension methods to instances (IsHiddenin pythonnet'sExtensionMethods.cs). The attribute changes nothing for C# callers, so engine and user C# code still compile and run as before. - End to end: I ran a Python backtest on a build of this branch.
hasattrwas False forsymbol.requires_mapping,self.set_runtime_errorandself.process_security_changes.Extensions.requires_mapping(symbol)still worked. Market and combo orders filled.order.is_contingent()stayed bound, andint(ticket)still returned the order id at runtime.StubsIgnoreonly hides the conversion from the stubs, not from Python. - Callers: none of the newly hidden methods are called in instance form from any Python algorithm in this repository or in the documentation examples.
Smaller points, none of them blocking:
CreateOptionChainandCreateFutureChain(boththis IAlgorithm) are still bound to Python algorithm instances, asself.create_option_chain(...). They look just as engine-only asProcessSecurityChanges. Was leaving them out intentional?- An inline nit on the
usingorder inExtensions.cs. - It would help to add the end-to-end outcome to the description's testing section.
Affected repositories: QuantConnect/quantconnect-stubs-generator#104 (still open) should ship with this PR, as the description says. No other repository needs an update.
Risk: risk:high. This changes Lean's Python algorithm API. Release 18215 already includes pythonnet 2.0.67, so a Python algorithm can call these methods in instance form today (e.g. symbol.requires_mapping()). After this PR they only exist in their static form. That is very unlikely to affect anyone, since these methods are engine plumbing, and the change is easy to revert. But removing user-visible members is a high-risk trait regardless of the evidence.
| * limitations under the License. | ||
| */ | ||
|
|
||
| using System.ComponentModel; |
There was a problem hiding this comment.
Nit: this goes above using System;, while the rest of the block is sorted. Moving it after using System.Collections.Immutable; keeps the order.
Description
Python.NET 2.0.67 (QuantConnect/pythonnet#150 and #151) binds C# extension methods to the type they extend and gives types with an implicit numeric conversion the Python number protocol. The stubs follow suit in QuantConnect/quantconnect-stubs-generator#104. Two things on the Lean side should stay out of the user-facing surface:
IAlgorithm,Symbol,OrderandSubscriptionDataConfig, such asProcessSecurityChanges,RequiresMapping,ShouldEmitDataorTryGetContingentOrders, are markedEditorBrowsable(Never). Python.NET and the stubs keep them in their static form instead of binding them to the instance.OrderTicket'simplicit operator intis markedStubsIgnore, so the stubs do not give tickets the number protocol.Split out of #9896 so it can ship together with the stubs generator PR.
Related Issue
N/A
Motivation and Context
Without the attributes, every Python
Symbol,Orderor algorithm instance advertises engine plumbing likeself.set_runtime_error()orsymbol.requires_mapping(), andOrderTicketgets__add__and friends in the stubs.Requires Documentation Change
No.
How Has This Been Tested?
ExtensionsTests.EditorBrowsableNeverExtensionMethodsAreNotBoundToPythonInstances:hasattris false for the hidden methods on aSymbol, anOrderand aSubscriptionDataConfig, the other extensions such asorder.is_contingent()stay bound, and the static forms still work.OrderTicket.Types of changes
Checklist:
bug-<issue#>-<description>orfeature-<issue#>-<description>