You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
"a foreign function that will call a COM method" generated by ctypes.WINFUNCTYPE works in Python3.7, does not work as same in newer Python #99952
Is the bug in the setting or the fetching of that value?
In other words, if you make a spreadsheet manually by hand with those
values, and then change your test case to just open the file and fetch
the values in that cell range, do you get the expected results?
Is the bug in the setting or the fetching of that value?
The same behaviour.
For such code:
xl = CreateObject("Excel.Application")
from comtypes.gen.Excel import xlRangeValueDefault
xl.Workbooks.Add()
xl.Range["A1", "C1"].Value[xlRangeValueDefault] = (10, "20", 31.4)
xl.Visible = True
print(xl.Range["A1", "C1"].Value[xlRangeValueDefault])
input("Press a key") # in this place we just edited a row
print(xl.Range["A1", "C1"].Value[xlRangeValueDefault])
input("Press a key")
xl.Quit()
we have results:
D:\Py>py -3.7 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
D:\Py>py -3.10 z_COM.py
10.0
Press a key
33.0
Press a key
D:\Py>py -3.11 z_COM.py
10.0
Press a key
33.0
Press a key
PS: py>3.7 gets last cell in the row instead of whole row.
VARIANT("A1") and VARIANT("C1") are created by from_param() for calling com method.
It seems that line 203 _VariantClear() is called after line 214 soon.
Then, memory is freed before calling com method.
Also, SysAllocStringLen() returns same memory address with "A1" for "C1".
comtypes/automation.py:
class tagVARIANT(Structure):
...
199 def __del__(self):
200 if self._b_needsfree_:
201 # XXX This does not work. _b_needsfree_ is never
202 # set because the buffer is internal to the object.
203 _VariantClear(self)
204
205 def __repr__(self):
206 if self.vt & VT_BYREF:
207 return "VARIANT(vt=0x%x, byref(%r))" % (self.vt, self[0])
208 return "VARIANT(vt=0x%x, %r)" % (self.vt, self.value)
209
210 @classmethod
211 def from_param(cls, value):
212 if isinstance(value, cls):
213 return value
214 return cls(value)
199 def del(self):
200 if self.b_needsfree:
201 # XXX This does not work. b_needsfree is never
202 # set because the buffer is internal to the object.
203 _VariantClear(self)
Yes! I can confim. After commented:
pass #_VariantClear(self)
comtypes works as expected also for Py 3.8, 3.9, 3.10, 3.11
D:\Py>py -3.8 z_COM.py
10.0
Press a key
33.0
Press a key
C:\Python38\Lib\site-packages\comtypes>copy automation.py automation.py.org
1 file(s) copied.
D:\Py>py -3.7 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
D:\Py>py -3.8 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
D:\Py>py -3.9 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
D:\Py>py -3.10 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
D:\Py>py -3.11 z_COM.py
((10.0, 20.0, 31.4),)
Press a key
((11.0, 22.0, 33.0),)
Press a key
Yes. Seems like a main reason of this bug is a different object lifetime in Py <= 3.7, and Py >= 3.8
so (fortunately) in old Pythons this potential ctypes bug maybe was hidden/masked due to longer lifetime of referenced object?.
Maybe in comtypes will be useful/enough to use (as worarround/fix) pythonapi''s IncRef(obj)/DecRef(obj) ??
This will allow to avoid waiting for the official port and python releases with ev. fix?
@junkmd, can you confirm that this is now fixed in the latest bugfix releases? I believe the merged PRs should have been included in 3.10.10 and 3.11.2.
I have installed Python 3.10.10 and Python 3.11.2 and have run the comtypes tests that failed in the previous versions and have confirmed that they succeed(comtypes issue link).
Activity
karpierz commentedon Dec 8, 2022
Unfortunatelly the bug still exist in the newest (6.12.2022) versions of Python (3.10.9, 3.11.1).
For such code:
we have results:
PS: This is an important/real barrier to upgrading Python to versions newer than 3.7.
michaelDCurran commentedon Dec 8, 2022
karpierz commentedon Dec 8, 2022
@michaelDCurran
The same behaviour.
For such code:
we have results:
PS: py>3.7 gets last cell in the row instead of whole row.
ynkdir commentedon Dec 9, 2022
VARIANT("A1") and VARIANT("C1") are created by from_param() for calling com method.
It seems that line 203 _VariantClear() is called after line 214 soon.
Then, memory is freed before calling com method.
Also, SysAllocStringLen() returns same memory address with "A1" for "C1".
ynkdir commentedon Dec 10, 2022
Here is minimal reproducible code.
karpierz commentedon Dec 10, 2022
@ynkdir
Yes! I can confim. After commented:
pass #_VariantClear(self)
comtypes works as expected also for Py 3.8, 3.9, 3.10, 3.11
Thanks,
Adam
ynkdir commentedon Dec 10, 2022
Perhaps ctypes's StructParam_Type should keep object which copied from.
I am not familiar with python source.
karpierz commentedon Dec 10, 2022
Yes. Seems like a main reason of this bug is a different object lifetime in Py <= 3.7, and Py >= 3.8
so (fortunately) in old Pythons this potential ctypes bug maybe was hidden/masked due to longer lifetime of referenced object?.
Maybe in comtypes will be useful/enough to use (as worarround/fix) pythonapi''s IncRef(obj)/DecRef(obj) ??
This will allow to avoid waiting for the official port and python releases with ev. fix?
from ctypes import py_object, pythonapi
Py_IncRef = pythonapi.Py_IncRef
Py_IncRef.argtypes = [py_object]
Py_IncRef.restype = None
Py_DecRef = pythonapi.Py_DecRef
Py_DecRef.argtypes = [py_object]
Py_DecRef.restype = None
PS: Unfortunately I am also not familiar with Python and ctypes C source code :(
pythongh-99952: [ctypes] fix refcount issues in from_param() result.
gh-99952: [ctypes] fix refcount issues in from_param() result. (#100169)
[3.11] pythongh-99952: [ctypes] fix refcount issues in from_param() r…
[3.11] gh-99952: fix refcount issues in ctypes.Structure from_param()…
[3.11] pythongh-99952: fix refcount issues in ctypes.Structure from_p…
pythongh-99952: [ctypes] fix refcount issues in from_param() result. (p…
[3.10] [3.11] gh-99952: fix refcount issues in ctypes.Structure from_…
zware commentedon Mar 19, 2023
@junkmd, can you confirm that this is now fixed in the latest bugfix releases? I believe the merged PRs should have been included in 3.10.10 and 3.11.2.
junkmd commentedon Mar 20, 2023
I have installed Python 3.10.10 and Python 3.11.2 and have run the
comtypestests that failed in the previous versions and have confirmed that they succeed(comtypesissue link).Thank you.