Commit 691f9d7
Implementation of 'com_record' as a subclassable Python type. (#2437)
* Implementation of 'com_record' as a subclassable Python type.
A 'tp_new' method was added to the 'PyTypeObject' slots of 'com_record'.
Replacement new is now used to create an instance of a 'com_record' type,
i.e. in 'tp_new' as well as in the factory functions. The 'tp_dealloc'
method explicitely calls the destructor before finally calling 'tp_free'.
Records returned from a call to a COM method do get the subclass type
according to the GUID in the COM RecordInfo. If no subclass with that
GUID is found, the generic 'com_record' base class is used.
The algorithm that retrieves the list of subclasses of 'com_record'
only uses methods and data structures of the public Python API.
This is important because in Python 3.12 the type of the 'tp_subclasses'
slot of a 'PyTypeObject' was changed to 'void*' to indicate that for some
types it does not hold a valid 'PyObject*'.
The 'PyRecord_Check' function was modified to test if the object is an
instance of 'com_record' or a derived type.
The implementation does not break existing code.
It is not required to define 'com_record' subclasses, i.e. it is possible
to work with the generic 'com_record' type as before using the factory
function.
* Removed an unnecessary type cast and unreferenced local variables.
* Added a global dictionary for 'pythoncom.com_record' subclass registration.
* The algorithm that identifies the subclass of 'pythoncom.com_record'
from which a COM Record instance will be created now looks up the Record GUID
in a global map, to only create instances of subclasses that have explicitely
been registered in this map.
* Added the function 'register_record_class' to add proper subclasses of
'pythoncom.com_record' to the global map 'pythoncom.RecordClasses'.
The function does only add instantiable subclasses of 'pythoncom.com_record'
to the map if their GUID is not already contained in the map.
* Added a check for the record type name in the 'register_record_class'
Python function.
Also added another dunder attribute '__record_type_name__' to the
'PyRecord::getattro' function that retrieves the record type name
via 'IRecordInfo::GetName'.
* Update com/win32com/client/__init__.py
Co-authored-by: Avasam <samuel.06@hotmail.com>
* Code cleanup.
* Reverted the part of commit cd1c2fc
that added a check for the record type name in the 'register_record_class'
Python function.
* Added the dunder attribute '__record_type_guid__' to the
'PyRecord::getattro' function that retrieves the record
type GUID via 'IRecordInfo::GetGuid'.
* Added a NULL check for 'PyRecord::new_record' before calling
'PyTuple_SET_ITEM' in the 'PyObject_FromSAFEARRAYRecordInfo' function.
Also enhanced the treatment of NULL return values in several other
places in 'PyRecord.cpp'.
* Added tests for the 'pythoncom.com_record' subclassing functionality.
* Added a NULL check for 'PyRecord::new_record' before calling
'PyTuple_SET_ITEM' in the 'PyRecord::getattro' function.
Also 'PyRecord::new_record' will now raise a 'PyErr_NoMemory'
exception when the call to 'tp_alloc' returns NULL.
* Added a method for the 'tp_init' slot of 'com_record' to enable
instance initialization.
Also changed the com_record base class to be only instantiable via
the Record factory function and subclasses of com_record only if
they are registered.
Modified the test in 'testPyComTest.py' to reflect this.
Added a test for the initialization of com_record subclasses.
* Added a changelog entry.
* Added changes from code review.
---------
Co-authored-by: Avasam <samuel.06@hotmail.com>1 parent f587548 commit 691f9d7
8 files changed
Lines changed: 438 additions & 76 deletions
File tree
- com/win32com
- client
- src
- include
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| 21 | + | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
487 | 487 | | |
488 | 488 | | |
489 | 489 | | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
490 | 531 | | |
491 | 532 | | |
492 | 533 | | |
| |||
0 commit comments