Skip to content

Conversation

geppi
Copy link
Collaborator

@geppi geppi commented Sep 25, 2025

This PR implements:

  • Respecting type information when setting COM Record field values which enables SAFEARRAY fields of various element types, not just SAFEARRY(VARIANT).
  • Creating a multidimensional SAFEARRAY(COM Record) from a nested sequence of COM Records.
  • Retrieving a multidimensional SAFEARRAY(COM Record) as a nested sequence of COM Records.
  • Using multidimensional SAFEARRAYs of various element types as Record fields.
  • Tests for the implementation.
    These do also cover a test case as requested in Bugfix for COM Record instance creation. #2641 (review).

…Y(double)

Create SAFEARRAY(double) from a sequence of PyFloat objects instead of
SAFEARRAY(VARIANT(RT_8)).
The implementation builds multidimensional SAFEARRAYs from nested sequences.
The creation of SAFEARRAY(VT_RECORD) was improved to also allow nested
sequences.
@geppi
Copy link
Collaborator Author

geppi commented Sep 25, 2025

@Avasam I had to retarget the Visual Studio project of PyCOMTest for the build tools v143 with a wild card for "the latest" installed Win SDK version because the build did fail, complaining that:

The Windows SDK version 10.0.20348.0 was not found.

@geppi geppi requested review from mhammond and Avasam September 25, 2025 16:09
@Avasam
Copy link
Collaborator

Avasam commented Sep 27, 2025

@Avasam I had to retarget the Visual Studio project of PyCOMTest for the build tools v143 with a wild card for "the latest" installed Win SDK version because the build did fail, complaining that:

I don't mind the retargeting and bumping the platform toolset to v143 (Visual Studio 2022) makes sense. I probably missed that somewhere in the recent CI migration to windows-2022 (and/or something else changed after the initial migration).


As for the rest of the PR, I am not qualified to review that / it is past my areas of expertise, so 🤷 Leaving to @mhammond

Avasam added a commit to Avasam/pywin32 that referenced this pull request Sep 27, 2025
Copy link
Owner

@mhammond mhammond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - I'm going to need more time to look at this thoroughly, but some initial thoughts...

@geppi geppi force-pushed the multidim_safearray branch from 9077722 to 6617885 Compare October 4, 2025 15:16
@geppi
Copy link
Collaborator Author

geppi commented Oct 4, 2025

After reviewing the code path for the assignment of values to Record fields, I think the problem is that it was wrong from the beginning.

When I implemented the creation of SAFEARRAY(VT_RECORD) from a sequence of COM Records #2317, I followed the existing code path into PyCom_VariantFromPyObject and changed it to fit my actual use case. Later I encountered another COM Record type which has a field defined as SAFEARRAY(double) in the IDL file and tried to apply a similar change in the current PR, to also fit this use case.

Obviously IDL files in the field could contain struct definitions for SAFEARRAYs with other contained types, so we would need to change PyCom_VariantFromPyObject for the SAFEARRAYs of other types as well.
However, what would really be a problem is that an IDL file could also have a field defined as SAFEARRAY(VARIANT) which would then create an unresolvable conflict for this implementation.

The culprit is the setattro method of PyRecord that ignores the type information for Record fields which would well be available.

I think setattro should have never taken the code path via PyCom_VariantFromPyObject.
Instead it should retrieve the type information for the Record field via ITypeInfo and call PyCom_SAFEARRAYFromPyObject directly using this information in the vt parameter. For scalar types it should call the MakeObjToVariant method of PythonOleArgHelper, again using the retrieved type information in the m_reqdType attribute.

I have now reverted my changes in PyCom_VariantFromPyObject to the state before PR #2317, so that this function keeps doing what its name says, i.e. it always creates a VARIANT from PyObjects. Therefore the SAFEARRAYs it creates will contain VARIANT elements as was before PR #2317.

To fulfill the type requirements defined in an IDL file for the struct fields, the setattro method of PyRecord is changed in the way described above.

@mhammond Please let me know if you agree with this in general.

@geppi geppi changed the title Implementation of multidimensional SAFEARRAY(COM Record), SAFEARRAY(double) COM Record field assignment using type information and multidim SAFEARRAYs as field values Oct 4, 2025
@geppi geppi requested a review from mhammond October 4, 2025 16:43
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.

3 participants