Skip to content

Fixed-point number (VT_CY / VT_DECIMAL) marshaling improvements. - #978

Merged
junkmd merged 14 commits into
enthought:mainfrom
junkmd:cy_dec_variant_internal_safearray_unpack
Oct 31, 2026
Merged

junkmd merged 14 commits into
enthought:mainfrom
junkmd:cy_dec_variant_internal_safearray_unpack

Conversation

@junkmd

@junkmd junkmd commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Motivation

comtypes has problems with fixed-point numbers (VT_CY and VT_DECIMAL).

Current problems:

  • VT_CY uses c_longlong for internal storage. This is not correct because VT_CY should use tagCY structure.
  • When sending Decimal values, the code uses int(round(value * 10000)) which silently truncates large values and rounds without warning.
  • The calculation uses global decimal context, so getcontext().prec changes the result.
  • There is no way to send VT_DECIMAL type.
  • The _ctype_to_vartype dictionary is missing VT_CY and VT_DECIMAL entries.
  • SAFEARRAY did not support tagCY or tagDEC types, so fixed-point numbers could not be used in arrays.

Summary

This PR fixes the fixed-point number marshaling.
SAFEARRAY now supports tagDEC and tagCY, and preserves the correct type when the internal storage of a VARIANT is VT_CY.
Implicit rounding when passing a Decimal to a VARIANT parameter has been maintained. Keeping this behavior unchanged for now as it fall under Hyrum's Law.

Changes

Changed Behavior

  • VT_CY internal representation: The private union field v._.VT_CY now uses tagCY structure instead of c_longlong. This is an internal change only (accessed via v._.VT_CY).
  • Dictionary completeness: _ctype_to_vartype now includes tagCY: VT_CY and tagDEC: VT_DECIMAL mappings.
  • SAFEARRAY support: SAFEARRAY(tagCY) and SAFEARRAY(tagDEC) can now be created and unpacked. Unpacking returns Decimal values for easier use.

Not Changed

  • Public API: VARIANT.value property setter behavior for Decimal values is unchanged
  • tagDEC.as_decimal() behavior unchanged

Internal Changes

  • v._.VT_CY is now a tagCY structure, not c_longlong. Code accessing this private attribute directly will need to use .int64 property.
  • _vartype_to_ctype and _ctype_to_vartype updated for VT_CY and VT_DECIMAL.

…duce unit tests for their representation.
… `tagDEC`.

Due to a lack of proper conditional branching in the production code, it is
incorrectly treated as a struct that does not support `IRecordInfo`.
… `tagDEC`; add comprehensive unit tests for conversion methods.
In Python versions before 2.4, the `decimal` module was not in the stdlib.
So the check `decimal is not None` was needed.
Now this check is always True.
So we remove this redundant condition.
https://github.com/enthought/comtypes/blob/938fbd50d2077c6bd524790a9ed798c3990cdfc0/comtypes/automation.py#L8-L11
@junkmd junkmd added this to the 1.5.0 / Support Python 3.15 milestone Oct 31, 2026
@codecov-commenter

codecov-commenter commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.52267% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.33%. Comparing base (3bf33b2) to head (302d7f0).

Files with missing lines Patch % Lines
comtypes/test/test_fixed_point_numbers.py 98.26% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #978      +/-   ##
==========================================
+ Coverage   90.05%   90.33%   +0.27%     
==========================================
  Files         143      145       +2     
  Lines       14152    14567     +415     
==========================================
+ Hits        12745    13159     +414     
- Misses       1407     1408       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@junkmd junkmd added enhancement New feature or request tests enhance or fix tests labels Oct 31, 2026
@junkmd
junkmd merged commit 74e037e into enthought:main Oct 31, 2026
149 of 151 checks passed
@junkmd
junkmd deleted the cy_dec_variant_internal_safearray_unpack branch October 31, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request tests enhance or fix tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants