diff -r 40e8b39199da -r 12b5ea4f89bc Python/getargs.c --- a/Python/getargs.c Sat Dec 10 17:34:46 2016 +0100 +++ b/Python/getargs.c Sat Dec 10 18:15:18 2016 +0100 @@ -741,20 +741,23 @@ } case 'n': /* Py_ssize_t */ + case 'N': /* Optional Py_ssize_t */ { PyObject *iobj; Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); Py_ssize_t ival = -1; - if (float_argument_error(arg)) - RETURN_ERR_OCCURRED; - iobj = PyNumber_Index(arg); - if (iobj != NULL) { - ival = PyLong_AsSsize_t(iobj); - Py_DECREF(iobj); + if (c == 'n' || arg != Py_None) { + if (float_argument_error(arg)) + RETURN_ERR_OCCURRED; + iobj = PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) + RETURN_ERR_OCCURRED; + *p = ival; } - if (ival == -1 && PyErr_Occurred()) - RETURN_ERR_OCCURRED; - *p = ival; break; } case 'l': {/* long int */ @@ -2237,6 +2240,7 @@ case 'L': /* long long */ case 'K': /* long long sized bitfield */ case 'n': /* Py_ssize_t */ + case 'N': /* Optional Py_ssize_t */ case 'f': /* float */ case 'd': /* double */ case 'D': /* complex double */ diff -r 40e8b39199da -r 12b5ea4f89bc Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py Sat Dec 10 17:34:46 2016 +0100 +++ b/Tools/clinic/clinic.py Sat Dec 10 18:15:18 2016 +0100 @@ -2617,10 +2617,13 @@ class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' - default_type = int + default_type = (int, NoneType) format_unit = 'n' c_ignored_default = "0" + def converter_init(self): + if self.default is None: + self.format_unit = 'N' class float_converter(CConverter): type = 'float'