@@ -3634,6 +3634,9 @@ atomic_xgetref(PyObject *obj, PyObject **field)
36343634#endif
36353635}
36363636
3637+ static int
3638+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3639+
36373640
36383641
36393642/*[clinic input]
@@ -3747,16 +3750,22 @@ static int
37473750_ctypes_CFuncPtr_argtypes_set_impl (PyCFuncPtrObject * self , PyObject * value )
37483751/*[clinic end generated code: output=596a36e2ae89d7d1 input=c4627573e980aa8b]*/
37493752{
3750- PyObject * converters ;
3751-
37523753 if (value == NULL || value == Py_None ) {
37533754 atomic_xsetref (& self -> argtypes , NULL );
37543755 atomic_xsetref (& self -> converters , NULL );
37553756 } else {
3756- ctypes_state * st = get_module_state_by_def (Py_TYPE (Py_TYPE (self )));
3757- converters = converters_from_argtypes (st , value );
3757+ PyTypeObject * type = Py_TYPE (self );
3758+ ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3759+
3760+ PyObject * converters = converters_from_argtypes (st , value );
37583761 if (!converters )
37593762 return -1 ;
3763+
3764+ /* Verify paramflags again due to constraints with argtypes */
3765+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3766+ Py_DECREF (converters );
3767+ return -1 ;
3768+ }
37603769 atomic_xsetref (& self -> converters , converters );
37613770 Py_INCREF (value );
37623771 atomic_xsetref (& self -> argtypes , value );
@@ -3886,10 +3895,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
38863895
38873896/* Returns 1 on success, 0 on error */
38883897static int
3889- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3898+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
38903899{
38913900 Py_ssize_t i , len ;
3892- PyObject * argtypes ;
38933901
38943902 StgInfo * info ;
38953903 if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3900,10 +3908,13 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
39003908 "abstract class" );
39013909 return 0 ;
39023910 }
3903- argtypes = info -> argtypes ;
3911+ if (argtypes == NULL ) {
3912+ argtypes = info -> argtypes ;
3913+ }
39043914
3905- if (paramflags == NULL || info -> argtypes == NULL )
3915+ if (paramflags == NULL || argtypes == NULL ) {
39063916 return 1 ;
3917+ }
39073918
39083919 if (!PyTuple_Check (paramflags )) {
39093920 PyErr_SetString (PyExc_TypeError ,
@@ -3912,7 +3923,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
39123923 }
39133924
39143925 len = PyTuple_GET_SIZE (paramflags );
3915- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3926+ if (len != PyTuple_GET_SIZE (argtypes )) {
39163927 PyErr_SetString (PyExc_ValueError ,
39173928 "paramflags must have the same length as argtypes" );
39183929 return 0 ;
@@ -4088,7 +4099,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
40884099#endif
40894100#undef USE_DLERROR
40904101 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4091- if (!_validate_paramflags (st , type , paramflags )) {
4102+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
40924103 Py_DECREF (ftuple );
40934104 return NULL ;
40944105 }
@@ -4132,7 +4143,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
41324143 paramflags = NULL ;
41334144
41344145 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4135- if (!_validate_paramflags (st , type , paramflags )) {
4146+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
41364147 return NULL ;
41374148 }
41384149 self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments