@@ -3647,6 +3647,9 @@ atomic_xgetref(PyObject *obj, PyObject **field)
36473647#endif
36483648}
36493649
3650+ static int
3651+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3652+
36503653
36513654
36523655/*[clinic input]
@@ -3762,14 +3765,27 @@ _ctypes_CFuncPtr_argtypes_set_impl(PyCFuncPtrObject *self, PyObject *value)
37623765{
37633766 PyObject * converters ;
37643767
3768+ PyTypeObject * type = Py_TYPE (self );
3769+ ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3770+
37653771 if (value == NULL || value == Py_None ) {
3772+ /* Verify paramflags again due to constraints with argtypes */
3773+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3774+ return -1 ;
3775+ }
3776+
37663777 atomic_xsetref (& self -> argtypes , NULL );
37673778 atomic_xsetref (& self -> converters , NULL );
37683779 } else {
3769- ctypes_state * st = get_module_state_by_def (Py_TYPE (Py_TYPE (self )));
37703780 converters = converters_from_argtypes (st , value );
37713781 if (!converters )
37723782 return -1 ;
3783+
3784+ /* Verify paramflags again due to constraints with argtypes */
3785+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3786+ Py_DECREF (converters );
3787+ return -1 ;
3788+ }
37733789 atomic_xsetref (& self -> converters , converters );
37743790 Py_INCREF (value );
37753791 atomic_xsetref (& self -> argtypes , value );
@@ -3899,10 +3915,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
38993915
39003916/* Returns 1 on success, 0 on error */
39013917static int
3902- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3918+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
39033919{
39043920 Py_ssize_t i , len ;
3905- PyObject * argtypes ;
39063921
39073922 StgInfo * info ;
39083923 if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3913,9 +3928,11 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
39133928 "abstract class" );
39143929 return 0 ;
39153930 }
3916- argtypes = info -> argtypes ;
3931+ if (argtypes == NULL || argtypes == Py_None ) {
3932+ argtypes = info -> argtypes ;
3933+ }
39173934
3918- if (paramflags == NULL || info -> argtypes == NULL )
3935+ if (paramflags == NULL || argtypes == NULL )
39193936 return 1 ;
39203937
39213938 if (!PyTuple_Check (paramflags )) {
@@ -3925,7 +3942,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
39253942 }
39263943
39273944 len = PyTuple_GET_SIZE (paramflags );
3928- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3945+ if (len != PyTuple_GET_SIZE (argtypes )) {
39293946 PyErr_SetString (PyExc_ValueError ,
39303947 "paramflags must have the same length as argtypes" );
39313948 return 0 ;
@@ -4101,7 +4118,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
41014118#endif
41024119#undef USE_DLERROR
41034120 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4104- if (!_validate_paramflags (st , type , paramflags )) {
4121+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
41054122 Py_DECREF (ftuple );
41064123 return NULL ;
41074124 }
@@ -4145,7 +4162,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
41454162 paramflags = NULL ;
41464163
41474164 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4148- if (!_validate_paramflags (st , type , paramflags )) {
4165+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
41494166 return NULL ;
41504167 }
41514168 self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments