@@ -151,6 +151,95 @@ StringToChars(PyObject *object, PyObject **todecref)
151151 return (char_u * ) p ;
152152}
153153
154+ #define NUMBER_LONG 1
155+ #define NUMBER_INT 2
156+ #define NUMBER_NATURAL 4
157+ #define NUMBER_UNSIGNED 8
158+
159+ static int
160+ NumberToLong (PyObject * obj , long * result , int flags )
161+ {
162+ #if PY_MAJOR_VERSION < 3
163+ if (PyInt_Check (obj ))
164+ {
165+ * result = PyInt_AsLong (obj );
166+ if (PyErr_Occurred ())
167+ return -1 ;
168+ }
169+ else
170+ #endif
171+ if (PyLong_Check (obj ))
172+ {
173+ * result = PyLong_AsLong (obj );
174+ if (PyErr_Occurred ())
175+ return -1 ;
176+ }
177+ else if (PyNumber_Check (obj ))
178+ {
179+ PyObject * num ;
180+
181+ if (!(num = PyNumber_Long (obj )))
182+ return -1 ;
183+
184+ * result = PyLong_AsLong (num );
185+
186+ Py_DECREF (num );
187+
188+ if (PyErr_Occurred ())
189+ return -1 ;
190+ }
191+ else
192+ {
193+ PyErr_FORMAT (PyExc_TypeError ,
194+ #if PY_MAJOR_VERSION < 3
195+ "expected int(), long() or something supporting "
196+ "coercing to long(), but got %s"
197+ #else
198+ "expected int() or something supporting coercing to int(), "
199+ "but got %s"
200+ #endif
201+ , Py_TYPE_NAME (obj ));
202+ return -1 ;
203+ }
204+
205+ if (flags & NUMBER_INT )
206+ {
207+ if (* result > INT_MAX )
208+ {
209+ PyErr_SET_STRING (PyExc_OverflowError ,
210+ "value is too large to fit into C int type" );
211+ return -1 ;
212+ }
213+ else if (* result < INT_MIN )
214+ {
215+ PyErr_SET_STRING (PyExc_OverflowError ,
216+ "value is too small to fit into C int type" );
217+ return -1 ;
218+ }
219+ }
220+
221+ if (flags & NUMBER_NATURAL )
222+ {
223+ if (* result <= 0 )
224+ {
225+ PyErr_SET_STRING (PyExc_ValueError ,
226+ "number must be greater then zero" );
227+ return -1 ;
228+ }
229+ }
230+ else if (flags & NUMBER_UNSIGNED )
231+ {
232+ if (* result < 0 )
233+ {
234+ PyErr_SET_STRING (PyExc_ValueError ,
235+ "number must be greater or equal to zero" );
236+ return -1 ;
237+ }
238+ }
239+
240+ return 0 ;
241+ }
242+
154243 static int
155244add_string (PyObject * list , char * s )
156245{
@@ -243,13 +332,8 @@ OutputSetattr(OutputObject *self, char *name, PyObject *val)
243332
244333 if (strcmp (name , "softspace" ) == 0 )
245334 {
246- if (!PyInt_Check (val ))
247- {
248- PyErr_SET_STRING (PyExc_TypeError , "softspace must be an integer" );
335+ if (NumberToLong (val , & (self -> softspace ), NUMBER_UNSIGNED ))
249336 return -1 ;
250- }
251-
252- self -> softspace = PyInt_AsLong (val );
253337 return 0 ;
254338 }
255339
@@ -2839,23 +2923,15 @@ OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
28392923 }
28402924 else if (flags & SOPT_NUM )
28412925 {
2842- int val ;
2926+ long val ;
28432927
2844- #if PY_MAJOR_VERSION < 3
2845- if (PyInt_Check (valObject ))
2846- val = PyInt_AsLong (valObject );
2847- else
2848- #endif
2849- if (PyLong_Check (valObject ))
2850- val = PyLong_AsLong (valObject );
2851- else
2928+ if (NumberToLong (valObject , & val , NUMBER_INT ))
28522929 {
2853- PyErr_SET_STRING (PyExc_TypeError , "object must be integer" );
28542930 Py_XDECREF (todecref );
28552931 return -1 ;
28562932 }
28572933
2858- r = set_option_value_for (key , val , NULL , opt_flags ,
2934+ r = set_option_value_for (key , ( int ) val , NULL , opt_flags ,
28592935 self -> opt_type , self -> from );
28602936 }
28612937 else
@@ -3265,10 +3341,10 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
32653341 }
32663342 else if (strcmp (name , "height" ) == 0 )
32673343 {
3268- int height ;
3344+ long height ;
32693345 win_T * savewin ;
32703346
3271- if (! PyArg_Parse (val , "i" , & height ))
3347+ if (NumberToLong (val , & height , NUMBER_INT ))
32723348 return -1 ;
32733349
32743350#ifdef FEAT_GUI
@@ -3278,7 +3354,7 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
32783354 curwin = self -> win ;
32793355
32803356 VimTryStart ();
3281- win_setheight (height );
3357+ win_setheight (( int ) height );
32823358 curwin = savewin ;
32833359 if (VimTryEnd ())
32843360 return -1 ;
@@ -3288,10 +3364,10 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
32883364#ifdef FEAT_VERTSPLIT
32893365 else if (strcmp (name , "width ") == 0 )
32903366 {
3291- int width ;
3367+ long width ;
32923368 win_T * savewin ;
32933369
3294- if (! PyArg_Parse (val , "i" , & width ))
3370+ if (NumberToLong (val , & width , NUMBER_INT ))
32953371 return -1 ;
32963372
32973373#ifdef FEAT_GUI
@@ -3301,7 +3377,7 @@ WindowSetattr(WindowObject *self, char *name, PyObject *val)
33013377 curwin = self -> win ;
33023378
33033379 VimTryStart ();
3304- win_setwidth (width );
3380+ win_setwidth (( int ) width );
33053381 curwin = savewin ;
33063382 if (VimTryEnd ())
33073383 return -1 ;
@@ -4555,22 +4631,12 @@ BufMapLength(PyObject *self UNUSED)
45554631BufMapItem (PyObject * self UNUSED , PyObject * keyObject )
45564632{
45574633 buf_T * b ;
4558- int bnr ;
4634+ long bnr ;
45594635
4560- #if PY_MAJOR_VERSION < 3
4561- if (PyInt_Check (keyObject ))
4562- bnr = PyInt_AsLong (keyObject );
4563- else
4564- #endif
4565- if (PyLong_Check (keyObject ))
4566- bnr = PyLong_AsLong (keyObject );
4567- else
4568- {
4569- PyErr_SET_STRING (PyExc_TypeError , "key must be integer" );
4636+ if (NumberToLong (keyObject , & bnr , NUMBER_INT |NUMBER_NATURAL ))
45704637 return NULL ;
4571- }
45724638
4573- b = buflist_findnr (bnr );
4639+ b = buflist_findnr (( int ) bnr );
45744640
45754641 if (b )
45764642 return BufferNew (b );
@@ -5345,12 +5411,16 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
53455411 {
53465412 tv -> v_type = VAR_NUMBER ;
53475413 tv -> vval .v_number = (varnumber_T ) PyInt_AsLong (obj );
5414+ if (PyErr_Occurred ())
5415+ return -1 ;
53485416 }
53495417#endif
53505418 else if (PyLong_Check (obj ))
53515419 {
53525420 tv -> v_type = VAR_NUMBER ;
53535421 tv -> vval .v_number = (varnumber_T ) PyLong_AsLong (obj );
5422+ if (PyErr_Occurred ())
5423+ return -1 ;
53545424 }
53555425 else if (PyDict_Check (obj ))
53565426 return convert_dl (obj , tv , pydict_to_tv , lookup_dict );
@@ -5367,6 +5437,18 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
53675437 return convert_dl (obj , tv , pyseq_to_tv , lookup_dict );
53685438 else if (PyMapping_Check (obj ))
53695439 return convert_dl (obj , tv , pymap_to_tv , lookup_dict );
5440+ else if (PyNumber_Check (obj ))
5441+ {
5442+ PyObject * num ;
5443+
5444+ if (!(num = PyNumber_Long (obj )))
5445+ return -1 ;
5446+
5447+ tv -> v_type = VAR_NUMBER ;
5448+ tv -> vval .v_number = (varnumber_T ) PyLong_AsLong (num );
5449+
5450+ Py_DECREF (num );
5451+ }
53705452 else
53715453 {
53725454 PyErr_FORMAT (PyExc_TypeError ,
0 commit comments