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
Automatic upcast does not occur for custom classes #74877
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2017-06-17.19:29:40.309>labels= ['ctypes', 'type-bug']
title='Automatic upcast does not occur for custom classes'updated_at=<Date2017-06-17.19:39:41.287>user='https://bugs.python.org/rharke'
I have noticed that the automatic upcast mechanism which works for
standard ctypes types does not appear to work for custom types with
_as_parameter_ defined.
Consider the following example (written for Mac OS X but just change
the LoadLibrary call to test on a different OS):
# -- begin --fromctypesimport*libc=cdll.LoadLibrary('/usr/lib/libc.dylib')
classBase(Structure): passclassDerived(Base): passclassWrapper(object): passprintf=libc.printfprintf.argtypes= [ c_char_p, POINTER(Base) ]
printf.restype=c_intderived=Derived()
derived_ptr=pointer(derived)
derived_ptr_wrapper=Wrapper()
derived_ptr_wrapper._as_parameter_=pointer(derived)
# Case 1 WORKS: Derived* is automatically upcast to Base* and passed to# printfprintf(b'%p\n', derived_ptr)
# Case 2 WORKS: The Wrapper can be explicitly upcast to a Base* and# passed to printfprintf(b'%p\n', cast(derived_ptr_wrapper, POINTER(Base)))
# Case 3 FAILS: Automatic upcast does NOT happen with the value in the# Wrapper: 'expected LP_Base instance instead of# LP_Derived'printf(b'%p\n', derived_ptr_wrapper)
# -- end --
Here we have two types, Base which is a ctypes Structure, and Derived
which derives from Base. A pointer to Derived can be passed to a
function that expects a pointer to Base, and it will automatically be
upcast.
However, once the Wrapper type is introduced, which simply holds a
pointer to Derived in its _as_parameter_ attribute, the automatic
upcast no longer occurs. A manual upcast works, though.
I believe this may be related to bpo-27803, but that is talking about
byref() whereas this is related to cast(). Perhaps the internal
mechanism is the same; certainly it sounds like a similar problem.
I've tested this in Python 2.7 and 3.6, and the result is the same.
Not sure if this is a bug or an enhancement request- filing it as
"behavior" for now since to me, this is something that I expected to
implicitly work.
Activity
rharke commentedon Jun 17, 2017
I have noticed that the automatic upcast mechanism which works for
standard ctypes types does not appear to work for custom types with
_as_parameter_ defined.
Consider the following example (written for Mac OS X but just change
the LoadLibrary call to test on a different OS):
Here we have two types, Base which is a ctypes Structure, and Derived
which derives from Base. A pointer to Derived can be passed to a
function that expects a pointer to Base, and it will automatically be
upcast.
However, once the Wrapper type is introduced, which simply holds a
pointer to Derived in its _as_parameter_ attribute, the automatic
upcast no longer occurs. A manual upcast works, though.
I believe this may be related to bpo-27803, but that is talking about
byref() whereas this is related to cast(). Perhaps the internal
mechanism is the same; certainly it sounds like a similar problem.
I've tested this in Python 2.7 and 3.6, and the result is the same.
Not sure if this is a bug or an enhancement request- filing it as
"behavior" for now since to me, this is something that I expected to
implicitly work.
Thanks! - Ranger Harke.
ZeroIntensity commentedon Oct 19, 2026
Same root cause as #71990, so #159763 should fix it.