@@ -3341,25 +3341,23 @@ sock_setsockopt(PyObject *self, PyObject *args)
33413341 unsigned int optlen ;
33423342 PyObject * optval ;
33433343
3344+ if (!PyArg_ParseTuple (args , "iiO|I:setsockopt" ,
3345+ & level , & optname , & optval , & optlen )) {
3346+ return NULL ;
3347+ }
3348+
33443349 arglen = PyTuple_Size (args );
3345- switch (arglen ) {
3346- case 3 :
3347- if (!PyArg_ParseTuple (args , "iiO:setsockopt" ,
3348- & level , & optname , & optval )) {
3349- return NULL ;
3350- }
3351- break ;
3352- case 4 :
3353- if (!PyArg_ParseTuple (args , "iiO!I:setsockopt" ,
3354- & level , & optname , Py_TYPE (Py_None ), & optval , & optlen )) {
3355- return NULL ;
3356- }
3357- break ;
3358- default :
3359- PyErr_Format (PyExc_TypeError ,
3360- "setsockopt() takes 3 or 4 arguments (%zd given)" ,
3361- arglen );
3362- return NULL ;
3350+ if (arglen == 3 && optval == Py_None ) {
3351+ PyErr_Format (PyExc_TypeError ,
3352+ "setsockopt() take 4 arguments when socket option is None (%zd given)" ,
3353+ arglen );
3354+ return NULL ;
3355+ }
3356+ if (arglen == 4 && optval != Py_None ) {
3357+ PyErr_Format (PyExc_TypeError ,
3358+ "setsockopt() argument 3 must be NoneType, not %s" ,
3359+ Py_TYPE (optval )-> tp_name );
3360+ return NULL ;
33633361 }
33643362
33653363#ifdef AF_VSOCK
@@ -3397,14 +3395,8 @@ sock_setsockopt(PyObject *self, PyObject *args)
33973395 goto done ;
33983396 }
33993397
3400- /* setsockopt(level, opt, None, flag ) */
3398+ /* setsockopt(level, opt, None, optlen ) */
34013399 if (optval == Py_None ) {
3402- if (arglen != 4 ) {
3403- PyErr_Format (PyExc_TypeError ,
3404- "setsockopt() take 4 arguments when socket option is None (%zd given)" ,
3405- arglen );
3406- return NULL ;
3407- }
34083400 assert (sizeof (socklen_t ) >= sizeof (unsigned int ));
34093401 res = setsockopt (get_sock_fd (s ), level , optname ,
34103402 NULL , (socklen_t )optlen );
@@ -3425,7 +3417,7 @@ sock_setsockopt(PyObject *self, PyObject *args)
34253417 return NULL ;
34263418 }
34273419 res = setsockopt (get_sock_fd (s ), level , optname ,
3428- buffer .buf , (int )buffer .len );
3420+ buffer .buf , (int )buffer .len );
34293421#else
34303422 res = setsockopt (get_sock_fd (s ), level , optname , buffer .buf , buffer .len );
34313423#endif
@@ -3434,7 +3426,8 @@ sock_setsockopt(PyObject *self, PyObject *args)
34343426 }
34353427
34363428 PyErr_Format (PyExc_TypeError ,
3437- "socket option should be integer, bytes-like object or None" );
3429+ "socket option should be int, bytes-like object or None (got %s)" ,
3430+ Py_TYPE (optval )-> tp_name );
34383431 return NULL ;
34393432
34403433done :
0 commit comments