Add explicit WinRT Object boxing and type-preserving unboxing to Python - #194
Open
leileizhang (lei9444) wants to merge 4 commits into
Open
leileizhang (lei9444) wants to merge 4 commits into
leileizhang (lei9444) wants to merge 4 commits into
Conversation
Generated Object positions stay native (IInspectable); applications now convert boxed values explicitly at the boundaries that want value semantics. Core: PropertyValueData models every PropertyType that has a payload (37 of 41), unbox_property_value reports payload-less boxes as Unsupported, and box_property_value creates system PropertyValue boxes. JavaScript keeps its exact behavior and messages through a compile-only adapter. Python: - unbox_object additionally supports DateTime, TimeSpan, Point, Size, Rect, their arrays and InspectableArray (elements unboxed by the same rules); already-supported types return the same values, and payload-less boxes still raise OSError. - unbox_object(raw, preserve_type=True) returns dynwinrt.values tags and typed arrays, so to_winrt_object restores the exact PropertyType and value. - to_winrt_object(value, property_type=None) boxes only unambiguous values: a plain int is Int32 only, lists must be homogeneous, and enum members, empty or mixed lists and InspectableArray need an explicit type. - The tags, typed arrays, Point/Size/Rect and PropertyType live in the new dynwinrt.values submodule, outside the top-level namespace. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Python-only checks on generated bindings: - object_value_roundtrip: every PropertyValue.create_* factory (37 PropertyTypes) round-trips through unbox_object(preserve_type=True) and to_winrt_object with its exact PropertyType, and dynwinrt.values.PropertyType matches the metadata enum. - object_value_storage_properties: a temporary file's System.Size unboxes as UInt64 in preserve mode and System.DateModified as an aware datetime. - object_value_device_properties: DeviceInformation.properties values unbox as str, bool and UUID, skipping gracefully without devices. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mixed-language test coverageWorkflow status: ✅ Passed
|
Bring #188's lifecycle-aware Python runtime, implementation callback checks, apartment constants, actionable errors, and released-reference E2E coverage into the explicit Object value conversion branch. Resolve the overlapping runtime API by keeping unbox_object in the explicit conversion layer and routing every native read through DynWinRTValue's live input check. Released top-level values, projected wrappers, inferred list items, typed-array items, and explicit InspectableArray items now raise the standard released-input RuntimeError rather than appearing as WinRT null. Legitimate null values retain their existing boxing and unboxing behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
leileizhang (lei9444)
added a commit
that referenced
this pull request
Sep 28, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add an opt-in value view for WinRT Object-valued maps in Python dynwinrt.values.object_value_view(mapping, *, preserve_type=False) wraps a generated IMap or IMapView wrapper whose values are Object, such as PropertySet, ValueSet or DeviceInformation.properties. It returns a live MutableObjectValueView or read-only ObjectValueView that holds no WinRT reference of its own: reads unbox with unbox_object(), writes box with to_winrt_object()'s default rules, and view.raw is the generated map. QueryInterface for IMap/IMapView<String or Guid, Object> confirms the value type, so other maps such as StringMap raise TypeError, and the overloads reject them statically. A box without a Python form (an unsupported PropertyType or a DateTime outside datetime's range) reads back raw so that dict(view) does not fail on one odd entry. Generated code, unbox_object() and to_winrt_object() are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Type MutableObjectValueView.update() like item assignment update() writes through __setitem__ and to_winrt_object(), so its overloads now accept any value, as item assignment already does. They mirror MutableMapping.update(), which allows keyword arguments only for str keys. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Type MutableObjectValueView.setdefault() like item assignment setdefault() now accepts any default that to_winrt_object() accepts, like __setitem__ and update(), and returns the read type: after storing a missing key it reads the value back, so (1, 2) returns [1, 2] and a runtime object its DynWinRTValue. MutableMapping.setdefault() would return the default itself. A targeted type: ignore[override] covers typeshed's self-typed overload, which infers "-> None" for a value type that includes None. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Address Object map view review findings Mark only binding-classified unsupported PropertyTypes so a supported IPropertyValue getter that returns the same HRESULT still propagates. Verify that a generated wrapper's actual map dispatch pointer is the reflexive IMap/IMapView<String or Guid, Object> pointer, rejecting another map wrapper on the same COM identity while preserving .raw. Constrain the public view key type to str or UUID. Add a synthetic dual-map COM object, getter-error identity checks, strict mypy/Pyright key controls, and generated Guid-map E2E coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Validate Object map dispatch metadata Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Regress released Object map views with updated runtime Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.
Problem
unbox_object()lacked severalIPropertyValuetypes, lost numeric type information, and Python had no explicit boxing helper.Automatic conversion at every
Objectposition is unsafe becauseObjectmay be a runtime object and Python values do not identify one exact WinRT type.Key changes
Objectpositions raw; add explicitto_winrt_object(value, property_type=None).unbox_object(value, *, preserve_type=False)to DateTime, TimeSpan, Point/Size/Rect, their arrays, and InspectableArray.dynwinrt.values: exact numeric tags, typed arrays, geometry values, and aPropertyTypeenum.Notes
intmeans Int32 only; enum members, empty/mixed lists, and InspectableArray require an explicit type.