xref: /vim-8.2.3635/src/if_py_both.h (revision 94688b8a)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 /*
10  * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
11  * Pavlov.
12  *
13  * Common code for if_python.c and if_python3.c.
14  */
15 
16 #ifdef __BORLANDC__
17 /* Disable Warning W8060: Possibly incorrect assignment in function ... */
18 # pragma warn -8060
19 #endif
20 
21 static char_u e_py_systemexit[]	= "E880: Can't handle SystemExit of %s exception in vim";
22 
23 #if PY_VERSION_HEX < 0x02050000
24 typedef int Py_ssize_t;  /* Python 2.4 and earlier don't have this type. */
25 #endif
26 
27 #define ENC_OPT ((char *)p_enc)
28 #define DOPY_FUNC "_vim_pydo"
29 
30 static const char *vim_special_path = "_vim_path_";
31 
32 #define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
33 #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
34 #define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
35 #define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg)
36 #define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2)
37 #define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg)
38 
39 #define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
40 	? "(NULL)" \
41 	: obj->ob_type->tp_name)
42 
43 #define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
44 					    N_("empty keys are not allowed"))
45 #define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
46 #define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
47 #define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
48 #define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
49 #define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
50 #define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
51 #define RAISE_KEY_ADD_FAIL(key) \
52     PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
53 #define RAISE_INVALID_INDEX_TYPE(idx) \
54     PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
55 	    Py_TYPE_NAME(idx));
56 
57 #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
58 #define INVALID_WINDOW_VALUE ((win_T *)(-1))
59 #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
60 
61 typedef void (*rangeinitializer)(void *);
62 typedef void (*runner)(const char *, void *
63 #ifdef PY_CAN_RECURSE
64 	, PyGILState_STATE *
65 #endif
66 	);
67 
68 static int ConvertFromPyObject(PyObject *, typval_T *);
69 static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
70 static int ConvertFromPyMapping(PyObject *, typval_T *);
71 static int ConvertFromPySequence(PyObject *, typval_T *);
72 static PyObject *WindowNew(win_T *, tabpage_T *);
73 static PyObject *BufferNew (buf_T *);
74 static PyObject *LineToString(const char *);
75 
76 static PyInt RangeStart;
77 static PyInt RangeEnd;
78 
79 static PyObject *globals;
80 
81 static PyObject *py_chdir;
82 static PyObject *py_fchdir;
83 static PyObject *py_getcwd;
84 static PyObject *vim_module;
85 static PyObject *vim_special_path_object;
86 
87 #if PY_VERSION_HEX >= 0x030700f0
88 static PyObject *py_find_spec;
89 #else
90 static PyObject *py_find_module;
91 static PyObject *py_load_module;
92 #endif
93 
94 static PyObject *VimError;
95 
96 /*
97  * obtain a lock on the Vim data structures
98  */
99     static void
100 Python_Lock_Vim(void)
101 {
102 }
103 
104 /*
105  * release a lock on the Vim data structures
106  */
107     static void
108 Python_Release_Vim(void)
109 {
110 }
111 
112 /*
113  * The "todecref" argument holds a pointer to PyObject * that must be
114  * DECREF'ed after returned char_u * is no longer needed or NULL if all what
115  * was needed to generate returned value is object.
116  *
117  * Use Py_XDECREF to decrement reference count.
118  */
119     static char_u *
120 StringToChars(PyObject *obj, PyObject **todecref)
121 {
122     char_u	*str;
123 
124     if (PyBytes_Check(obj))
125     {
126 
127 	if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
128 		|| str == NULL)
129 	    return NULL;
130 
131 	*todecref = NULL;
132     }
133     else if (PyUnicode_Check(obj))
134     {
135 	PyObject	*bytes;
136 
137 	if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
138 	    return NULL;
139 
140 	if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
141 		|| str == NULL)
142 	{
143 	    Py_DECREF(bytes);
144 	    return NULL;
145 	}
146 
147 	*todecref = bytes;
148     }
149     else
150     {
151 #if PY_MAJOR_VERSION < 3
152 	PyErr_FORMAT(PyExc_TypeError,
153 		N_("expected str() or unicode() instance, but got %s"),
154 		Py_TYPE_NAME(obj));
155 #else
156 	PyErr_FORMAT(PyExc_TypeError,
157 		N_("expected bytes() or str() instance, but got %s"),
158 		Py_TYPE_NAME(obj));
159 #endif
160 	return NULL;
161     }
162 
163     return (char_u *) str;
164 }
165 
166 #define NUMBER_LONG     1
167 #define NUMBER_INT      2
168 #define NUMBER_NATURAL  4
169 #define NUMBER_UNSIGNED 8
170 
171     static int
172 NumberToLong(PyObject *obj, long *result, int flags)
173 {
174 #if PY_MAJOR_VERSION < 3
175     if (PyInt_Check(obj))
176     {
177 	*result = PyInt_AsLong(obj);
178 	if (PyErr_Occurred())
179 	    return -1;
180     }
181     else
182 #endif
183     if (PyLong_Check(obj))
184     {
185 	*result = PyLong_AsLong(obj);
186 	if (PyErr_Occurred())
187 	    return -1;
188     }
189     else if (PyNumber_Check(obj))
190     {
191 	PyObject	*num;
192 
193 	if (!(num = PyNumber_Long(obj)))
194 	    return -1;
195 
196 	*result = PyLong_AsLong(num);
197 
198 	Py_DECREF(num);
199 
200 	if (PyErr_Occurred())
201 	    return -1;
202     }
203     else
204     {
205 #if PY_MAJOR_VERSION < 3
206 	PyErr_FORMAT(PyExc_TypeError,
207 		N_("expected int(), long() or something supporting "
208 		   "coercing to long(), but got %s"),
209 		Py_TYPE_NAME(obj));
210 #else
211 	PyErr_FORMAT(PyExc_TypeError,
212 		N_("expected int() or something supporting coercing to int(), "
213 		   "but got %s"),
214 		Py_TYPE_NAME(obj));
215 #endif
216 	return -1;
217     }
218 
219     if (flags & NUMBER_INT)
220     {
221 	if (*result > INT_MAX)
222 	{
223 	    PyErr_SET_STRING(PyExc_OverflowError,
224 		    N_("value is too large to fit into C int type"));
225 	    return -1;
226 	}
227 	else if (*result < INT_MIN)
228 	{
229 	    PyErr_SET_STRING(PyExc_OverflowError,
230 		    N_("value is too small to fit into C int type"));
231 	    return -1;
232 	}
233     }
234 
235     if (flags & NUMBER_NATURAL)
236     {
237 	if (*result <= 0)
238 	{
239 	    PyErr_SET_STRING(PyExc_ValueError,
240 		    N_("number must be greater than zero"));
241 	    return -1;
242 	}
243     }
244     else if (flags & NUMBER_UNSIGNED)
245     {
246 	if (*result < 0)
247 	{
248 	    PyErr_SET_STRING(PyExc_ValueError,
249 		    N_("number must be greater or equal to zero"));
250 	    return -1;
251 	}
252     }
253 
254     return 0;
255 }
256 
257     static int
258 add_string(PyObject *list, char *s)
259 {
260     PyObject	*string;
261 
262     if (!(string = PyString_FromString(s)))
263 	return -1;
264 
265     if (PyList_Append(list, string))
266     {
267 	Py_DECREF(string);
268 	return -1;
269     }
270 
271     Py_DECREF(string);
272     return 0;
273 }
274 
275     static PyObject *
276 ObjectDir(PyObject *self, char **attributes)
277 {
278     PyMethodDef	*method;
279     char	**attr;
280     PyObject	*ret;
281 
282     if (!(ret = PyList_New(0)))
283 	return NULL;
284 
285     if (self)
286 	for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
287 	    if (add_string(ret, (char *)method->ml_name))
288 	    {
289 		Py_DECREF(ret);
290 		return NULL;
291 	    }
292 
293     for (attr = attributes ; *attr ; ++attr)
294 	if (add_string(ret, *attr))
295 	{
296 	    Py_DECREF(ret);
297 	    return NULL;
298 	}
299 
300 #if PY_MAJOR_VERSION < 3
301     if (add_string(ret, "__members__"))
302     {
303 	Py_DECREF(ret);
304 	return NULL;
305     }
306 #endif
307 
308     return ret;
309 }
310 
311 /* Output buffer management
312  */
313 
314 /* Function to write a line, points to either msg() or emsg(). */
315 typedef void (*writefn)(char_u *);
316 
317 static PyTypeObject OutputType;
318 
319 typedef struct
320 {
321     PyObject_HEAD
322     long softspace;
323     long error;
324 } OutputObject;
325 
326 static char *OutputAttrs[] = {
327     "softspace",
328     NULL
329 };
330 
331     static PyObject *
332 OutputDir(PyObject *self)
333 {
334     return ObjectDir(self, OutputAttrs);
335 }
336 
337     static int
338 OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
339 {
340     if (valObject == NULL)
341     {
342 	PyErr_SET_STRING(PyExc_AttributeError,
343 		N_("can't delete OutputObject attributes"));
344 	return -1;
345     }
346 
347     if (strcmp(name, "softspace") == 0)
348     {
349 	if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
350 	    return -1;
351 	return 0;
352     }
353 
354     PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
355     return -1;
356 }
357 
358 /* Buffer IO, we write one whole line at a time. */
359 static garray_T io_ga = {0, 0, 1, 80, NULL};
360 static writefn old_fn = NULL;
361 
362     static void
363 PythonIO_Flush(void)
364 {
365     if (old_fn != NULL && io_ga.ga_len > 0)
366     {
367 	((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
368 	old_fn((char_u *)io_ga.ga_data);
369     }
370     io_ga.ga_len = 0;
371 }
372 
373     static void
374 writer(writefn fn, char_u *str, PyInt n)
375 {
376     char_u *ptr;
377 
378     /* Flush when switching output function. */
379     if (fn != old_fn)
380 	PythonIO_Flush();
381     old_fn = fn;
382 
383     /* Write each NL separated line.  Text after the last NL is kept for
384      * writing later. */
385     while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
386     {
387 	PyInt len = ptr - str;
388 
389 	if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
390 	    break;
391 
392 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
393 	((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
394 	fn((char_u *)io_ga.ga_data);
395 	str = ptr + 1;
396 	n -= len + 1;
397 	io_ga.ga_len = 0;
398     }
399 
400     /* Put the remaining text into io_ga for later printing. */
401     if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
402     {
403 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
404 	io_ga.ga_len += (int)n;
405     }
406 }
407 
408     static int
409 write_output(OutputObject *self, PyObject *string)
410 {
411     Py_ssize_t	len = 0;
412     char	*str = NULL;
413     int		error = self->error;
414 
415     if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
416 	return -1;
417 
418     Py_BEGIN_ALLOW_THREADS
419     Python_Lock_Vim();
420     writer((writefn)(error ? emsg : msg), (char_u *)str, len);
421     Python_Release_Vim();
422     Py_END_ALLOW_THREADS
423     PyMem_Free(str);
424 
425     return 0;
426 }
427 
428     static PyObject *
429 OutputWrite(OutputObject *self, PyObject *string)
430 {
431     if (write_output(self, string))
432 	return NULL;
433 
434     Py_INCREF(Py_None);
435     return Py_None;
436 }
437 
438     static PyObject *
439 OutputWritelines(OutputObject *self, PyObject *seq)
440 {
441     PyObject	*iterator;
442     PyObject	*item;
443 
444     if (!(iterator = PyObject_GetIter(seq)))
445 	return NULL;
446 
447     while ((item = PyIter_Next(iterator)))
448     {
449 	if (write_output(self, item))
450 	{
451 	    Py_DECREF(iterator);
452 	    Py_DECREF(item);
453 	    return NULL;
454 	}
455 	Py_DECREF(item);
456     }
457 
458     Py_DECREF(iterator);
459 
460     /* Iterator may have finished due to an exception */
461     if (PyErr_Occurred())
462 	return NULL;
463 
464     Py_INCREF(Py_None);
465     return Py_None;
466 }
467 
468     static PyObject *
469 AlwaysNone(PyObject *self UNUSED)
470 {
471     /* do nothing */
472     Py_INCREF(Py_None);
473     return Py_None;
474 }
475 
476     static PyObject *
477 AlwaysFalse(PyObject *self UNUSED)
478 {
479     /* do nothing */
480     PyObject	*ret = Py_False;
481     Py_INCREF(ret);
482     return ret;
483 }
484 
485     static PyObject *
486 AlwaysTrue(PyObject *self UNUSED)
487 {
488     /* do nothing */
489     PyObject	*ret = Py_True;
490     Py_INCREF(ret);
491     return ret;
492 }
493 
494 /***************/
495 
496 static struct PyMethodDef OutputMethods[] = {
497     /* name,	    function,				calling,	doc */
498     {"write",	    (PyCFunction)OutputWrite,		METH_O,		""},
499     {"writelines",  (PyCFunction)OutputWritelines,	METH_O,		""},
500     {"flush",	    (PyCFunction)AlwaysNone,		METH_NOARGS,	""},
501     {"close",	    (PyCFunction)AlwaysNone,		METH_NOARGS,	""},
502     {"isatty",	    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
503     {"readable",    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
504     {"seekable",    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
505     {"writable",    (PyCFunction)AlwaysTrue,		METH_NOARGS,	""},
506     {"closed",      (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
507     {"__dir__",	    (PyCFunction)OutputDir,		METH_NOARGS,	""},
508     { NULL,	    NULL,				0,		NULL}
509 };
510 
511 static OutputObject Output =
512 {
513     PyObject_HEAD_INIT(&OutputType)
514     0,
515     0
516 };
517 
518 static OutputObject Error =
519 {
520     PyObject_HEAD_INIT(&OutputType)
521     0,
522     1
523 };
524 
525     static int
526 PythonIO_Init_io(void)
527 {
528     if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
529 	return -1;
530     if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
531 	return -1;
532 
533     if (PyErr_Occurred())
534     {
535 	emsg(_("E264: Python: Error initialising I/O objects"));
536 	return -1;
537     }
538 
539     return 0;
540 }
541 
542 #if PY_VERSION_HEX < 0x030700f0
543 static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
544 
545 typedef struct
546 {
547     PyObject_HEAD
548     char	*fullname;
549     PyObject	*result;
550 } LoaderObject;
551 static PyTypeObject LoaderType;
552 
553     static void
554 LoaderDestructor(LoaderObject *self)
555 {
556     vim_free(self->fullname);
557     Py_XDECREF(self->result);
558     DESTRUCTOR_FINISH(self);
559 }
560 
561     static PyObject *
562 LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
563 {
564     char	*fullname = self->fullname;
565     PyObject	*result = self->result;
566     PyObject	*module;
567 
568     if (!fullname)
569     {
570 	module = result ? result : Py_None;
571 	Py_INCREF(module);
572 	return module;
573     }
574 
575     module = call_load_module(fullname, (int)STRLEN(fullname), result);
576 
577     self->fullname = NULL;
578     self->result = module;
579 
580     vim_free(fullname);
581     Py_DECREF(result);
582 
583     if (!module)
584     {
585 	if (PyErr_Occurred())
586 	    return NULL;
587 
588 	Py_INCREF(Py_None);
589 	return Py_None;
590     }
591 
592     Py_INCREF(module);
593     return module;
594 }
595 
596 static struct PyMethodDef LoaderMethods[] = {
597     /* name,	    function,				calling,	doc */
598     {"load_module", (PyCFunction)LoaderLoadModule,	METH_VARARGS,	""},
599     { NULL,	    NULL,				0,		NULL}
600 };
601 #endif
602 
603 /* Check to see whether a Vim error has been reported, or a keyboard
604  * interrupt has been detected.
605  */
606 
607     static void
608 VimTryStart(void)
609 {
610     ++trylevel;
611 }
612 
613     static int
614 VimTryEnd(void)
615 {
616     --trylevel;
617     /* Without this it stops processing all subsequent Vim script commands and
618      * generates strange error messages if I e.g. try calling Test() in a cycle
619      */
620     did_emsg = FALSE;
621     /* Keyboard interrupt should be preferred over anything else */
622     if (got_int)
623     {
624 	if (did_throw)
625 	    discard_current_exception();
626 	got_int = FALSE;
627 	PyErr_SetNone(PyExc_KeyboardInterrupt);
628 	return -1;
629     }
630     else if (msg_list != NULL && *msg_list != NULL)
631     {
632 	int	should_free;
633 	char	*msg;
634 
635 	msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free);
636 
637 	if (msg == NULL)
638 	{
639 	    PyErr_NoMemory();
640 	    return -1;
641 	}
642 
643 	PyErr_SetVim(msg);
644 
645 	free_global_msglist();
646 
647 	if (should_free)
648 	    vim_free(msg);
649 
650 	return -1;
651     }
652     else if (!did_throw)
653 	return (PyErr_Occurred() ? -1 : 0);
654     /* Python exception is preferred over vim one; unlikely to occur though */
655     else if (PyErr_Occurred())
656     {
657 	discard_current_exception();
658 	return -1;
659     }
660     /* Finally transform Vim script exception to python one */
661     else
662     {
663 	PyErr_SetVim((char *)current_exception->value);
664 	discard_current_exception();
665 	return -1;
666     }
667 }
668 
669     static int
670 VimCheckInterrupt(void)
671 {
672     if (got_int)
673     {
674 	PyErr_SetNone(PyExc_KeyboardInterrupt);
675 	return 1;
676     }
677     return 0;
678 }
679 
680 /* Vim module - Implementation
681  */
682 
683     static PyObject *
684 VimCommand(PyObject *self UNUSED, PyObject *string)
685 {
686     char_u	*cmd;
687     PyObject	*ret;
688     PyObject	*todecref;
689 
690     if (!(cmd = StringToChars(string, &todecref)))
691 	return NULL;
692 
693     Py_BEGIN_ALLOW_THREADS
694     Python_Lock_Vim();
695 
696     VimTryStart();
697     do_cmdline_cmd(cmd);
698     update_screen(VALID);
699 
700     Python_Release_Vim();
701     Py_END_ALLOW_THREADS
702 
703     if (VimTryEnd())
704 	ret = NULL;
705     else
706 	ret = Py_None;
707 
708     Py_XINCREF(ret);
709     Py_XDECREF(todecref);
710     return ret;
711 }
712 
713 /*
714  * Function to translate a typval_T into a PyObject; this will recursively
715  * translate lists/dictionaries into their Python equivalents.
716  *
717  * The depth parameter is to avoid infinite recursion, set it to 1 when
718  * you call VimToPython.
719  */
720     static PyObject *
721 VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
722 {
723     PyObject	*ret;
724     PyObject	*newObj;
725     char	ptrBuf[sizeof(void *) * 2 + 3];
726 
727     /* Avoid infinite recursion */
728     if (depth > 100)
729     {
730 	Py_INCREF(Py_None);
731 	ret = Py_None;
732 	return ret;
733     }
734 
735     /* Check if we run into a recursive loop.  The item must be in lookup_dict
736      * then and we can use it again. */
737     if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
738 	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
739     {
740 	sprintf(ptrBuf, "%p",
741 		our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
742 					   : (void *)our_tv->vval.v_dict);
743 
744 	if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
745 	{
746 	    Py_INCREF(ret);
747 	    return ret;
748 	}
749     }
750 
751     if (our_tv->v_type == VAR_STRING)
752 	ret = PyString_FromString(our_tv->vval.v_string == NULL
753 					? "" : (char *)our_tv->vval.v_string);
754     else if (our_tv->v_type == VAR_NUMBER)
755     {
756 	char buf[NUMBUFLEN];
757 
758 	/* For backwards compatibility numbers are stored as strings. */
759 	sprintf(buf, "%ld", (long)our_tv->vval.v_number);
760 	ret = PyString_FromString((char *)buf);
761     }
762 # ifdef FEAT_FLOAT
763     else if (our_tv->v_type == VAR_FLOAT)
764     {
765 	char buf[NUMBUFLEN];
766 
767 	sprintf(buf, "%f", our_tv->vval.v_float);
768 	ret = PyString_FromString((char *)buf);
769     }
770 # endif
771     else if (our_tv->v_type == VAR_LIST)
772     {
773 	list_T		*list = our_tv->vval.v_list;
774 	listitem_T	*curr;
775 
776 	if (list == NULL)
777 	    return NULL;
778 
779 	if (!(ret = PyList_New(0)))
780 	    return NULL;
781 
782 	if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
783 	{
784 	    Py_DECREF(ret);
785 	    return NULL;
786 	}
787 
788 	for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
789 	{
790 	    if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
791 	    {
792 		Py_DECREF(ret);
793 		return NULL;
794 	    }
795 	    if (PyList_Append(ret, newObj))
796 	    {
797 		Py_DECREF(newObj);
798 		Py_DECREF(ret);
799 		return NULL;
800 	    }
801 	    Py_DECREF(newObj);
802 	}
803     }
804     else if (our_tv->v_type == VAR_DICT)
805     {
806 
807 	hashtab_T	*ht;
808 	long_u		todo;
809 	hashitem_T	*hi;
810 	dictitem_T	*di;
811 
812 	if (our_tv->vval.v_dict == NULL)
813 	    return NULL;
814 	ht = &our_tv->vval.v_dict->dv_hashtab;
815 
816 	if (!(ret = PyDict_New()))
817 	    return NULL;
818 
819 	if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
820 	{
821 	    Py_DECREF(ret);
822 	    return NULL;
823 	}
824 
825 	todo = ht->ht_used;
826 	for (hi = ht->ht_array; todo > 0; ++hi)
827 	{
828 	    if (!HASHITEM_EMPTY(hi))
829 	    {
830 		--todo;
831 
832 		di = dict_lookup(hi);
833 		if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
834 		{
835 		    Py_DECREF(ret);
836 		    return NULL;
837 		}
838 		if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
839 		{
840 		    Py_DECREF(ret);
841 		    Py_DECREF(newObj);
842 		    return NULL;
843 		}
844 	    }
845 	}
846     }
847     else if (our_tv->v_type == VAR_SPECIAL)
848     {
849 	if (our_tv->vval.v_number == VVAL_FALSE)
850 	{
851 	    ret = Py_False;
852 	    Py_INCREF(ret);
853 	}
854 	else if (our_tv->vval.v_number == VVAL_TRUE)
855 	{
856 	    ret = Py_True;
857 	    Py_INCREF(ret);
858 	}
859 	else
860 	{
861 	    Py_INCREF(Py_None);
862 	    ret = Py_None;
863 	}
864 	return ret;
865     }
866     else if (our_tv->v_type == VAR_BLOB)
867 	ret = PyBytes_FromStringAndSize(
868 		(char*) our_tv->vval.v_blob->bv_ga.ga_data,
869 		(Py_ssize_t) our_tv->vval.v_blob->bv_ga.ga_len);
870     else
871     {
872 	Py_INCREF(Py_None);
873 	ret = Py_None;
874     }
875 
876     return ret;
877 }
878 
879     static PyObject *
880 VimEval(PyObject *self UNUSED, PyObject *args)
881 {
882     char_u	*expr;
883     typval_T	*our_tv;
884     PyObject	*string;
885     PyObject	*todecref;
886     PyObject	*ret;
887     PyObject	*lookup_dict;
888 
889     if (!PyArg_ParseTuple(args, "O", &string))
890 	return NULL;
891 
892     if (!(expr = StringToChars(string, &todecref)))
893 	return NULL;
894 
895     Py_BEGIN_ALLOW_THREADS
896     Python_Lock_Vim();
897     VimTryStart();
898     our_tv = eval_expr(expr, NULL);
899     Python_Release_Vim();
900     Py_END_ALLOW_THREADS
901 
902     Py_XDECREF(todecref);
903 
904     if (VimTryEnd())
905 	return NULL;
906 
907     if (our_tv == NULL)
908     {
909 	PyErr_SET_VIM(N_("invalid expression"));
910 	return NULL;
911     }
912 
913     /* Convert the Vim type into a Python type.  Create a dictionary that's
914      * used to check for recursive loops. */
915     if (!(lookup_dict = PyDict_New()))
916 	ret = NULL;
917     else
918     {
919 	ret = VimToPython(our_tv, 1, lookup_dict);
920 	Py_DECREF(lookup_dict);
921     }
922 
923 
924     Py_BEGIN_ALLOW_THREADS
925     Python_Lock_Vim();
926     free_tv(our_tv);
927     Python_Release_Vim();
928     Py_END_ALLOW_THREADS
929 
930     return ret;
931 }
932 
933 static PyObject *ConvertToPyObject(typval_T *);
934 
935     static PyObject *
936 VimEvalPy(PyObject *self UNUSED, PyObject *string)
937 {
938     typval_T	*our_tv;
939     PyObject	*ret;
940     char_u	*expr;
941     PyObject	*todecref;
942 
943     if (!(expr = StringToChars(string, &todecref)))
944 	return NULL;
945 
946     Py_BEGIN_ALLOW_THREADS
947     Python_Lock_Vim();
948     VimTryStart();
949     our_tv = eval_expr(expr, NULL);
950     Python_Release_Vim();
951     Py_END_ALLOW_THREADS
952 
953     Py_XDECREF(todecref);
954 
955     if (VimTryEnd())
956 	return NULL;
957 
958     if (our_tv == NULL)
959     {
960 	PyErr_SET_VIM(N_("invalid expression"));
961 	return NULL;
962     }
963 
964     ret = ConvertToPyObject(our_tv);
965     Py_BEGIN_ALLOW_THREADS
966     Python_Lock_Vim();
967     free_tv(our_tv);
968     Python_Release_Vim();
969     Py_END_ALLOW_THREADS
970 
971     return ret;
972 }
973 
974     static PyObject *
975 VimStrwidth(PyObject *self UNUSED, PyObject *string)
976 {
977     char_u	*str;
978     PyObject	*todecref;
979     int		len;
980 
981     if (!(str = StringToChars(string, &todecref)))
982 	return NULL;
983 
984     len = mb_string2cells(str, (int)STRLEN(str));
985 
986     Py_XDECREF(todecref);
987 
988     return PyLong_FromLong(len);
989 }
990 
991     static PyObject *
992 _VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
993 {
994     PyObject	*ret;
995     PyObject	*newwd;
996     PyObject	*todecref;
997     char_u	*new_dir;
998 
999     if (_chdir == NULL)
1000 	return NULL;
1001     if (!(ret = PyObject_Call(_chdir, args, kwargs)))
1002 	return NULL;
1003 
1004     if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
1005     {
1006 	Py_DECREF(ret);
1007 	return NULL;
1008     }
1009 
1010     if (!(new_dir = StringToChars(newwd, &todecref)))
1011     {
1012 	Py_DECREF(ret);
1013 	Py_DECREF(newwd);
1014 	return NULL;
1015     }
1016 
1017     VimTryStart();
1018 
1019     if (vim_chdir(new_dir))
1020     {
1021 	Py_DECREF(ret);
1022 	Py_DECREF(newwd);
1023 	Py_XDECREF(todecref);
1024 
1025 	if (VimTryEnd())
1026 	    return NULL;
1027 
1028 	PyErr_SET_VIM(N_("failed to change directory"));
1029 	return NULL;
1030     }
1031 
1032     Py_DECREF(newwd);
1033     Py_XDECREF(todecref);
1034 
1035     post_chdir(FALSE);
1036 
1037     if (VimTryEnd())
1038     {
1039 	Py_DECREF(ret);
1040 	return NULL;
1041     }
1042 
1043     return ret;
1044 }
1045 
1046     static PyObject *
1047 VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1048 {
1049     return _VimChdir(py_chdir, args, kwargs);
1050 }
1051 
1052     static PyObject *
1053 VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1054 {
1055     return _VimChdir(py_fchdir, args, kwargs);
1056 }
1057 
1058 typedef struct {
1059     PyObject	*callable;
1060     PyObject	*result;
1061 } map_rtp_data;
1062 
1063     static void
1064 map_rtp_callback(char_u *path, void *_data)
1065 {
1066     void	**data = (void **) _data;
1067     PyObject	*pathObject;
1068     map_rtp_data	*mr_data = *((map_rtp_data **) data);
1069 
1070     if (!(pathObject = PyString_FromString((char *)path)))
1071     {
1072 	*data = NULL;
1073 	return;
1074     }
1075 
1076     mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
1077 						   pathObject, NULL);
1078 
1079     Py_DECREF(pathObject);
1080 
1081     if (!mr_data->result || mr_data->result != Py_None)
1082 	*data = NULL;
1083     else
1084     {
1085 	Py_DECREF(mr_data->result);
1086 	mr_data->result = NULL;
1087     }
1088 }
1089 
1090     static PyObject *
1091 VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
1092 {
1093     map_rtp_data	data;
1094 
1095     data.callable = callable;
1096     data.result = NULL;
1097 
1098     do_in_runtimepath(NULL, 0, &map_rtp_callback, &data);
1099 
1100     if (data.result == NULL)
1101     {
1102 	if (PyErr_Occurred())
1103 	    return NULL;
1104 	else
1105 	{
1106 	    Py_INCREF(Py_None);
1107 	    return Py_None;
1108 	}
1109     }
1110     return data.result;
1111 }
1112 
1113 /*
1114  * _vim_runtimepath_ special path implementation.
1115  */
1116 
1117     static void
1118 map_finder_callback(char_u *path, void *_data)
1119 {
1120     void	**data = (void **) _data;
1121     PyObject	*list = *((PyObject **) data);
1122     PyObject	*pathObject1, *pathObject2;
1123     char	*pathbuf;
1124     size_t	pathlen;
1125 
1126     pathlen = STRLEN(path);
1127 
1128 #if PY_MAJOR_VERSION < 3
1129 # define PY_MAIN_DIR_STRING "python2"
1130 #else
1131 # define PY_MAIN_DIR_STRING "python3"
1132 #endif
1133 #define PY_ALTERNATE_DIR_STRING "pythonx"
1134 
1135 #define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
1136     if (!(pathbuf = PyMem_New(char,
1137 		    pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
1138     {
1139 	PyErr_NoMemory();
1140 	*data = NULL;
1141 	return;
1142     }
1143 
1144     mch_memmove(pathbuf, path, pathlen + 1);
1145     add_pathsep((char_u *) pathbuf);
1146 
1147     pathlen = STRLEN(pathbuf);
1148     mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
1149 	    PYTHONX_STRING_LENGTH + 1);
1150 
1151     if (!(pathObject1 = PyString_FromString(pathbuf)))
1152     {
1153 	*data = NULL;
1154 	PyMem_Free(pathbuf);
1155 	return;
1156     }
1157 
1158     mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
1159 	    PYTHONX_STRING_LENGTH + 1);
1160 
1161     if (!(pathObject2 = PyString_FromString(pathbuf)))
1162     {
1163 	Py_DECREF(pathObject1);
1164 	PyMem_Free(pathbuf);
1165 	*data = NULL;
1166 	return;
1167     }
1168 
1169     PyMem_Free(pathbuf);
1170 
1171     if (PyList_Append(list, pathObject1)
1172 	    || PyList_Append(list, pathObject2))
1173 	*data = NULL;
1174 
1175     Py_DECREF(pathObject1);
1176     Py_DECREF(pathObject2);
1177 }
1178 
1179     static PyObject *
1180 Vim_GetPaths(PyObject *self UNUSED)
1181 {
1182     PyObject	*ret;
1183 
1184     if (!(ret = PyList_New(0)))
1185 	return NULL;
1186 
1187     do_in_runtimepath(NULL, 0, &map_finder_callback, ret);
1188 
1189     if (PyErr_Occurred())
1190     {
1191 	Py_DECREF(ret);
1192 	return NULL;
1193     }
1194 
1195     return ret;
1196 }
1197 
1198 #if PY_VERSION_HEX >= 0x030700f0
1199     static PyObject *
1200 FinderFindSpec(PyObject *self, PyObject *args)
1201 {
1202     char	*fullname;
1203     PyObject	*paths;
1204     PyObject	*target = Py_None;
1205     PyObject	*spec;
1206 
1207     if (!PyArg_ParseTuple(args, "s|O", &fullname, &target))
1208 	return NULL;
1209 
1210     if (!(paths = Vim_GetPaths(self)))
1211 	return NULL;
1212 
1213     spec = PyObject_CallFunction(py_find_spec, "sNN", fullname, paths, target);
1214 
1215     Py_DECREF(paths);
1216 
1217     if (!spec)
1218     {
1219 	if (PyErr_Occurred())
1220 	    return NULL;
1221 
1222 	Py_INCREF(Py_None);
1223 	return Py_None;
1224     }
1225 
1226     return spec;
1227 }
1228 #else
1229     static PyObject *
1230 call_load_module(char *name, int len, PyObject *find_module_result)
1231 {
1232     PyObject	*fd, *pathname, *description;
1233 
1234     if (!PyTuple_Check(find_module_result))
1235     {
1236 	PyErr_FORMAT(PyExc_TypeError,
1237 		N_("expected 3-tuple as imp.find_module() result, but got %s"),
1238 		Py_TYPE_NAME(find_module_result));
1239 	return NULL;
1240     }
1241     if (PyTuple_GET_SIZE(find_module_result) != 3)
1242     {
1243 	PyErr_FORMAT(PyExc_TypeError,
1244 		N_("expected 3-tuple as imp.find_module() result, but got "
1245 		   "tuple of size %d"),
1246 		(int) PyTuple_GET_SIZE(find_module_result));
1247 	return NULL;
1248     }
1249 
1250     if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1251 	    || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1252 	    || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1253     {
1254 	PyErr_SET_STRING(PyExc_RuntimeError,
1255 		N_("internal error: imp.find_module returned tuple with NULL"));
1256 	return NULL;
1257     }
1258 
1259     return PyObject_CallFunction(py_load_module,
1260 	    "s#OOO", name, len, fd, pathname, description);
1261 }
1262 
1263     static PyObject *
1264 find_module(char *fullname, char *tail, PyObject *new_path)
1265 {
1266     PyObject	*find_module_result;
1267     PyObject	*module;
1268     char	*dot;
1269 
1270     if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
1271     {
1272 	/*
1273 	 * There is a dot in the name: call find_module recursively without the
1274 	 * first component
1275 	 */
1276 	PyObject	*newest_path;
1277 	int		partlen = (int) (dot - 1 - tail);
1278 
1279 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
1280 			"s#O", tail, partlen, new_path)))
1281 	{
1282 	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1283 		PyErr_Clear();
1284 	    return NULL;
1285 	}
1286 
1287 	if (!(module = call_load_module(
1288 			fullname,
1289 			((int) (tail - fullname)) + partlen,
1290 			find_module_result)))
1291 	{
1292 	    Py_DECREF(find_module_result);
1293 	    return NULL;
1294 	}
1295 
1296 	Py_DECREF(find_module_result);
1297 
1298 	if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1299 	{
1300 	    Py_DECREF(module);
1301 	    return NULL;
1302 	}
1303 
1304 	Py_DECREF(module);
1305 
1306 	find_module_result = find_module(fullname, dot + 1, newest_path);
1307 
1308 	Py_DECREF(newest_path);
1309 
1310 	return find_module_result;
1311     }
1312     else
1313     {
1314 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
1315 			"sO", tail, new_path)))
1316 	{
1317 	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1318 		PyErr_Clear();
1319 	    return NULL;
1320 	}
1321 
1322 	return find_module_result;
1323     }
1324 }
1325 
1326     static PyObject *
1327 FinderFindModule(PyObject *self, PyObject *args)
1328 {
1329     char	*fullname;
1330     PyObject	*result;
1331     PyObject	*new_path;
1332     LoaderObject	*loader;
1333 
1334     if (!PyArg_ParseTuple(args, "s", &fullname))
1335 	return NULL;
1336 
1337     if (!(new_path = Vim_GetPaths(self)))
1338 	return NULL;
1339 
1340     result = find_module(fullname, fullname, new_path);
1341 
1342     Py_DECREF(new_path);
1343 
1344     if (!result)
1345     {
1346 	if (PyErr_Occurred())
1347 	    return NULL;
1348 
1349 	Py_INCREF(Py_None);
1350 	return Py_None;
1351     }
1352 
1353     if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
1354     {
1355 	Py_DECREF(result);
1356 	PyErr_NoMemory();
1357 	return NULL;
1358     }
1359 
1360     if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1361     {
1362 	vim_free(fullname);
1363 	Py_DECREF(result);
1364 	return NULL;
1365     }
1366 
1367     loader->fullname = fullname;
1368     loader->result = result;
1369 
1370     return (PyObject *) loader;
1371 }
1372 #endif
1373 
1374     static PyObject *
1375 VimPathHook(PyObject *self UNUSED, PyObject *args)
1376 {
1377     char	*path;
1378 
1379     if (PyArg_ParseTuple(args, "s", &path)
1380 	    && STRCMP(path, vim_special_path) == 0)
1381     {
1382 	Py_INCREF(vim_module);
1383 	return vim_module;
1384     }
1385 
1386     PyErr_Clear();
1387     PyErr_SetNone(PyExc_ImportError);
1388     return NULL;
1389 }
1390 
1391 /*
1392  * Vim module - Definitions
1393  */
1394 
1395 static struct PyMethodDef VimMethods[] = {
1396     /* name,	    function,			calling,			documentation */
1397     {"command",	    VimCommand,			METH_O,				"Execute a Vim ex-mode command" },
1398     {"eval",	    VimEval,			METH_VARARGS,			"Evaluate an expression using Vim evaluator" },
1399     {"bindeval",    VimEvalPy,			METH_O,				"Like eval(), but returns objects attached to vim ones"},
1400     {"strwidth",    VimStrwidth,		METH_O,				"Screen string width, counts <Tab> as having width 1"},
1401     {"chdir",	    (PyCFunction)VimChdir,	METH_VARARGS|METH_KEYWORDS,	"Change directory"},
1402     {"fchdir",	    (PyCFunction)VimFchdir,	METH_VARARGS|METH_KEYWORDS,	"Change directory"},
1403     {"foreach_rtp", VimForeachRTP,		METH_O,				"Call given callable for each path in &rtp"},
1404 #if PY_VERSION_HEX >= 0x030700f0
1405     {"find_spec",   FinderFindSpec,		METH_VARARGS,			"Internal use only, returns spec object for any input it receives"},
1406 #else
1407     {"find_module", FinderFindModule,		METH_VARARGS,			"Internal use only, returns loader object for any input it receives"},
1408 #endif
1409     {"path_hook",   VimPathHook,		METH_VARARGS,			"Hook function to install in sys.path_hooks"},
1410     {"_get_paths",  (PyCFunction)Vim_GetPaths,	METH_NOARGS,			"Get &rtp-based additions to sys.path"},
1411     { NULL,	    NULL,			0,				NULL}
1412 };
1413 
1414 /*
1415  * Generic iterator object
1416  */
1417 
1418 static PyTypeObject IterType;
1419 
1420 typedef PyObject *(*nextfun)(void **);
1421 typedef void (*destructorfun)(void *);
1422 typedef int (*traversefun)(void *, visitproc, void *);
1423 typedef int (*clearfun)(void **);
1424 
1425 /* Main purpose of this object is removing the need for do python
1426  * initialization (i.e. PyType_Ready and setting type attributes) for a big
1427  * bunch of objects. */
1428 
1429 typedef struct
1430 {
1431     PyObject_HEAD
1432     void *cur;
1433     nextfun next;
1434     destructorfun destruct;
1435     traversefun traverse;
1436     clearfun clear;
1437 } IterObject;
1438 
1439     static PyObject *
1440 IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1441 	clearfun clear)
1442 {
1443     IterObject *self;
1444 
1445     self = PyObject_GC_New(IterObject, &IterType);
1446     self->cur = start;
1447     self->next = next;
1448     self->destruct = destruct;
1449     self->traverse = traverse;
1450     self->clear = clear;
1451 
1452     return (PyObject *)(self);
1453 }
1454 
1455     static void
1456 IterDestructor(IterObject *self)
1457 {
1458     PyObject_GC_UnTrack((void *)(self));
1459     self->destruct(self->cur);
1460     PyObject_GC_Del((void *)(self));
1461 }
1462 
1463     static int
1464 IterTraverse(IterObject *self, visitproc visit, void *arg)
1465 {
1466     if (self->traverse != NULL)
1467 	return self->traverse(self->cur, visit, arg);
1468     else
1469 	return 0;
1470 }
1471 
1472 /* Mac OSX defines clear() somewhere. */
1473 #ifdef clear
1474 # undef clear
1475 #endif
1476 
1477     static int
1478 IterClear(IterObject *self)
1479 {
1480     if (self->clear != NULL)
1481 	return self->clear(&self->cur);
1482     else
1483 	return 0;
1484 }
1485 
1486     static PyObject *
1487 IterNext(IterObject *self)
1488 {
1489     return self->next(&self->cur);
1490 }
1491 
1492     static PyObject *
1493 IterIter(PyObject *self)
1494 {
1495     Py_INCREF(self);
1496     return self;
1497 }
1498 
1499 typedef struct pylinkedlist_S {
1500     struct pylinkedlist_S	*pll_next;
1501     struct pylinkedlist_S	*pll_prev;
1502     PyObject			*pll_obj;
1503 } pylinkedlist_T;
1504 
1505 static pylinkedlist_T *lastdict = NULL;
1506 static pylinkedlist_T *lastlist = NULL;
1507 static pylinkedlist_T *lastfunc = NULL;
1508 
1509     static void
1510 pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1511 {
1512     if (ref->pll_prev == NULL)
1513     {
1514 	if (ref->pll_next == NULL)
1515 	{
1516 	    *last = NULL;
1517 	    return;
1518 	}
1519     }
1520     else
1521 	ref->pll_prev->pll_next = ref->pll_next;
1522 
1523     if (ref->pll_next == NULL)
1524 	*last = ref->pll_prev;
1525     else
1526 	ref->pll_next->pll_prev = ref->pll_prev;
1527 }
1528 
1529     static void
1530 pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1531 {
1532     if (*last == NULL)
1533 	ref->pll_prev = NULL;
1534     else
1535     {
1536 	(*last)->pll_next = ref;
1537 	ref->pll_prev = *last;
1538     }
1539     ref->pll_next = NULL;
1540     ref->pll_obj = self;
1541     *last = ref;
1542 }
1543 
1544 static PyTypeObject DictionaryType;
1545 
1546 typedef struct
1547 {
1548     PyObject_HEAD
1549     dict_T	*dict;
1550     pylinkedlist_T	ref;
1551 } DictionaryObject;
1552 
1553 static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1554 
1555 #define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1556 
1557     static PyObject *
1558 DictionaryNew(PyTypeObject *subtype, dict_T *dict)
1559 {
1560     DictionaryObject	*self;
1561 
1562     self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
1563     if (self == NULL)
1564 	return NULL;
1565     self->dict = dict;
1566     ++dict->dv_refcount;
1567 
1568     pyll_add((PyObject *)(self), &self->ref, &lastdict);
1569 
1570     return (PyObject *)(self);
1571 }
1572 
1573     static dict_T *
1574 py_dict_alloc(void)
1575 {
1576     dict_T	*ret;
1577 
1578     if (!(ret = dict_alloc()))
1579     {
1580 	PyErr_NoMemory();
1581 	return NULL;
1582     }
1583     ++ret->dv_refcount;
1584 
1585     return ret;
1586 }
1587 
1588     static PyObject *
1589 DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1590 {
1591     DictionaryObject	*self;
1592     dict_T	*dict;
1593 
1594     if (!(dict = py_dict_alloc()))
1595 	return NULL;
1596 
1597     self = (DictionaryObject *) DictionaryNew(subtype, dict);
1598 
1599     --dict->dv_refcount;
1600 
1601     if (kwargs || PyTuple_Size(args))
1602     {
1603 	PyObject	*tmp;
1604 	if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1605 	{
1606 	    Py_DECREF(self);
1607 	    return NULL;
1608 	}
1609 
1610 	Py_DECREF(tmp);
1611     }
1612 
1613     return (PyObject *)(self);
1614 }
1615 
1616     static void
1617 DictionaryDestructor(DictionaryObject *self)
1618 {
1619     pyll_remove(&self->ref, &lastdict);
1620     dict_unref(self->dict);
1621 
1622     DESTRUCTOR_FINISH(self);
1623 }
1624 
1625 static char *DictionaryAttrs[] = {
1626     "locked", "scope",
1627     NULL
1628 };
1629 
1630     static PyObject *
1631 DictionaryDir(PyObject *self)
1632 {
1633     return ObjectDir(self, DictionaryAttrs);
1634 }
1635 
1636     static int
1637 DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
1638 {
1639     if (valObject == NULL)
1640     {
1641 	PyErr_SET_STRING(PyExc_AttributeError,
1642 		N_("cannot delete vim.Dictionary attributes"));
1643 	return -1;
1644     }
1645 
1646     if (strcmp(name, "locked") == 0)
1647     {
1648 	if (self->dict->dv_lock == VAR_FIXED)
1649 	{
1650 	    PyErr_SET_STRING(PyExc_TypeError,
1651 		    N_("cannot modify fixed dictionary"));
1652 	    return -1;
1653 	}
1654 	else
1655 	{
1656 	    int		istrue = PyObject_IsTrue(valObject);
1657 	    if (istrue == -1)
1658 		return -1;
1659 	    else if (istrue)
1660 		self->dict->dv_lock = VAR_LOCKED;
1661 	    else
1662 		self->dict->dv_lock = 0;
1663 	}
1664 	return 0;
1665     }
1666     else
1667     {
1668 	PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
1669 	return -1;
1670     }
1671 }
1672 
1673     static PyInt
1674 DictionaryLength(DictionaryObject *self)
1675 {
1676     return ((PyInt) (self->dict->dv_hashtab.ht_used));
1677 }
1678 
1679 #define DICT_FLAG_HAS_DEFAULT	0x01
1680 #define DICT_FLAG_POP		0x02
1681 #define DICT_FLAG_NONE_DEFAULT	0x04
1682 #define DICT_FLAG_RETURN_BOOL	0x08 /* Incompatible with DICT_FLAG_POP */
1683 #define DICT_FLAG_RETURN_PAIR	0x10
1684 
1685     static PyObject *
1686 _DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
1687 {
1688     PyObject	*keyObject;
1689     PyObject	*defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
1690     PyObject	*ret;
1691     char_u	*key;
1692     dictitem_T	*di;
1693     dict_T	*dict = self->dict;
1694     hashitem_T	*hi;
1695     PyObject	*todecref;
1696 
1697     if (flags & DICT_FLAG_HAS_DEFAULT)
1698     {
1699 	if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1700 	    return NULL;
1701     }
1702     else
1703 	keyObject = args;
1704 
1705     if (flags & DICT_FLAG_RETURN_BOOL)
1706 	defObject = Py_False;
1707 
1708     if (!(key = StringToChars(keyObject, &todecref)))
1709 	return NULL;
1710 
1711     if (*key == NUL)
1712     {
1713 	RAISE_NO_EMPTY_KEYS;
1714 	Py_XDECREF(todecref);
1715 	return NULL;
1716     }
1717 
1718     hi = hash_find(&dict->dv_hashtab, key);
1719 
1720     Py_XDECREF(todecref);
1721 
1722     if (HASHITEM_EMPTY(hi))
1723     {
1724 	if (defObject)
1725 	{
1726 	    Py_INCREF(defObject);
1727 	    return defObject;
1728 	}
1729 	else
1730 	{
1731 	    PyErr_SetObject(PyExc_KeyError, keyObject);
1732 	    return NULL;
1733 	}
1734     }
1735     else if (flags & DICT_FLAG_RETURN_BOOL)
1736     {
1737 	ret = Py_True;
1738 	Py_INCREF(ret);
1739 	return ret;
1740     }
1741 
1742     di = dict_lookup(hi);
1743 
1744     if (!(ret = ConvertToPyObject(&di->di_tv)))
1745 	return NULL;
1746 
1747     if (flags & DICT_FLAG_POP)
1748     {
1749 	if (dict->dv_lock)
1750 	{
1751 	    RAISE_LOCKED_DICTIONARY;
1752 	    Py_DECREF(ret);
1753 	    return NULL;
1754 	}
1755 
1756 	hash_remove(&dict->dv_hashtab, hi);
1757 	dictitem_free(di);
1758     }
1759 
1760     return ret;
1761 }
1762 
1763     static PyObject *
1764 DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1765 {
1766     return _DictionaryItem(self, keyObject, 0);
1767 }
1768 
1769     static int
1770 DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1771 {
1772     PyObject	*rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1773     int		ret;
1774 
1775     if (rObj == NULL)
1776 	return -1;
1777 
1778     ret = (rObj == Py_True);
1779 
1780     Py_DECREF(rObj);
1781 
1782     return ret;
1783 }
1784 
1785 typedef struct
1786 {
1787     hashitem_T	*ht_array;
1788     long_u	ht_used;
1789     hashtab_T	*ht;
1790     hashitem_T	*hi;
1791     long_u	todo;
1792 } dictiterinfo_T;
1793 
1794     static PyObject *
1795 DictionaryIterNext(dictiterinfo_T **dii)
1796 {
1797     PyObject	*ret;
1798 
1799     if (!(*dii)->todo)
1800 	return NULL;
1801 
1802     if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1803 	    (*dii)->ht->ht_used != (*dii)->ht_used)
1804     {
1805 	PyErr_SET_STRING(PyExc_RuntimeError,
1806 		N_("hashtab changed during iteration"));
1807 	return NULL;
1808     }
1809 
1810     while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1811 	++((*dii)->hi);
1812 
1813     --((*dii)->todo);
1814 
1815     if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
1816 	return NULL;
1817 
1818     return ret;
1819 }
1820 
1821     static PyObject *
1822 DictionaryIter(DictionaryObject *self)
1823 {
1824     dictiterinfo_T	*dii;
1825     hashtab_T		*ht;
1826 
1827     if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1828     {
1829 	PyErr_NoMemory();
1830 	return NULL;
1831     }
1832 
1833     ht = &self->dict->dv_hashtab;
1834     dii->ht_array = ht->ht_array;
1835     dii->ht_used = ht->ht_used;
1836     dii->ht = ht;
1837     dii->hi = dii->ht_array;
1838     dii->todo = dii->ht_used;
1839 
1840     return IterNew(dii,
1841 	    (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1842 	    NULL, NULL);
1843 }
1844 
1845     static PyInt
1846 DictionaryAssItem(
1847 	DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
1848 {
1849     char_u	*key;
1850     typval_T	tv;
1851     dict_T	*dict = self->dict;
1852     dictitem_T	*di;
1853     PyObject	*todecref;
1854 
1855     if (dict->dv_lock)
1856     {
1857 	RAISE_LOCKED_DICTIONARY;
1858 	return -1;
1859     }
1860 
1861     if (!(key = StringToChars(keyObject, &todecref)))
1862 	return -1;
1863 
1864     if (*key == NUL)
1865     {
1866 	RAISE_NO_EMPTY_KEYS;
1867 	Py_XDECREF(todecref);
1868 	return -1;
1869     }
1870 
1871     di = dict_find(dict, key, -1);
1872 
1873     if (valObject == NULL)
1874     {
1875 	hashitem_T	*hi;
1876 
1877 	if (di == NULL)
1878 	{
1879 	    Py_XDECREF(todecref);
1880 	    PyErr_SetObject(PyExc_KeyError, keyObject);
1881 	    return -1;
1882 	}
1883 	hi = hash_find(&dict->dv_hashtab, di->di_key);
1884 	hash_remove(&dict->dv_hashtab, hi);
1885 	dictitem_free(di);
1886 	Py_XDECREF(todecref);
1887 	return 0;
1888     }
1889 
1890     if (ConvertFromPyObject(valObject, &tv) == -1)
1891     {
1892 	Py_XDECREF(todecref);
1893 	return -1;
1894     }
1895 
1896     if (di == NULL)
1897     {
1898 	if (!(di = dictitem_alloc(key)))
1899 	{
1900 	    Py_XDECREF(todecref);
1901 	    PyErr_NoMemory();
1902 	    return -1;
1903 	}
1904 	di->di_tv.v_type = VAR_UNKNOWN;
1905 
1906 	if (dict_add(dict, di) == FAIL)
1907 	{
1908 	    vim_free(di);
1909 	    dictitem_free(di);
1910 	    RAISE_KEY_ADD_FAIL(key);
1911 	    Py_XDECREF(todecref);
1912 	    return -1;
1913 	}
1914     }
1915     else
1916 	clear_tv(&di->di_tv);
1917 
1918     Py_XDECREF(todecref);
1919 
1920     copy_tv(&tv, &di->di_tv);
1921     clear_tv(&tv);
1922     return 0;
1923 }
1924 
1925 typedef PyObject *(*hi_to_py)(hashitem_T *);
1926 
1927     static PyObject *
1928 DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
1929 {
1930     dict_T	*dict = self->dict;
1931     long_u	todo = dict->dv_hashtab.ht_used;
1932     Py_ssize_t	i = 0;
1933     PyObject	*ret;
1934     hashitem_T	*hi;
1935     PyObject	*newObj;
1936 
1937     ret = PyList_New(todo);
1938     for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1939     {
1940 	if (!HASHITEM_EMPTY(hi))
1941 	{
1942 	    if (!(newObj = hiconvert(hi)))
1943 	    {
1944 		Py_DECREF(ret);
1945 		return NULL;
1946 	    }
1947 	    PyList_SET_ITEM(ret, i, newObj);
1948 	    --todo;
1949 	    ++i;
1950 	}
1951     }
1952     return ret;
1953 }
1954 
1955     static PyObject *
1956 dict_key(hashitem_T *hi)
1957 {
1958     return PyBytes_FromString((char *)(hi->hi_key));
1959 }
1960 
1961     static PyObject *
1962 DictionaryListKeys(DictionaryObject *self)
1963 {
1964     return DictionaryListObjects(self, dict_key);
1965 }
1966 
1967     static PyObject *
1968 dict_val(hashitem_T *hi)
1969 {
1970     dictitem_T	*di;
1971 
1972     di = dict_lookup(hi);
1973     return ConvertToPyObject(&di->di_tv);
1974 }
1975 
1976     static PyObject *
1977 DictionaryListValues(DictionaryObject *self)
1978 {
1979     return DictionaryListObjects(self, dict_val);
1980 }
1981 
1982     static PyObject *
1983 dict_item(hashitem_T *hi)
1984 {
1985     PyObject	*keyObject;
1986     PyObject	*valObject;
1987     PyObject	*ret;
1988 
1989     if (!(keyObject = dict_key(hi)))
1990 	return NULL;
1991 
1992     if (!(valObject = dict_val(hi)))
1993     {
1994 	Py_DECREF(keyObject);
1995 	return NULL;
1996     }
1997 
1998     ret = Py_BuildValue("(OO)", keyObject, valObject);
1999 
2000     Py_DECREF(keyObject);
2001     Py_DECREF(valObject);
2002 
2003     return ret;
2004 }
2005 
2006     static PyObject *
2007 DictionaryListItems(DictionaryObject *self)
2008 {
2009     return DictionaryListObjects(self, dict_item);
2010 }
2011 
2012     static PyObject *
2013 DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
2014 {
2015     dict_T	*dict = self->dict;
2016 
2017     if (dict->dv_lock)
2018     {
2019 	RAISE_LOCKED_DICTIONARY;
2020 	return NULL;
2021     }
2022 
2023     if (kwargs)
2024     {
2025 	typval_T	tv;
2026 
2027 	if (ConvertFromPyMapping(kwargs, &tv) == -1)
2028 	    return NULL;
2029 
2030 	VimTryStart();
2031 	dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
2032 	clear_tv(&tv);
2033 	if (VimTryEnd())
2034 	    return NULL;
2035     }
2036     else
2037     {
2038 	PyObject	*obj = NULL;
2039 
2040 	if (!PyArg_ParseTuple(args, "|O", &obj))
2041 	    return NULL;
2042 
2043 	if (obj == NULL)
2044 	{
2045 	    Py_INCREF(Py_None);
2046 	    return Py_None;
2047 	}
2048 
2049 	if (PyObject_HasAttrString(obj, "keys"))
2050 	    return DictionaryUpdate(self, NULL, obj);
2051 	else
2052 	{
2053 	    PyObject	*iterator;
2054 	    PyObject	*item;
2055 
2056 	    if (!(iterator = PyObject_GetIter(obj)))
2057 		return NULL;
2058 
2059 	    while ((item = PyIter_Next(iterator)))
2060 	    {
2061 		PyObject	*fast;
2062 		PyObject	*keyObject;
2063 		PyObject	*valObject;
2064 		PyObject	*todecref;
2065 		char_u		*key;
2066 		dictitem_T	*di;
2067 		hashitem_T	*hi;
2068 
2069 		if (!(fast = PySequence_Fast(item, "")))
2070 		{
2071 		    Py_DECREF(iterator);
2072 		    Py_DECREF(item);
2073 		    return NULL;
2074 		}
2075 
2076 		Py_DECREF(item);
2077 
2078 		if (PySequence_Fast_GET_SIZE(fast) != 2)
2079 		{
2080 		    Py_DECREF(iterator);
2081 		    Py_DECREF(fast);
2082 		    PyErr_FORMAT(PyExc_ValueError,
2083 			    N_("expected sequence element of size 2, "
2084 			    "but got sequence of size %d"),
2085 			    (int) PySequence_Fast_GET_SIZE(fast));
2086 		    return NULL;
2087 		}
2088 
2089 		keyObject = PySequence_Fast_GET_ITEM(fast, 0);
2090 
2091 		if (!(key = StringToChars(keyObject, &todecref)))
2092 		{
2093 		    Py_DECREF(iterator);
2094 		    Py_DECREF(fast);
2095 		    return NULL;
2096 		}
2097 
2098 		di = dictitem_alloc(key);
2099 
2100 		Py_XDECREF(todecref);
2101 
2102 		if (di == NULL)
2103 		{
2104 		    Py_DECREF(fast);
2105 		    Py_DECREF(iterator);
2106 		    PyErr_NoMemory();
2107 		    return NULL;
2108 		}
2109 		di->di_tv.v_type = VAR_UNKNOWN;
2110 
2111 		valObject = PySequence_Fast_GET_ITEM(fast, 1);
2112 
2113 		if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
2114 		{
2115 		    Py_DECREF(iterator);
2116 		    Py_DECREF(fast);
2117 		    dictitem_free(di);
2118 		    return NULL;
2119 		}
2120 
2121 		Py_DECREF(fast);
2122 
2123 		hi = hash_find(&dict->dv_hashtab, di->di_key);
2124 		if (!HASHITEM_EMPTY(hi) || dict_add(dict, di) == FAIL)
2125 		{
2126 		    RAISE_KEY_ADD_FAIL(di->di_key);
2127 		    Py_DECREF(iterator);
2128 		    dictitem_free(di);
2129 		    return NULL;
2130 		}
2131 	    }
2132 
2133 	    Py_DECREF(iterator);
2134 
2135 	    /* Iterator may have finished due to an exception */
2136 	    if (PyErr_Occurred())
2137 		return NULL;
2138 	}
2139     }
2140     Py_INCREF(Py_None);
2141     return Py_None;
2142 }
2143 
2144     static PyObject *
2145 DictionaryGet(DictionaryObject *self, PyObject *args)
2146 {
2147     return _DictionaryItem(self, args,
2148 			    DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
2149 }
2150 
2151     static PyObject *
2152 DictionaryPop(DictionaryObject *self, PyObject *args)
2153 {
2154     return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
2155 }
2156 
2157     static PyObject *
2158 DictionaryPopItem(DictionaryObject *self)
2159 {
2160     hashitem_T	*hi;
2161     PyObject	*ret;
2162     PyObject	*valObject;
2163     dictitem_T	*di;
2164 
2165     if (self->dict->dv_hashtab.ht_used == 0)
2166     {
2167 	PyErr_SetNone(PyExc_KeyError);
2168 	return NULL;
2169     }
2170 
2171     hi = self->dict->dv_hashtab.ht_array;
2172     while (HASHITEM_EMPTY(hi))
2173 	++hi;
2174 
2175     di = dict_lookup(hi);
2176 
2177     if (!(valObject = ConvertToPyObject(&di->di_tv)))
2178 	return NULL;
2179 
2180     if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
2181     {
2182 	Py_DECREF(valObject);
2183 	return NULL;
2184     }
2185 
2186     hash_remove(&self->dict->dv_hashtab, hi);
2187     dictitem_free(di);
2188 
2189     return ret;
2190 }
2191 
2192     static PyObject *
2193 DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
2194 {
2195     return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
2196 }
2197 
2198 static PySequenceMethods DictionaryAsSeq = {
2199     0,					/* sq_length */
2200     0,					/* sq_concat */
2201     0,					/* sq_repeat */
2202     0,					/* sq_item */
2203     0,					/* sq_slice */
2204     0,					/* sq_ass_item */
2205     0,					/* sq_ass_slice */
2206     (objobjproc) DictionaryContains,	/* sq_contains */
2207     0,					/* sq_inplace_concat */
2208     0,					/* sq_inplace_repeat */
2209 };
2210 
2211 static PyMappingMethods DictionaryAsMapping = {
2212     (lenfunc)       DictionaryLength,
2213     (binaryfunc)    DictionaryItem,
2214     (objobjargproc) DictionaryAssItem,
2215 };
2216 
2217 static struct PyMethodDef DictionaryMethods[] = {
2218     {"keys",	(PyCFunction)DictionaryListKeys,	METH_NOARGS,	""},
2219     {"values",	(PyCFunction)DictionaryListValues,	METH_NOARGS,	""},
2220     {"items",	(PyCFunction)DictionaryListItems,	METH_NOARGS,	""},
2221     {"update",	(PyCFunction)DictionaryUpdate,		METH_VARARGS|METH_KEYWORDS, ""},
2222     {"get",	(PyCFunction)DictionaryGet,		METH_VARARGS,	""},
2223     {"pop",	(PyCFunction)DictionaryPop,		METH_VARARGS,	""},
2224     {"popitem",	(PyCFunction)DictionaryPopItem,		METH_NOARGS,	""},
2225     {"has_key",	(PyCFunction)DictionaryHasKey,		METH_O,		""},
2226     {"__dir__",	(PyCFunction)DictionaryDir,		METH_NOARGS,	""},
2227     { NULL,	NULL,					0,		NULL}
2228 };
2229 
2230 static PyTypeObject ListType;
2231 
2232 typedef struct
2233 {
2234     PyObject_HEAD
2235     list_T	*list;
2236     pylinkedlist_T	ref;
2237 } ListObject;
2238 
2239 #define NEW_LIST(list) ListNew(&ListType, list)
2240 
2241     static PyObject *
2242 ListNew(PyTypeObject *subtype, list_T *list)
2243 {
2244     ListObject	*self;
2245 
2246     self = (ListObject *) subtype->tp_alloc(subtype, 0);
2247     if (self == NULL)
2248 	return NULL;
2249     self->list = list;
2250     ++list->lv_refcount;
2251 
2252     pyll_add((PyObject *)(self), &self->ref, &lastlist);
2253 
2254     return (PyObject *)(self);
2255 }
2256 
2257     static list_T *
2258 py_list_alloc(void)
2259 {
2260     list_T	*ret;
2261 
2262     if (!(ret = list_alloc()))
2263     {
2264 	PyErr_NoMemory();
2265 	return NULL;
2266     }
2267     ++ret->lv_refcount;
2268 
2269     return ret;
2270 }
2271 
2272     static int
2273 list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2274 {
2275     PyObject	*iterator;
2276     PyObject	*item;
2277     listitem_T	*li;
2278 
2279     if (!(iterator = PyObject_GetIter(obj)))
2280 	return -1;
2281 
2282     while ((item = PyIter_Next(iterator)))
2283     {
2284 	if (!(li = listitem_alloc()))
2285 	{
2286 	    PyErr_NoMemory();
2287 	    Py_DECREF(item);
2288 	    Py_DECREF(iterator);
2289 	    return -1;
2290 	}
2291 	li->li_tv.v_lock = 0;
2292 	li->li_tv.v_type = VAR_UNKNOWN;
2293 
2294 	if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2295 	{
2296 	    Py_DECREF(item);
2297 	    Py_DECREF(iterator);
2298 	    listitem_free(li);
2299 	    return -1;
2300 	}
2301 
2302 	Py_DECREF(item);
2303 
2304 	list_append(l, li);
2305     }
2306 
2307     Py_DECREF(iterator);
2308 
2309     /* Iterator may have finished due to an exception */
2310     if (PyErr_Occurred())
2311 	return -1;
2312 
2313     return 0;
2314 }
2315 
2316     static PyObject *
2317 ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2318 {
2319     list_T	*list;
2320     PyObject	*obj = NULL;
2321 
2322     if (kwargs)
2323     {
2324 	PyErr_SET_STRING(PyExc_TypeError,
2325 		N_("list constructor does not accept keyword arguments"));
2326 	return NULL;
2327     }
2328 
2329     if (!PyArg_ParseTuple(args, "|O", &obj))
2330 	return NULL;
2331 
2332     if (!(list = py_list_alloc()))
2333 	return NULL;
2334 
2335     if (obj)
2336     {
2337 	PyObject	*lookup_dict;
2338 
2339 	if (!(lookup_dict = PyDict_New()))
2340 	{
2341 	    list_unref(list);
2342 	    return NULL;
2343 	}
2344 
2345 	if (list_py_concat(list, obj, lookup_dict) == -1)
2346 	{
2347 	    Py_DECREF(lookup_dict);
2348 	    list_unref(list);
2349 	    return NULL;
2350 	}
2351 
2352 	Py_DECREF(lookup_dict);
2353     }
2354 
2355     return ListNew(subtype, list);
2356 }
2357 
2358     static void
2359 ListDestructor(ListObject *self)
2360 {
2361     pyll_remove(&self->ref, &lastlist);
2362     list_unref(self->list);
2363 
2364     DESTRUCTOR_FINISH(self);
2365 }
2366 
2367     static PyInt
2368 ListLength(ListObject *self)
2369 {
2370     return ((PyInt) (self->list->lv_len));
2371 }
2372 
2373     static PyObject *
2374 ListIndex(ListObject *self, Py_ssize_t index)
2375 {
2376     listitem_T	*li;
2377 
2378     if (index >= ListLength(self))
2379     {
2380 	PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2381 	return NULL;
2382     }
2383     li = list_find(self->list, (long) index);
2384     if (li == NULL)
2385     {
2386 	/* No more suitable format specifications in python-2.3 */
2387 	PyErr_VIM_FORMAT(N_("internal error: failed to get vim list item %d"),
2388 		(int) index);
2389 	return NULL;
2390     }
2391     return ConvertToPyObject(&li->li_tv);
2392 }
2393 
2394     static PyObject *
2395 ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step,
2396 	  Py_ssize_t slicelen)
2397 {
2398     PyInt	i;
2399     PyObject	*list;
2400 
2401     if (step == 0)
2402     {
2403 	PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2404 	return NULL;
2405     }
2406 
2407     list = PyList_New(slicelen);
2408     if (list == NULL)
2409 	return NULL;
2410 
2411     for (i = 0; i < slicelen; ++i)
2412     {
2413 	PyObject	*item;
2414 
2415 	item = ListIndex(self, first + i*step);
2416 	if (item == NULL)
2417 	{
2418 	    Py_DECREF(list);
2419 	    return NULL;
2420 	}
2421 
2422 	PyList_SET_ITEM(list, i, item);
2423     }
2424 
2425     return list;
2426 }
2427 
2428     static PyObject *
2429 ListItem(ListObject *self, PyObject* idx)
2430 {
2431 #if PY_MAJOR_VERSION < 3
2432     if (PyInt_Check(idx))
2433     {
2434 	long _idx = PyInt_AsLong(idx);
2435 	return ListIndex(self, _idx);
2436     }
2437     else
2438 #endif
2439     if (PyLong_Check(idx))
2440     {
2441 	long _idx = PyLong_AsLong(idx);
2442 	return ListIndex(self, _idx);
2443     }
2444     else if (PySlice_Check(idx))
2445     {
2446 	Py_ssize_t start, stop, step, slicelen;
2447 
2448 	if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
2449 				 &start, &stop, &step, &slicelen) < 0)
2450 	    return NULL;
2451 	return ListSlice(self, start, step, slicelen);
2452     }
2453     else
2454     {
2455 	RAISE_INVALID_INDEX_TYPE(idx);
2456 	return NULL;
2457     }
2458 }
2459 
2460     static void
2461 list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen,
2462 	list_T *l, listitem_T **lis, listitem_T *lastaddedli)
2463 {
2464     while (numreplaced--)
2465     {
2466 	list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]);
2467 	listitem_remove(l, lis[slicelen + numreplaced]);
2468     }
2469     while (numadded--)
2470     {
2471 	listitem_T	*next;
2472 
2473 	next = lastaddedli->li_prev;
2474 	listitem_remove(l, lastaddedli);
2475 	lastaddedli = next;
2476     }
2477 }
2478 
2479     static int
2480 ListAssSlice(ListObject *self, Py_ssize_t first,
2481 	     Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj)
2482 {
2483     PyObject	*iterator;
2484     PyObject	*item;
2485     listitem_T	*li;
2486     listitem_T	*lastaddedli = NULL;
2487     listitem_T	*next;
2488     typval_T	v;
2489     list_T	*l = self->list;
2490     PyInt	i;
2491     PyInt	j;
2492     PyInt	numreplaced = 0;
2493     PyInt	numadded = 0;
2494     PyInt	size;
2495     listitem_T	**lis = NULL;
2496 
2497     size = ListLength(self);
2498 
2499     if (l->lv_lock)
2500     {
2501 	RAISE_LOCKED_LIST;
2502 	return -1;
2503     }
2504 
2505     if (step == 0)
2506     {
2507 	PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2508 	return -1;
2509     }
2510 
2511     if (step != 1 && slicelen == 0)
2512     {
2513 	/* Nothing to do. Only error out if obj has some items. */
2514 	int		ret = 0;
2515 
2516 	if (obj == NULL)
2517 	    return 0;
2518 
2519 	if (!(iterator = PyObject_GetIter(obj)))
2520 	    return -1;
2521 
2522 	if ((item = PyIter_Next(iterator)))
2523 	{
2524 	    PyErr_FORMAT(PyExc_ValueError,
2525 		    N_("attempt to assign sequence of size greater than %d "
2526 			"to extended slice"), 0);
2527 	    Py_DECREF(item);
2528 	    ret = -1;
2529 	}
2530 	Py_DECREF(iterator);
2531 	return ret;
2532     }
2533 
2534     if (obj != NULL)
2535 	/* XXX May allocate zero bytes. */
2536 	if (!(lis = PyMem_New(listitem_T *, slicelen * 2)))
2537 	{
2538 	    PyErr_NoMemory();
2539 	    return -1;
2540 	}
2541 
2542     if (first == size)
2543 	li = NULL;
2544     else
2545     {
2546 	li = list_find(l, (long) first);
2547 	if (li == NULL)
2548 	{
2549 	    PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
2550 		    (int)first);
2551 	    if (obj != NULL)
2552 		PyMem_Free(lis);
2553 	    return -1;
2554 	}
2555 	i = slicelen;
2556 	while (i-- && li != NULL)
2557 	{
2558 	    j = step;
2559 	    next = li;
2560 	    if (step > 0)
2561 		while (next != NULL && ((next = next->li_next) != NULL) && --j);
2562 	    else
2563 		while (next != NULL && ((next = next->li_prev) != NULL) && ++j);
2564 
2565 	    if (obj == NULL)
2566 		listitem_remove(l, li);
2567 	    else
2568 		lis[slicelen - i - 1] = li;
2569 
2570 	    li = next;
2571 	}
2572 	if (li == NULL && i != -1)
2573 	{
2574 	    PyErr_SET_VIM(N_("internal error: not enough list items"));
2575 	    if (obj != NULL)
2576 		PyMem_Free(lis);
2577 	    return -1;
2578 	}
2579     }
2580 
2581     if (obj == NULL)
2582 	return 0;
2583 
2584     if (!(iterator = PyObject_GetIter(obj)))
2585     {
2586 	PyMem_Free(lis);
2587 	return -1;
2588     }
2589 
2590     i = 0;
2591     while ((item = PyIter_Next(iterator)))
2592     {
2593 	if (ConvertFromPyObject(item, &v) == -1)
2594 	{
2595 	    Py_DECREF(iterator);
2596 	    Py_DECREF(item);
2597 	    PyMem_Free(lis);
2598 	    return -1;
2599 	}
2600 	Py_DECREF(item);
2601 	if (list_insert_tv(l, &v, numreplaced < slicelen
2602 				    ? lis[numreplaced]
2603 				    : li) == FAIL)
2604 	{
2605 	    clear_tv(&v);
2606 	    PyErr_SET_VIM(N_("internal error: failed to add item to list"));
2607 	    list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2608 	    PyMem_Free(lis);
2609 	    return -1;
2610 	}
2611 	if (numreplaced < slicelen)
2612 	{
2613 	    lis[slicelen + numreplaced] = lis[numreplaced]->li_prev;
2614 	    vimlist_remove(l, lis[numreplaced], lis[numreplaced]);
2615 	    numreplaced++;
2616 	}
2617 	else
2618 	{
2619 	    if (li)
2620 		lastaddedli = li->li_prev;
2621 	    else
2622 		lastaddedli = l->lv_last;
2623 	    numadded++;
2624 	}
2625 	clear_tv(&v);
2626 	if (step != 1 && i >= slicelen)
2627 	{
2628 	    Py_DECREF(iterator);
2629 	    PyErr_FORMAT(PyExc_ValueError,
2630 		    N_("attempt to assign sequence of size greater than %d "
2631 			"to extended slice"), (int) slicelen);
2632 	    list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2633 	    PyMem_Free(lis);
2634 	    return -1;
2635 	}
2636 	++i;
2637     }
2638     Py_DECREF(iterator);
2639 
2640     if (step != 1 && i != slicelen)
2641     {
2642 	PyErr_FORMAT2(PyExc_ValueError,
2643 		N_("attempt to assign sequence of size %d to extended slice "
2644 		    "of size %d"), (int) i, (int) slicelen);
2645 	list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2646 	PyMem_Free(lis);
2647 	return -1;
2648     }
2649 
2650     if (PyErr_Occurred())
2651     {
2652 	list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2653 	PyMem_Free(lis);
2654 	return -1;
2655     }
2656 
2657     for (i = 0; i < numreplaced; i++)
2658 	listitem_free(lis[i]);
2659     if (step == 1)
2660 	for (i = numreplaced; i < slicelen; i++)
2661 	    listitem_remove(l, lis[i]);
2662 
2663     PyMem_Free(lis);
2664 
2665     return 0;
2666 }
2667 
2668     static int
2669 ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
2670 {
2671     typval_T	tv;
2672     list_T	*l = self->list;
2673     listitem_T	*li;
2674     Py_ssize_t	length = ListLength(self);
2675 
2676     if (l->lv_lock)
2677     {
2678 	RAISE_LOCKED_LIST;
2679 	return -1;
2680     }
2681     if (index > length || (index == length && obj == NULL))
2682     {
2683 	PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2684 	return -1;
2685     }
2686 
2687     if (obj == NULL)
2688     {
2689 	li = list_find(l, (long) index);
2690 	vimlist_remove(l, li, li);
2691 	clear_tv(&li->li_tv);
2692 	vim_free(li);
2693 	return 0;
2694     }
2695 
2696     if (ConvertFromPyObject(obj, &tv) == -1)
2697 	return -1;
2698 
2699     if (index == length)
2700     {
2701 	if (list_append_tv(l, &tv) == FAIL)
2702 	{
2703 	    clear_tv(&tv);
2704 	    PyErr_SET_VIM(N_("failed to add item to list"));
2705 	    return -1;
2706 	}
2707     }
2708     else
2709     {
2710 	li = list_find(l, (long) index);
2711 	clear_tv(&li->li_tv);
2712 	copy_tv(&tv, &li->li_tv);
2713 	clear_tv(&tv);
2714     }
2715     return 0;
2716 }
2717 
2718     static Py_ssize_t
2719 ListAssItem(ListObject *self, PyObject *idx, PyObject *obj)
2720 {
2721 #if PY_MAJOR_VERSION < 3
2722     if (PyInt_Check(idx))
2723     {
2724 	long _idx = PyInt_AsLong(idx);
2725 	return ListAssIndex(self, _idx, obj);
2726     }
2727     else
2728 #endif
2729     if (PyLong_Check(idx))
2730     {
2731 	long _idx = PyLong_AsLong(idx);
2732 	return ListAssIndex(self, _idx, obj);
2733     }
2734     else if (PySlice_Check(idx))
2735     {
2736 	Py_ssize_t start, stop, step, slicelen;
2737 
2738 	if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
2739 				 &start, &stop, &step, &slicelen) < 0)
2740 	    return -1;
2741 	return ListAssSlice(self, start, step, slicelen,
2742 		obj);
2743     }
2744     else
2745     {
2746 	RAISE_INVALID_INDEX_TYPE(idx);
2747 	return -1;
2748     }
2749 }
2750 
2751     static PyObject *
2752 ListConcatInPlace(ListObject *self, PyObject *obj)
2753 {
2754     list_T	*l = self->list;
2755     PyObject	*lookup_dict;
2756 
2757     if (l->lv_lock)
2758     {
2759 	RAISE_LOCKED_LIST;
2760 	return NULL;
2761     }
2762 
2763     if (!(lookup_dict = PyDict_New()))
2764 	return NULL;
2765 
2766     if (list_py_concat(l, obj, lookup_dict) == -1)
2767     {
2768 	Py_DECREF(lookup_dict);
2769 	return NULL;
2770     }
2771     Py_DECREF(lookup_dict);
2772 
2773     Py_INCREF(self);
2774     return (PyObject *)(self);
2775 }
2776 
2777 typedef struct
2778 {
2779     listwatch_T	lw;
2780     list_T	*list;
2781 } listiterinfo_T;
2782 
2783     static void
2784 ListIterDestruct(listiterinfo_T *lii)
2785 {
2786     list_rem_watch(lii->list, &lii->lw);
2787     PyMem_Free(lii);
2788 }
2789 
2790     static PyObject *
2791 ListIterNext(listiterinfo_T **lii)
2792 {
2793     PyObject	*ret;
2794 
2795     if (!((*lii)->lw.lw_item))
2796 	return NULL;
2797 
2798     if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
2799 	return NULL;
2800 
2801     (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2802 
2803     return ret;
2804 }
2805 
2806     static PyObject *
2807 ListIter(ListObject *self)
2808 {
2809     listiterinfo_T	*lii;
2810     list_T	*l = self->list;
2811 
2812     if (!(lii = PyMem_New(listiterinfo_T, 1)))
2813     {
2814 	PyErr_NoMemory();
2815 	return NULL;
2816     }
2817 
2818     list_add_watch(l, &lii->lw);
2819     lii->lw.lw_item = l->lv_first;
2820     lii->list = l;
2821 
2822     return IterNew(lii,
2823 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2824 	    NULL, NULL);
2825 }
2826 
2827 static char *ListAttrs[] = {
2828     "locked",
2829     NULL
2830 };
2831 
2832     static PyObject *
2833 ListDir(PyObject *self)
2834 {
2835     return ObjectDir(self, ListAttrs);
2836 }
2837 
2838     static int
2839 ListSetattr(ListObject *self, char *name, PyObject *valObject)
2840 {
2841     if (valObject == NULL)
2842     {
2843 	PyErr_SET_STRING(PyExc_AttributeError,
2844 		N_("cannot delete vim.List attributes"));
2845 	return -1;
2846     }
2847 
2848     if (strcmp(name, "locked") == 0)
2849     {
2850 	if (self->list->lv_lock == VAR_FIXED)
2851 	{
2852 	    PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
2853 	    return -1;
2854 	}
2855 	else
2856 	{
2857 	    int		istrue = PyObject_IsTrue(valObject);
2858 	    if (istrue == -1)
2859 		return -1;
2860 	    else if (istrue)
2861 		self->list->lv_lock = VAR_LOCKED;
2862 	    else
2863 		self->list->lv_lock = 0;
2864 	}
2865 	return 0;
2866     }
2867     else
2868     {
2869 	PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
2870 	return -1;
2871     }
2872 }
2873 
2874 static PySequenceMethods ListAsSeq = {
2875     (lenfunc)		ListLength,	 /* sq_length,	  len(x)   */
2876     (binaryfunc)	0,		 /* RangeConcat, sq_concat,  x+y   */
2877     0,					 /* RangeRepeat, sq_repeat,  x*n   */
2878     (PyIntArgFunc)	ListIndex,	 /* sq_item,	  x[i]	   */
2879     0,					 /* was_sq_slice,     x[i:j]   */
2880     (PyIntObjArgProc)	ListAssIndex,	 /* sq_as_item,  x[i]=v   */
2881     0,					 /* was_sq_ass_slice, x[i:j]=v */
2882     0,					 /* sq_contains */
2883     (binaryfunc)	ListConcatInPlace,/* sq_inplace_concat */
2884     0,					 /* sq_inplace_repeat */
2885 };
2886 
2887 static PyMappingMethods ListAsMapping = {
2888     /* mp_length	*/ (lenfunc) ListLength,
2889     /* mp_subscript     */ (binaryfunc) ListItem,
2890     /* mp_ass_subscript */ (objobjargproc) ListAssItem,
2891 };
2892 
2893 static struct PyMethodDef ListMethods[] = {
2894     {"extend",	(PyCFunction)ListConcatInPlace,	METH_O,		""},
2895     {"__dir__",	(PyCFunction)ListDir,		METH_NOARGS,	""},
2896     { NULL,	NULL,				0,		NULL}
2897 };
2898 
2899 typedef struct
2900 {
2901     PyObject_HEAD
2902     char_u	*name;
2903     int		argc;
2904     typval_T	*argv;
2905     dict_T	*self;
2906     pylinkedlist_T	ref;
2907     int		auto_rebind;
2908 } FunctionObject;
2909 
2910 static PyTypeObject FunctionType;
2911 
2912 #define NEW_FUNCTION(name, argc, argv, self, pt_auto) \
2913     FunctionNew(&FunctionType, (name), (argc), (argv), (self), (pt_auto))
2914 
2915     static PyObject *
2916 FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
2917 	dict_T *selfdict, int auto_rebind)
2918 {
2919     FunctionObject	*self;
2920 
2921     self = (FunctionObject *)subtype->tp_alloc(subtype, 0);
2922     if (self == NULL)
2923 	return NULL;
2924 
2925     if (isdigit(*name))
2926     {
2927 	if (!translated_function_exists(name))
2928 	{
2929 	    PyErr_FORMAT(PyExc_ValueError,
2930 		    N_("unnamed function %s does not exist"), name);
2931 	    return NULL;
2932 	}
2933 	self->name = vim_strsave(name);
2934     }
2935     else
2936     {
2937 	char_u *p;
2938 
2939 	if ((p = get_expanded_name(name,
2940 			    vim_strchr(name, AUTOLOAD_CHAR) == NULL)) == NULL)
2941 	{
2942 	    PyErr_FORMAT(PyExc_ValueError,
2943 		    N_("function %s does not exist"), name);
2944 	    return NULL;
2945 	}
2946 
2947 	if (p[0] == K_SPECIAL && p[1] == KS_EXTRA && p[2] == (int)KE_SNR)
2948 	{
2949 	    char_u *np;
2950 	    size_t len = STRLEN(p) + 1;
2951 
2952 	    if ((np = alloc((int)len + 2)) == NULL)
2953 	    {
2954 		vim_free(p);
2955 		return NULL;
2956 	    }
2957 	    mch_memmove(np, "<SNR>", 5);
2958 	    mch_memmove(np + 5, p + 3, len - 3);
2959 	    vim_free(p);
2960 	    self->name = np;
2961 	}
2962 	else
2963 	    self->name = p;
2964     }
2965 
2966     func_ref(self->name);
2967     self->argc = argc;
2968     self->argv = argv;
2969     self->self = selfdict;
2970     self->auto_rebind = selfdict == NULL ? TRUE : auto_rebind;
2971 
2972     if (self->argv || self->self)
2973 	pyll_add((PyObject *)(self), &self->ref, &lastfunc);
2974 
2975     return (PyObject *)(self);
2976 }
2977 
2978     static PyObject *
2979 FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2980 {
2981     PyObject	*self;
2982     PyObject	*selfdictObject;
2983     PyObject	*autoRebindObject;
2984     PyObject	*argsObject = NULL;
2985     char_u	*name;
2986     typval_T	selfdicttv;
2987     typval_T	argstv;
2988     list_T	*argslist = NULL;
2989     dict_T	*selfdict = NULL;
2990     int		argc = 0;
2991     int		auto_rebind = TRUE;
2992     typval_T	*argv = NULL;
2993     typval_T	*curtv;
2994     listitem_T	*li;
2995 
2996     if (kwargs != NULL)
2997     {
2998 	selfdictObject = PyDict_GetItemString(kwargs, "self");
2999 	if (selfdictObject != NULL)
3000 	{
3001 	    if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
3002 		return NULL;
3003 	    selfdict = selfdicttv.vval.v_dict;
3004 	}
3005 	argsObject = PyDict_GetItemString(kwargs, "args");
3006 	if (argsObject != NULL)
3007 	{
3008 	    if (ConvertFromPySequence(argsObject, &argstv) == -1)
3009 	    {
3010 		dict_unref(selfdict);
3011 		return NULL;
3012 	    }
3013 	    argslist = argstv.vval.v_list;
3014 
3015 	    argc = argslist->lv_len;
3016 	    if (argc != 0)
3017 	    {
3018 		argv = PyMem_New(typval_T, (size_t) argc);
3019 		if (argv == NULL)
3020 		{
3021 		    PyErr_NoMemory();
3022 		    dict_unref(selfdict);
3023 		    list_unref(argslist);
3024 		    return NULL;
3025 		}
3026 		curtv = argv;
3027 		for (li = argslist->lv_first; li != NULL; li = li->li_next)
3028 		    copy_tv(&li->li_tv, curtv++);
3029 	    }
3030 	    list_unref(argslist);
3031 	}
3032 	if (selfdict != NULL)
3033 	{
3034 	    auto_rebind = FALSE;
3035 	    autoRebindObject = PyDict_GetItemString(kwargs, "auto_rebind");
3036 	    if (autoRebindObject != NULL)
3037 	    {
3038 		auto_rebind = PyObject_IsTrue(autoRebindObject);
3039 		if (auto_rebind == -1)
3040 		{
3041 		    dict_unref(selfdict);
3042 		    list_unref(argslist);
3043 		    return NULL;
3044 		}
3045 	    }
3046 	}
3047     }
3048 
3049     if (!PyArg_ParseTuple(args, "et", "ascii", &name))
3050     {
3051 	dict_unref(selfdict);
3052 	while (argc--)
3053 	    clear_tv(&argv[argc]);
3054 	PyMem_Free(argv);
3055 	return NULL;
3056     }
3057 
3058     self = FunctionNew(subtype, name, argc, argv, selfdict, auto_rebind);
3059 
3060     PyMem_Free(name);
3061 
3062     return self;
3063 }
3064 
3065     static void
3066 FunctionDestructor(FunctionObject *self)
3067 {
3068     int i;
3069     func_unref(self->name);
3070     vim_free(self->name);
3071     for (i = 0; i < self->argc; ++i)
3072 	clear_tv(&self->argv[i]);
3073     PyMem_Free(self->argv);
3074     dict_unref(self->self);
3075     if (self->argv || self->self)
3076 	pyll_remove(&self->ref, &lastfunc);
3077 
3078     DESTRUCTOR_FINISH(self);
3079 }
3080 
3081 static char *FunctionAttrs[] = {
3082     "softspace", "args", "self", "auto_rebind",
3083     NULL
3084 };
3085 
3086     static PyObject *
3087 FunctionDir(PyObject *self)
3088 {
3089     return ObjectDir(self, FunctionAttrs);
3090 }
3091 
3092     static PyObject *
3093 FunctionAttr(FunctionObject *self, char *name)
3094 {
3095     list_T *list;
3096     int i;
3097     if (strcmp(name, "name") == 0)
3098 	return PyString_FromString((char *)(self->name));
3099     else if (strcmp(name, "args") == 0)
3100     {
3101 	if (self->argv == NULL || (list = list_alloc()) == NULL)
3102 	    return AlwaysNone(NULL);
3103 
3104 	for (i = 0; i < self->argc; ++i)
3105 	    list_append_tv(list, &self->argv[i]);
3106 	return NEW_LIST(list);
3107     }
3108     else if (strcmp(name, "self") == 0)
3109 	return self->self == NULL
3110 	    ? AlwaysNone(NULL)
3111 	    : NEW_DICTIONARY(self->self);
3112     else if (strcmp(name, "auto_rebind") == 0)
3113 	return self->auto_rebind
3114 	    ? AlwaysTrue(NULL)
3115 	    : AlwaysFalse(NULL);
3116     else if (strcmp(name, "__members__") == 0)
3117 	return ObjectDir(NULL, FunctionAttrs);
3118     return NULL;
3119 }
3120 
3121 /* Populate partial_T given function object.
3122  *
3123  * "exported" should be set to true when it is needed to construct a partial
3124  * that may be stored in a variable (i.e. may be freed by Vim).
3125  */
3126     static void
3127 set_partial(FunctionObject *self, partial_T *pt, int exported)
3128 {
3129     int i;
3130 
3131     pt->pt_name = self->name;
3132     if (self->argv)
3133     {
3134 	pt->pt_argc = self->argc;
3135 	if (exported)
3136 	{
3137 	    pt->pt_argv = (typval_T *)alloc_clear(
3138 		    sizeof(typval_T) * self->argc);
3139 	    for (i = 0; i < pt->pt_argc; ++i)
3140 		copy_tv(&self->argv[i], &pt->pt_argv[i]);
3141 	}
3142 	else
3143 	    pt->pt_argv = self->argv;
3144     }
3145     else
3146     {
3147 	pt->pt_argc = 0;
3148 	pt->pt_argv = NULL;
3149     }
3150     pt->pt_auto = self->auto_rebind || !exported;
3151     pt->pt_dict = self->self;
3152     if (exported && self->self)
3153 	++pt->pt_dict->dv_refcount;
3154     if (exported)
3155 	pt->pt_name = vim_strsave(pt->pt_name);
3156     pt->pt_refcount = 1;
3157 }
3158 
3159     static PyObject *
3160 FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
3161 {
3162     char_u	*name = self->name;
3163     typval_T	args;
3164     typval_T	selfdicttv;
3165     typval_T	rettv;
3166     dict_T	*selfdict = NULL;
3167     PyObject	*selfdictObject;
3168     PyObject	*ret;
3169     int		error;
3170     partial_T	pt;
3171     partial_T	*pt_ptr = NULL;
3172 
3173     if (ConvertFromPySequence(argsObject, &args) == -1)
3174 	return NULL;
3175 
3176     if (kwargs != NULL)
3177     {
3178 	selfdictObject = PyDict_GetItemString(kwargs, "self");
3179 	if (selfdictObject != NULL)
3180 	{
3181 	    if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
3182 	    {
3183 		clear_tv(&args);
3184 		return NULL;
3185 	    }
3186 	    selfdict = selfdicttv.vval.v_dict;
3187 	}
3188     }
3189 
3190     if (self->argv || self->self)
3191     {
3192 	vim_memset(&pt, 0, sizeof(partial_T));
3193 	set_partial(self, &pt, FALSE);
3194 	pt_ptr = &pt;
3195     }
3196 
3197     Py_BEGIN_ALLOW_THREADS
3198     Python_Lock_Vim();
3199 
3200     VimTryStart();
3201     error = func_call(name, &args, pt_ptr, selfdict, &rettv);
3202 
3203     Python_Release_Vim();
3204     Py_END_ALLOW_THREADS
3205 
3206     if (VimTryEnd())
3207 	ret = NULL;
3208     else if (error != OK)
3209     {
3210 	ret = NULL;
3211 	PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
3212     }
3213     else
3214 	ret = ConvertToPyObject(&rettv);
3215 
3216     clear_tv(&args);
3217     clear_tv(&rettv);
3218     if (selfdict != NULL)
3219 	clear_tv(&selfdicttv);
3220 
3221     return ret;
3222 }
3223 
3224     static PyObject *
3225 FunctionRepr(FunctionObject *self)
3226 {
3227     PyObject *ret;
3228     garray_T repr_ga;
3229     int i;
3230     char_u *tofree = NULL;
3231     typval_T tv;
3232     char_u numbuf[NUMBUFLEN];
3233 
3234     ga_init2(&repr_ga, (int)sizeof(char), 70);
3235     ga_concat(&repr_ga, (char_u *)"<vim.Function '");
3236     if (self->name)
3237 	ga_concat(&repr_ga, self->name);
3238     else
3239 	ga_concat(&repr_ga, (char_u *)"<NULL>");
3240     ga_append(&repr_ga, '\'');
3241     if (self->argv)
3242     {
3243 	ga_concat(&repr_ga, (char_u *)", args=[");
3244 	++emsg_silent;
3245 	for (i = 0; i < self->argc; i++)
3246 	{
3247 	    if (i != 0)
3248 		ga_concat(&repr_ga, (char_u *)", ");
3249 	    ga_concat(&repr_ga, tv2string(&self->argv[i], &tofree, numbuf,
3250 			get_copyID()));
3251 	    vim_free(tofree);
3252 	}
3253 	--emsg_silent;
3254 	ga_append(&repr_ga, ']');
3255     }
3256     if (self->self)
3257     {
3258 	ga_concat(&repr_ga, (char_u *)", self=");
3259 	tv.v_type = VAR_DICT;
3260 	tv.vval.v_dict = self->self;
3261 	++emsg_silent;
3262 	ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID()));
3263 	--emsg_silent;
3264 	vim_free(tofree);
3265 	if (self->auto_rebind)
3266 	    ga_concat(&repr_ga, (char_u *)", auto_rebind=True");
3267     }
3268     ga_append(&repr_ga, '>');
3269     ret = PyString_FromString((char *)repr_ga.ga_data);
3270     ga_clear(&repr_ga);
3271     return ret;
3272 }
3273 
3274 static struct PyMethodDef FunctionMethods[] = {
3275     {"__dir__",	(PyCFunction)FunctionDir,   METH_NOARGS,		""},
3276     { NULL,	NULL,			0,				NULL}
3277 };
3278 
3279 /*
3280  * Options object
3281  */
3282 
3283 static PyTypeObject OptionsType;
3284 
3285 typedef int (*checkfun)(void *);
3286 
3287 typedef struct
3288 {
3289     PyObject_HEAD
3290     int		opt_type;
3291     void	*from;
3292     checkfun	Check;
3293     PyObject	*fromObj;
3294 } OptionsObject;
3295 
3296     static int
3297 dummy_check(void *arg UNUSED)
3298 {
3299     return 0;
3300 }
3301 
3302     static PyObject *
3303 OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
3304 {
3305     OptionsObject	*self;
3306 
3307     self = PyObject_GC_New(OptionsObject, &OptionsType);
3308     if (self == NULL)
3309 	return NULL;
3310 
3311     self->opt_type = opt_type;
3312     self->from = from;
3313     self->Check = Check;
3314     self->fromObj = fromObj;
3315     if (fromObj)
3316 	Py_INCREF(fromObj);
3317 
3318     return (PyObject *)(self);
3319 }
3320 
3321     static void
3322 OptionsDestructor(OptionsObject *self)
3323 {
3324     PyObject_GC_UnTrack((void *)(self));
3325     Py_XDECREF(self->fromObj);
3326     PyObject_GC_Del((void *)(self));
3327 }
3328 
3329     static int
3330 OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
3331 {
3332     Py_VISIT(self->fromObj);
3333     return 0;
3334 }
3335 
3336     static int
3337 OptionsClear(OptionsObject *self)
3338 {
3339     Py_CLEAR(self->fromObj);
3340     return 0;
3341 }
3342 
3343     static PyObject *
3344 OptionsItem(OptionsObject *self, PyObject *keyObject)
3345 {
3346     char_u	*key;
3347     int		flags;
3348     long	numval;
3349     char_u	*stringval;
3350     PyObject	*todecref;
3351 
3352     if (self->Check(self->from))
3353 	return NULL;
3354 
3355     if (!(key = StringToChars(keyObject, &todecref)))
3356 	return NULL;
3357 
3358     if (*key == NUL)
3359     {
3360 	RAISE_NO_EMPTY_KEYS;
3361 	Py_XDECREF(todecref);
3362 	return NULL;
3363     }
3364 
3365     flags = get_option_value_strict(key, &numval, &stringval,
3366 				    self->opt_type, self->from);
3367 
3368     Py_XDECREF(todecref);
3369 
3370     if (flags == 0)
3371     {
3372 	PyErr_SetObject(PyExc_KeyError, keyObject);
3373 	return NULL;
3374     }
3375 
3376     if (flags & SOPT_UNSET)
3377     {
3378 	Py_INCREF(Py_None);
3379 	return Py_None;
3380     }
3381     else if (flags & SOPT_BOOL)
3382     {
3383 	PyObject	*ret;
3384 	ret = numval ? Py_True : Py_False;
3385 	Py_INCREF(ret);
3386 	return ret;
3387     }
3388     else if (flags & SOPT_NUM)
3389 	return PyInt_FromLong(numval);
3390     else if (flags & SOPT_STRING)
3391     {
3392 	if (stringval)
3393 	{
3394 	    PyObject	*ret = PyBytes_FromString((char *)stringval);
3395 	    vim_free(stringval);
3396 	    return ret;
3397 	}
3398 	else
3399 	{
3400 	    PyErr_SET_STRING(PyExc_RuntimeError,
3401 		    N_("unable to get option value"));
3402 	    return NULL;
3403 	}
3404     }
3405     else
3406     {
3407 	PyErr_SET_VIM(N_("internal error: unknown option type"));
3408 	return NULL;
3409     }
3410 }
3411 
3412     static int
3413 OptionsContains(OptionsObject *self, PyObject *keyObject)
3414 {
3415     char_u	*key;
3416     PyObject	*todecref;
3417 
3418     if (!(key = StringToChars(keyObject, &todecref)))
3419 	return -1;
3420 
3421     if (*key == NUL)
3422     {
3423 	Py_XDECREF(todecref);
3424 	return 0;
3425     }
3426 
3427     if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
3428     {
3429 	Py_XDECREF(todecref);
3430 	return 1;
3431     }
3432     else
3433     {
3434 	Py_XDECREF(todecref);
3435 	return 0;
3436     }
3437 }
3438 
3439 typedef struct
3440 {
3441     void	*lastoption;
3442     int		opt_type;
3443 } optiterinfo_T;
3444 
3445     static PyObject *
3446 OptionsIterNext(optiterinfo_T **oii)
3447 {
3448     char_u	*name;
3449 
3450     if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
3451 	return PyString_FromString((char *)name);
3452 
3453     return NULL;
3454 }
3455 
3456     static PyObject *
3457 OptionsIter(OptionsObject *self)
3458 {
3459     optiterinfo_T	*oii;
3460 
3461     if (!(oii = PyMem_New(optiterinfo_T, 1)))
3462     {
3463 	PyErr_NoMemory();
3464 	return NULL;
3465     }
3466 
3467     oii->opt_type = self->opt_type;
3468     oii->lastoption = NULL;
3469 
3470     return IterNew(oii,
3471 	    (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
3472 	    NULL, NULL);
3473 }
3474 
3475     static int
3476 set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
3477 {
3478     char	*errmsg;
3479 
3480     if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
3481     {
3482 	if (VimTryEnd())
3483 	    return FAIL;
3484 	PyErr_SetVim(errmsg);
3485 	return FAIL;
3486     }
3487     return OK;
3488 }
3489 
3490     static int
3491 set_option_value_for(
3492 	char_u *key,
3493 	int numval,
3494 	char_u *stringval,
3495 	int opt_flags,
3496 	int opt_type,
3497 	void *from)
3498 {
3499     win_T	*save_curwin = NULL;
3500     tabpage_T	*save_curtab = NULL;
3501     bufref_T	save_curbuf;
3502     int		set_ret = 0;
3503 
3504     VimTryStart();
3505     switch (opt_type)
3506     {
3507 	case SREQ_WIN:
3508 	    if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
3509 			      win_find_tabpage((win_T *)from), FALSE) == FAIL)
3510 	    {
3511 		restore_win(save_curwin, save_curtab, TRUE);
3512 		if (VimTryEnd())
3513 		    return -1;
3514 		PyErr_SET_VIM(N_("problem while switching windows"));
3515 		return -1;
3516 	    }
3517 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3518 	    restore_win(save_curwin, save_curtab, TRUE);
3519 	    break;
3520 	case SREQ_BUF:
3521 	    switch_buffer(&save_curbuf, (buf_T *)from);
3522 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3523 	    restore_buffer(&save_curbuf);
3524 	    break;
3525 	case SREQ_GLOBAL:
3526 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3527 	    break;
3528     }
3529     if (set_ret == FAIL)
3530 	return -1;
3531     return VimTryEnd();
3532 }
3533 
3534     static int
3535 OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
3536 {
3537     char_u	*key;
3538     int		flags;
3539     int		opt_flags;
3540     int		ret = 0;
3541     PyObject	*todecref;
3542 
3543     if (self->Check(self->from))
3544 	return -1;
3545 
3546     if (!(key = StringToChars(keyObject, &todecref)))
3547 	return -1;
3548 
3549     if (*key == NUL)
3550     {
3551 	RAISE_NO_EMPTY_KEYS;
3552 	Py_XDECREF(todecref);
3553 	return -1;
3554     }
3555 
3556     flags = get_option_value_strict(key, NULL, NULL,
3557 				    self->opt_type, self->from);
3558 
3559     if (flags == 0)
3560     {
3561 	PyErr_SetObject(PyExc_KeyError, keyObject);
3562 	Py_XDECREF(todecref);
3563 	return -1;
3564     }
3565 
3566     if (valObject == NULL)
3567     {
3568 	if (self->opt_type == SREQ_GLOBAL)
3569 	{
3570 	    PyErr_FORMAT(PyExc_ValueError,
3571 		    N_("unable to unset global option %s"), key);
3572 	    Py_XDECREF(todecref);
3573 	    return -1;
3574 	}
3575 	else if (!(flags & SOPT_GLOBAL))
3576 	{
3577 	    PyErr_FORMAT(PyExc_ValueError,
3578 		    N_("unable to unset option %s "
3579 		       "which does not have global value"), key);
3580 	    Py_XDECREF(todecref);
3581 	    return -1;
3582 	}
3583 	else
3584 	{
3585 	    unset_global_local_option(key, self->from);
3586 	    Py_XDECREF(todecref);
3587 	    return 0;
3588 	}
3589     }
3590 
3591     opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
3592 
3593     if (flags & SOPT_BOOL)
3594     {
3595 	int	istrue = PyObject_IsTrue(valObject);
3596 
3597 	if (istrue == -1)
3598 	    ret = -1;
3599 	else
3600 	    ret = set_option_value_for(key, istrue, NULL,
3601 				    opt_flags, self->opt_type, self->from);
3602     }
3603     else if (flags & SOPT_NUM)
3604     {
3605 	long	val;
3606 
3607 	if (NumberToLong(valObject, &val, NUMBER_INT))
3608 	{
3609 	    Py_XDECREF(todecref);
3610 	    return -1;
3611 	}
3612 
3613 	ret = set_option_value_for(key, (int) val, NULL, opt_flags,
3614 				self->opt_type, self->from);
3615     }
3616     else
3617     {
3618 	char_u		*val;
3619 	PyObject	*todecref2;
3620 
3621 	if ((val = StringToChars(valObject, &todecref2)))
3622 	{
3623 	    ret = set_option_value_for(key, 0, val, opt_flags,
3624 				    self->opt_type, self->from);
3625 	    Py_XDECREF(todecref2);
3626 	}
3627 	else
3628 	    ret = -1;
3629     }
3630 
3631     Py_XDECREF(todecref);
3632 
3633     return ret;
3634 }
3635 
3636 static PySequenceMethods OptionsAsSeq = {
3637     0,					/* sq_length */
3638     0,					/* sq_concat */
3639     0,					/* sq_repeat */
3640     0,					/* sq_item */
3641     0,					/* sq_slice */
3642     0,					/* sq_ass_item */
3643     0,					/* sq_ass_slice */
3644     (objobjproc) OptionsContains,	/* sq_contains */
3645     0,					/* sq_inplace_concat */
3646     0,					/* sq_inplace_repeat */
3647 };
3648 
3649 static PyMappingMethods OptionsAsMapping = {
3650     (lenfunc)       NULL,
3651     (binaryfunc)    OptionsItem,
3652     (objobjargproc) OptionsAssItem,
3653 };
3654 
3655 /* Tabpage object
3656  */
3657 
3658 typedef struct
3659 {
3660     PyObject_HEAD
3661     tabpage_T	*tab;
3662 } TabPageObject;
3663 
3664 static PyObject *WinListNew(TabPageObject *tabObject);
3665 
3666 static PyTypeObject TabPageType;
3667 
3668     static int
3669 CheckTabPage(TabPageObject *self)
3670 {
3671     if (self->tab == INVALID_TABPAGE_VALUE)
3672     {
3673 	PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
3674 	return -1;
3675     }
3676 
3677     return 0;
3678 }
3679 
3680     static PyObject *
3681 TabPageNew(tabpage_T *tab)
3682 {
3683     TabPageObject *self;
3684 
3685     if (TAB_PYTHON_REF(tab))
3686     {
3687 	self = TAB_PYTHON_REF(tab);
3688 	Py_INCREF(self);
3689     }
3690     else
3691     {
3692 	self = PyObject_NEW(TabPageObject, &TabPageType);
3693 	if (self == NULL)
3694 	    return NULL;
3695 	self->tab = tab;
3696 	TAB_PYTHON_REF(tab) = self;
3697     }
3698 
3699     return (PyObject *)(self);
3700 }
3701 
3702     static void
3703 TabPageDestructor(TabPageObject *self)
3704 {
3705     if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3706 	TAB_PYTHON_REF(self->tab) = NULL;
3707 
3708     DESTRUCTOR_FINISH(self);
3709 }
3710 
3711 static char *TabPageAttrs[] = {
3712     "windows", "number", "vars", "window", "valid",
3713     NULL
3714 };
3715 
3716     static PyObject *
3717 TabPageDir(PyObject *self)
3718 {
3719     return ObjectDir(self, TabPageAttrs);
3720 }
3721 
3722     static PyObject *
3723 TabPageAttrValid(TabPageObject *self, char *name)
3724 {
3725     PyObject	*ret;
3726 
3727     if (strcmp(name, "valid") != 0)
3728 	return NULL;
3729 
3730     ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3731     Py_INCREF(ret);
3732     return ret;
3733 }
3734 
3735     static PyObject *
3736 TabPageAttr(TabPageObject *self, char *name)
3737 {
3738     if (strcmp(name, "windows") == 0)
3739 	return WinListNew(self);
3740     else if (strcmp(name, "number") == 0)
3741 	return PyLong_FromLong((long) get_tab_number(self->tab));
3742     else if (strcmp(name, "vars") == 0)
3743 	return NEW_DICTIONARY(self->tab->tp_vars);
3744     else if (strcmp(name, "window") == 0)
3745     {
3746 	/* For current tab window.c does not bother to set or update tp_curwin
3747 	 */
3748 	if (self->tab == curtab)
3749 	    return WindowNew(curwin, curtab);
3750 	else
3751 	    return WindowNew(self->tab->tp_curwin, self->tab);
3752     }
3753     else if (strcmp(name, "__members__") == 0)
3754 	return ObjectDir(NULL, TabPageAttrs);
3755     return NULL;
3756 }
3757 
3758     static PyObject *
3759 TabPageRepr(TabPageObject *self)
3760 {
3761     if (self->tab == INVALID_TABPAGE_VALUE)
3762 	return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
3763     else
3764     {
3765 	int	t = get_tab_number(self->tab);
3766 
3767 	if (t == 0)
3768 	    return PyString_FromFormat("<tabpage object (unknown) at %p>",
3769 					(self));
3770 	else
3771 	    return PyString_FromFormat("<tabpage %d>", t - 1);
3772     }
3773 }
3774 
3775 static struct PyMethodDef TabPageMethods[] = {
3776     /* name,	    function,			calling,	documentation */
3777     {"__dir__",	    (PyCFunction)TabPageDir,	METH_NOARGS,	""},
3778     { NULL,	    NULL,			0,		NULL}
3779 };
3780 
3781 /*
3782  * Window list object
3783  */
3784 
3785 static PyTypeObject TabListType;
3786 static PySequenceMethods TabListAsSeq;
3787 
3788 typedef struct
3789 {
3790     PyObject_HEAD
3791 } TabListObject;
3792 
3793     static PyInt
3794 TabListLength(PyObject *self UNUSED)
3795 {
3796     tabpage_T	*tp = first_tabpage;
3797     PyInt	n = 0;
3798 
3799     while (tp != NULL)
3800     {
3801 	++n;
3802 	tp = tp->tp_next;
3803     }
3804 
3805     return n;
3806 }
3807 
3808     static PyObject *
3809 TabListItem(PyObject *self UNUSED, PyInt n)
3810 {
3811     tabpage_T	*tp;
3812 
3813     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3814 	if (n == 0)
3815 	    return TabPageNew(tp);
3816 
3817     PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
3818     return NULL;
3819 }
3820 
3821 /*
3822  * Window object
3823  */
3824 
3825 typedef struct
3826 {
3827     PyObject_HEAD
3828     win_T	*win;
3829     TabPageObject	*tabObject;
3830 } WindowObject;
3831 
3832 static PyTypeObject WindowType;
3833 
3834     static int
3835 CheckWindow(WindowObject *self)
3836 {
3837     if (self->win == INVALID_WINDOW_VALUE)
3838     {
3839 	PyErr_SET_VIM(N_("attempt to refer to deleted window"));
3840 	return -1;
3841     }
3842 
3843     return 0;
3844 }
3845 
3846     static PyObject *
3847 WindowNew(win_T *win, tabpage_T *tab)
3848 {
3849     /* We need to handle deletion of windows underneath us.
3850      * If we add a "w_python*_ref" field to the win_T structure,
3851      * then we can get at it in win_free() in vim. We then
3852      * need to create only ONE Python object per window - if
3853      * we try to create a second, just INCREF the existing one
3854      * and return it. The (single) Python object referring to
3855      * the window is stored in "w_python*_ref".
3856      * On a win_free() we set the Python object's win_T* field
3857      * to an invalid value. We trap all uses of a window
3858      * object, and reject them if the win_T* field is invalid.
3859      *
3860      * Python2 and Python3 get different fields and different objects:
3861      * w_python_ref and w_python3_ref fields respectively.
3862      */
3863 
3864     WindowObject *self;
3865 
3866     if (WIN_PYTHON_REF(win))
3867     {
3868 	self = WIN_PYTHON_REF(win);
3869 	Py_INCREF(self);
3870     }
3871     else
3872     {
3873 	self = PyObject_GC_New(WindowObject, &WindowType);
3874 	if (self == NULL)
3875 	    return NULL;
3876 	self->win = win;
3877 	WIN_PYTHON_REF(win) = self;
3878     }
3879 
3880     self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3881 
3882     return (PyObject *)(self);
3883 }
3884 
3885     static void
3886 WindowDestructor(WindowObject *self)
3887 {
3888     PyObject_GC_UnTrack((void *)(self));
3889     if (self->win && self->win != INVALID_WINDOW_VALUE)
3890 	WIN_PYTHON_REF(self->win) = NULL;
3891      Py_XDECREF(((PyObject *)(self->tabObject)));
3892     PyObject_GC_Del((void *)(self));
3893 }
3894 
3895     static int
3896 WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3897 {
3898     Py_VISIT(((PyObject *)(self->tabObject)));
3899     return 0;
3900 }
3901 
3902     static int
3903 WindowClear(WindowObject *self)
3904 {
3905     Py_CLEAR(self->tabObject);
3906     return 0;
3907 }
3908 
3909     static win_T *
3910 get_firstwin(TabPageObject *tabObject)
3911 {
3912     if (tabObject)
3913     {
3914 	if (CheckTabPage(tabObject))
3915 	    return NULL;
3916 	/* For current tab window.c does not bother to set or update tp_firstwin
3917 	 */
3918 	else if (tabObject->tab == curtab)
3919 	    return firstwin;
3920 	else
3921 	    return tabObject->tab->tp_firstwin;
3922     }
3923     else
3924 	return firstwin;
3925 }
3926 
3927 // Use the same order as in the WindowAttr() function.
3928 static char *WindowAttrs[] = {
3929     "buffer",
3930     "cursor",
3931     "height",
3932     "row",
3933     "width",
3934     "col",
3935     "vars",
3936     "options",
3937     "number",
3938     "tabpage",
3939     "valid",
3940     NULL
3941 };
3942 
3943     static PyObject *
3944 WindowDir(PyObject *self)
3945 {
3946     return ObjectDir(self, WindowAttrs);
3947 }
3948 
3949     static PyObject *
3950 WindowAttrValid(WindowObject *self, char *name)
3951 {
3952     PyObject	*ret;
3953 
3954     if (strcmp(name, "valid") != 0)
3955 	return NULL;
3956 
3957     ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3958     Py_INCREF(ret);
3959     return ret;
3960 }
3961 
3962     static PyObject *
3963 WindowAttr(WindowObject *self, char *name)
3964 {
3965     if (strcmp(name, "buffer") == 0)
3966 	return (PyObject *)BufferNew(self->win->w_buffer);
3967     else if (strcmp(name, "cursor") == 0)
3968     {
3969 	pos_T *pos = &self->win->w_cursor;
3970 
3971 	return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3972     }
3973     else if (strcmp(name, "height") == 0)
3974 	return PyLong_FromLong((long)(self->win->w_height));
3975     else if (strcmp(name, "row") == 0)
3976 	return PyLong_FromLong((long)(self->win->w_winrow));
3977     else if (strcmp(name, "width") == 0)
3978 	return PyLong_FromLong((long)(self->win->w_width));
3979     else if (strcmp(name, "col") == 0)
3980 	return PyLong_FromLong((long)(self->win->w_wincol));
3981     else if (strcmp(name, "vars") == 0)
3982 	return NEW_DICTIONARY(self->win->w_vars);
3983     else if (strcmp(name, "options") == 0)
3984 	return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3985 			(PyObject *) self);
3986     else if (strcmp(name, "number") == 0)
3987     {
3988 	if (CheckTabPage(self->tabObject))
3989 	    return NULL;
3990 	return PyLong_FromLong((long)
3991 		get_win_number(self->win, get_firstwin(self->tabObject)));
3992     }
3993     else if (strcmp(name, "tabpage") == 0)
3994     {
3995 	Py_INCREF(self->tabObject);
3996 	return (PyObject *)(self->tabObject);
3997     }
3998     else if (strcmp(name, "__members__") == 0)
3999 	return ObjectDir(NULL, WindowAttrs);
4000     else
4001 	return NULL;
4002 }
4003 
4004     static int
4005 WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
4006 {
4007     if (CheckWindow(self))
4008 	return -1;
4009 
4010     if (strcmp(name, "buffer") == 0)
4011     {
4012 	PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
4013 	return -1;
4014     }
4015     else if (strcmp(name, "cursor") == 0)
4016     {
4017 	long lnum;
4018 	long col;
4019 
4020 	if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
4021 	    return -1;
4022 
4023 	if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
4024 	{
4025 	    PyErr_SET_VIM(N_("cursor position outside buffer"));
4026 	    return -1;
4027 	}
4028 
4029 	/* Check for keyboard interrupts */
4030 	if (VimCheckInterrupt())
4031 	    return -1;
4032 
4033 	self->win->w_cursor.lnum = lnum;
4034 	self->win->w_cursor.col = col;
4035 	self->win->w_set_curswant = TRUE;
4036 	self->win->w_cursor.coladd = 0;
4037 	/* When column is out of range silently correct it. */
4038 	check_cursor_col_win(self->win);
4039 
4040 	update_screen(VALID);
4041 	return 0;
4042     }
4043     else if (strcmp(name, "height") == 0)
4044     {
4045 	long	height;
4046 	win_T	*savewin;
4047 
4048 	if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
4049 	    return -1;
4050 
4051 #ifdef FEAT_GUI
4052 	need_mouse_correct = TRUE;
4053 #endif
4054 	savewin = curwin;
4055 	curwin = self->win;
4056 
4057 	VimTryStart();
4058 	win_setheight((int) height);
4059 	curwin = savewin;
4060 	if (VimTryEnd())
4061 	    return -1;
4062 
4063 	return 0;
4064     }
4065     else if (strcmp(name, "width") == 0)
4066     {
4067 	long	width;
4068 	win_T	*savewin;
4069 
4070 	if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
4071 	    return -1;
4072 
4073 #ifdef FEAT_GUI
4074 	need_mouse_correct = TRUE;
4075 #endif
4076 	savewin = curwin;
4077 	curwin = self->win;
4078 
4079 	VimTryStart();
4080 	win_setwidth((int) width);
4081 	curwin = savewin;
4082 	if (VimTryEnd())
4083 	    return -1;
4084 
4085 	return 0;
4086     }
4087     else
4088     {
4089 	PyErr_SetString(PyExc_AttributeError, name);
4090 	return -1;
4091     }
4092 }
4093 
4094     static PyObject *
4095 WindowRepr(WindowObject *self)
4096 {
4097     if (self->win == INVALID_WINDOW_VALUE)
4098 	return PyString_FromFormat("<window object (deleted) at %p>", (self));
4099     else
4100     {
4101 	int	w = get_win_number(self->win, firstwin);
4102 
4103 	if (w == 0)
4104 	    return PyString_FromFormat("<window object (unknown) at %p>",
4105 								      (self));
4106 	else
4107 	    return PyString_FromFormat("<window %d>", w - 1);
4108     }
4109 }
4110 
4111 static struct PyMethodDef WindowMethods[] = {
4112     /* name,	    function,			calling,	documentation */
4113     {"__dir__",	    (PyCFunction)WindowDir,	METH_NOARGS,	""},
4114     { NULL,	    NULL,			0,		NULL}
4115 };
4116 
4117 /*
4118  * Window list object
4119  */
4120 
4121 static PyTypeObject WinListType;
4122 static PySequenceMethods WinListAsSeq;
4123 
4124 typedef struct
4125 {
4126     PyObject_HEAD
4127     TabPageObject	*tabObject;
4128 } WinListObject;
4129 
4130     static PyObject *
4131 WinListNew(TabPageObject *tabObject)
4132 {
4133     WinListObject	*self;
4134 
4135     self = PyObject_NEW(WinListObject, &WinListType);
4136     self->tabObject = tabObject;
4137     Py_INCREF(tabObject);
4138 
4139     return (PyObject *)(self);
4140 }
4141 
4142     static void
4143 WinListDestructor(WinListObject *self)
4144 {
4145     TabPageObject	*tabObject = self->tabObject;
4146 
4147     if (tabObject)
4148     {
4149 	Py_DECREF((PyObject *)(tabObject));
4150     }
4151 
4152     DESTRUCTOR_FINISH(self);
4153 }
4154 
4155     static PyInt
4156 WinListLength(WinListObject *self)
4157 {
4158     win_T	*w;
4159     PyInt	n = 0;
4160 
4161     if (!(w = get_firstwin(self->tabObject)))
4162 	return -1;
4163 
4164     while (w != NULL)
4165     {
4166 	++n;
4167 	w = W_NEXT(w);
4168     }
4169 
4170     return n;
4171 }
4172 
4173     static PyObject *
4174 WinListItem(WinListObject *self, PyInt n)
4175 {
4176     win_T *w;
4177 
4178     if (!(w = get_firstwin(self->tabObject)))
4179 	return NULL;
4180 
4181     for (; w != NULL; w = W_NEXT(w), --n)
4182 	if (n == 0)
4183 	    return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
4184 
4185     PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
4186     return NULL;
4187 }
4188 
4189 /* Convert a Python string into a Vim line.
4190  *
4191  * The result is in allocated memory. All internal nulls are replaced by
4192  * newline characters. It is an error for the string to contain newline
4193  * characters.
4194  *
4195  * On errors, the Python exception data is set, and NULL is returned.
4196  */
4197     static char *
4198 StringToLine(PyObject *obj)
4199 {
4200     char	*str;
4201     char	*save;
4202     PyObject	*bytes = NULL;
4203     Py_ssize_t	len = 0;
4204     PyInt	i;
4205     char	*p;
4206 
4207     if (PyBytes_Check(obj))
4208     {
4209 	if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
4210 		|| str == NULL)
4211 	    return NULL;
4212     }
4213     else if (PyUnicode_Check(obj))
4214     {
4215 	if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
4216 	    return NULL;
4217 
4218 	if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
4219 		|| str == NULL)
4220 	{
4221 	    Py_DECREF(bytes);
4222 	    return NULL;
4223 	}
4224     }
4225     else
4226     {
4227 #if PY_MAJOR_VERSION < 3
4228 	PyErr_FORMAT(PyExc_TypeError,
4229 		N_("expected str() or unicode() instance, but got %s"),
4230 		Py_TYPE_NAME(obj));
4231 #else
4232 	PyErr_FORMAT(PyExc_TypeError,
4233 		N_("expected bytes() or str() instance, but got %s"),
4234 		Py_TYPE_NAME(obj));
4235 #endif
4236 	return NULL;
4237     }
4238 
4239     /*
4240      * Error checking: String must not contain newlines, as we
4241      * are replacing a single line, and we must replace it with
4242      * a single line.
4243      * A trailing newline is removed, so that append(f.readlines()) works.
4244      */
4245     p = memchr(str, '\n', len);
4246     if (p != NULL)
4247     {
4248 	if (p == str + len - 1)
4249 	    --len;
4250 	else
4251 	{
4252 	    PyErr_SET_VIM(N_("string cannot contain newlines"));
4253 	    Py_XDECREF(bytes);
4254 	    return NULL;
4255 	}
4256     }
4257 
4258     /* Create a copy of the string, with internal nulls replaced by
4259      * newline characters, as is the vim convention.
4260      */
4261     save = (char *)alloc((unsigned)(len+1));
4262     if (save == NULL)
4263     {
4264 	PyErr_NoMemory();
4265 	Py_XDECREF(bytes);
4266 	return NULL;
4267     }
4268 
4269     for (i = 0; i < len; ++i)
4270     {
4271 	if (str[i] == '\0')
4272 	    save[i] = '\n';
4273 	else
4274 	    save[i] = str[i];
4275     }
4276 
4277     save[i] = '\0';
4278     Py_XDECREF(bytes);  /* Python 2 does nothing here */
4279 
4280     return save;
4281 }
4282 
4283 /* Get a line from the specified buffer. The line number is
4284  * in Vim format (1-based). The line is returned as a Python
4285  * string object.
4286  */
4287     static PyObject *
4288 GetBufferLine(buf_T *buf, PyInt n)
4289 {
4290     return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
4291 }
4292 
4293 
4294 /* Get a list of lines from the specified buffer. The line numbers
4295  * are in Vim format (1-based). The range is from lo up to, but not
4296  * including, hi. The list is returned as a Python list of string objects.
4297  */
4298     static PyObject *
4299 GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
4300 {
4301     PyInt	i;
4302     PyInt	n = hi - lo;
4303     PyObject	*list = PyList_New(n);
4304 
4305     if (list == NULL)
4306 	return NULL;
4307 
4308     for (i = 0; i < n; ++i)
4309     {
4310 	PyObject	*string = LineToString(
4311 		(char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
4312 
4313 	/* Error check - was the Python string creation OK? */
4314 	if (string == NULL)
4315 	{
4316 	    Py_DECREF(list);
4317 	    return NULL;
4318 	}
4319 
4320 	PyList_SET_ITEM(list, i, string);
4321     }
4322 
4323     /* The ownership of the Python list is passed to the caller (ie,
4324      * the caller should Py_DECREF() the object when it is finished
4325      * with it).
4326      */
4327 
4328     return list;
4329 }
4330 
4331 /*
4332  * Check if deleting lines made the cursor position invalid.
4333  * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
4334  * deleted).
4335  */
4336     static void
4337 py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
4338 {
4339     if (curwin->w_cursor.lnum >= lo)
4340     {
4341 	/* Adjust the cursor position if it's in/after the changed
4342 	 * lines. */
4343 	if (curwin->w_cursor.lnum >= hi)
4344 	{
4345 	    curwin->w_cursor.lnum += extra;
4346 	    check_cursor_col();
4347 	}
4348 	else if (extra < 0)
4349 	{
4350 	    curwin->w_cursor.lnum = lo;
4351 	    check_cursor();
4352 	}
4353 	else
4354 	    check_cursor_col();
4355 	changed_cline_bef_curs();
4356     }
4357     invalidate_botline();
4358 }
4359 
4360 /*
4361  * Replace a line in the specified buffer. The line number is
4362  * in Vim format (1-based). The replacement line is given as
4363  * a Python string object. The object is checked for validity
4364  * and correct format. Errors are returned as a value of FAIL.
4365  * The return value is OK on success.
4366  * If OK is returned and len_change is not NULL, *len_change
4367  * is set to the change in the buffer length.
4368  */
4369     static int
4370 SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
4371 {
4372     bufref_T	save_curbuf = {NULL, 0, 0};
4373     win_T	*save_curwin = NULL;
4374     tabpage_T	*save_curtab = NULL;
4375 
4376     /* First of all, we check the type of the supplied Python object.
4377      * There are three cases:
4378      *	  1. NULL, or None - this is a deletion.
4379      *	  2. A string	   - this is a replacement.
4380      *	  3. Anything else - this is an error.
4381      */
4382     if (line == Py_None || line == NULL)
4383     {
4384 	PyErr_Clear();
4385 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4386 
4387 	VimTryStart();
4388 
4389 	if (u_savedel((linenr_T)n, 1L) == FAIL)
4390 	    RAISE_UNDO_FAIL;
4391 	else if (ml_delete((linenr_T)n, FALSE) == FAIL)
4392 	    RAISE_DELETE_LINE_FAIL;
4393 	else
4394 	{
4395 	    if (buf == curbuf)
4396 		py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
4397 	    if (save_curbuf.br_buf == NULL)
4398 		/* Only adjust marks if we managed to switch to a window that
4399 		 * holds the buffer, otherwise line numbers will be invalid. */
4400 		deleted_lines_mark((linenr_T)n, 1L);
4401 	}
4402 
4403 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4404 
4405 	if (VimTryEnd())
4406 	    return FAIL;
4407 
4408 	if (len_change)
4409 	    *len_change = -1;
4410 
4411 	return OK;
4412     }
4413     else if (PyBytes_Check(line) || PyUnicode_Check(line))
4414     {
4415 	char	*save = StringToLine(line);
4416 
4417 	if (save == NULL)
4418 	    return FAIL;
4419 
4420 	VimTryStart();
4421 
4422 	/* We do not need to free "save" if ml_replace() consumes it. */
4423 	PyErr_Clear();
4424 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4425 
4426 	if (u_savesub((linenr_T)n) == FAIL)
4427 	{
4428 	    RAISE_UNDO_FAIL;
4429 	    vim_free(save);
4430 	}
4431 	else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
4432 	{
4433 	    RAISE_REPLACE_LINE_FAIL;
4434 	    vim_free(save);
4435 	}
4436 	else
4437 	    changed_bytes((linenr_T)n, 0);
4438 
4439 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4440 
4441 	/* Check that the cursor is not beyond the end of the line now. */
4442 	if (buf == curbuf)
4443 	    check_cursor_col();
4444 
4445 	if (VimTryEnd())
4446 	    return FAIL;
4447 
4448 	if (len_change)
4449 	    *len_change = 0;
4450 
4451 	return OK;
4452     }
4453     else
4454     {
4455 	PyErr_BadArgument();
4456 	return FAIL;
4457     }
4458 }
4459 
4460 /* Replace a range of lines in the specified buffer. The line numbers are in
4461  * Vim format (1-based). The range is from lo up to, but not including, hi.
4462  * The replacement lines are given as a Python list of string objects. The
4463  * list is checked for validity and correct format. Errors are returned as a
4464  * value of FAIL.  The return value is OK on success.
4465  * If OK is returned and len_change is not NULL, *len_change
4466  * is set to the change in the buffer length.
4467  */
4468     static int
4469 SetBufferLineList(
4470 	buf_T *buf,
4471 	PyInt lo,
4472 	PyInt hi,
4473 	PyObject *list,
4474 	PyInt *len_change)
4475 {
4476     bufref_T	save_curbuf = {NULL, 0, 0};
4477     win_T	*save_curwin = NULL;
4478     tabpage_T	*save_curtab = NULL;
4479 
4480     /* First of all, we check the type of the supplied Python object.
4481      * There are three cases:
4482      *	  1. NULL, or None - this is a deletion.
4483      *	  2. A list	   - this is a replacement.
4484      *	  3. Anything else - this is an error.
4485      */
4486     if (list == Py_None || list == NULL)
4487     {
4488 	PyInt	i;
4489 	PyInt	n = (int)(hi - lo);
4490 
4491 	PyErr_Clear();
4492 	VimTryStart();
4493 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4494 
4495 	if (u_savedel((linenr_T)lo, (long)n) == FAIL)
4496 	    RAISE_UNDO_FAIL;
4497 	else
4498 	{
4499 	    for (i = 0; i < n; ++i)
4500 	    {
4501 		if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4502 		{
4503 		    RAISE_DELETE_LINE_FAIL;
4504 		    break;
4505 		}
4506 	    }
4507 	    if (buf == curbuf && (save_curwin != NULL
4508 					       || save_curbuf.br_buf == NULL))
4509 		/* Using an existing window for the buffer, adjust the cursor
4510 		 * position. */
4511 		py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
4512 	    if (save_curbuf.br_buf == NULL)
4513 		/* Only adjust marks if we managed to switch to a window that
4514 		 * holds the buffer, otherwise line numbers will be invalid. */
4515 		deleted_lines_mark((linenr_T)lo, (long)i);
4516 	}
4517 
4518 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4519 
4520 	if (VimTryEnd())
4521 	    return FAIL;
4522 
4523 	if (len_change)
4524 	    *len_change = -n;
4525 
4526 	return OK;
4527     }
4528     else if (PyList_Check(list))
4529     {
4530 	PyInt	i;
4531 	PyInt	new_len = PyList_Size(list);
4532 	PyInt	old_len = hi - lo;
4533 	PyInt	extra = 0;	/* lines added to text, can be negative */
4534 	char	**array;
4535 
4536 	if (new_len == 0)	/* avoid allocating zero bytes */
4537 	    array = NULL;
4538 	else
4539 	{
4540 	    array = PyMem_New(char *, new_len);
4541 	    if (array == NULL)
4542 	    {
4543 		PyErr_NoMemory();
4544 		return FAIL;
4545 	    }
4546 	}
4547 
4548 	for (i = 0; i < new_len; ++i)
4549 	{
4550 	    PyObject *line;
4551 
4552 	    if (!(line = PyList_GetItem(list, i)) ||
4553 		!(array[i] = StringToLine(line)))
4554 	    {
4555 		while (i)
4556 		    vim_free(array[--i]);
4557 		PyMem_Free(array);
4558 		return FAIL;
4559 	    }
4560 	}
4561 
4562 	VimTryStart();
4563 	PyErr_Clear();
4564 
4565 	/* START of region without "return".  Must call restore_buffer()! */
4566 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4567 
4568 	if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
4569 	    RAISE_UNDO_FAIL;
4570 
4571 	/* If the size of the range is reducing (ie, new_len < old_len) we
4572 	 * need to delete some old_len. We do this at the start, by
4573 	 * repeatedly deleting line "lo".
4574 	 */
4575 	if (!PyErr_Occurred())
4576 	{
4577 	    for (i = 0; i < old_len - new_len; ++i)
4578 		if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4579 		{
4580 		    RAISE_DELETE_LINE_FAIL;
4581 		    break;
4582 		}
4583 	    extra -= i;
4584 	}
4585 
4586 	/* For as long as possible, replace the existing old_len with the
4587 	 * new old_len. This is a more efficient operation, as it requires
4588 	 * less memory allocation and freeing.
4589 	 */
4590 	if (!PyErr_Occurred())
4591 	{
4592 	    for (i = 0; i < old_len && i < new_len; ++i)
4593 		if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
4594 								      == FAIL)
4595 		{
4596 		    RAISE_REPLACE_LINE_FAIL;
4597 		    break;
4598 		}
4599 	}
4600 	else
4601 	    i = 0;
4602 
4603 	/* Now we may need to insert the remaining new old_len. If we do, we
4604 	 * must free the strings as we finish with them (we can't pass the
4605 	 * responsibility to vim in this case).
4606 	 */
4607 	if (!PyErr_Occurred())
4608 	{
4609 	    while (i < new_len)
4610 	    {
4611 		if (ml_append((linenr_T)(lo + i - 1),
4612 					(char_u *)array[i], 0, FALSE) == FAIL)
4613 		{
4614 		    RAISE_INSERT_LINE_FAIL;
4615 		    break;
4616 		}
4617 		vim_free(array[i]);
4618 		++i;
4619 		++extra;
4620 	    }
4621 	}
4622 
4623 	/* Free any left-over old_len, as a result of an error */
4624 	while (i < new_len)
4625 	{
4626 	    vim_free(array[i]);
4627 	    ++i;
4628 	}
4629 
4630 	/* Free the array of old_len. All of its contents have now
4631 	 * been dealt with (either freed, or the responsibility passed
4632 	 * to vim.
4633 	 */
4634 	PyMem_Free(array);
4635 
4636 	/* Adjust marks. Invalidate any which lie in the
4637 	 * changed range, and move any in the remainder of the buffer.
4638 	 * Only adjust marks if we managed to switch to a window that holds
4639 	 * the buffer, otherwise line numbers will be invalid. */
4640 	if (save_curbuf.br_buf == NULL)
4641 	    mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
4642 						  (long)MAXLNUM, (long)extra);
4643 	changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4644 
4645 	if (buf == curbuf)
4646 	    py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4647 
4648 	/* END of region without "return". */
4649 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4650 
4651 	if (VimTryEnd())
4652 	    return FAIL;
4653 
4654 	if (len_change)
4655 	    *len_change = new_len - old_len;
4656 
4657 	return OK;
4658     }
4659     else
4660     {
4661 	PyErr_BadArgument();
4662 	return FAIL;
4663     }
4664 }
4665 
4666 /* Insert a number of lines into the specified buffer after the specified line.
4667  * The line number is in Vim format (1-based). The lines to be inserted are
4668  * given as a Python list of string objects or as a single string. The lines
4669  * to be added are checked for validity and correct format. Errors are
4670  * returned as a value of FAIL.  The return value is OK on success.
4671  * If OK is returned and len_change is not NULL, *len_change
4672  * is set to the change in the buffer length.
4673  */
4674     static int
4675 InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4676 {
4677     bufref_T	save_curbuf = {NULL, 0, 0};
4678     win_T	*save_curwin = NULL;
4679     tabpage_T	*save_curtab = NULL;
4680 
4681     /* First of all, we check the type of the supplied Python object.
4682      * It must be a string or a list, or the call is in error.
4683      */
4684     if (PyBytes_Check(lines) || PyUnicode_Check(lines))
4685     {
4686 	char		*str = StringToLine(lines);
4687 
4688 	if (str == NULL)
4689 	    return FAIL;
4690 
4691 	PyErr_Clear();
4692 	VimTryStart();
4693 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4694 
4695 	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4696 	    RAISE_UNDO_FAIL;
4697 	else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
4698 	    RAISE_INSERT_LINE_FAIL;
4699 	else if (save_curbuf.br_buf == NULL)
4700 	    /* Only adjust marks if we managed to switch to a window that
4701 	     * holds the buffer, otherwise line numbers will be invalid. */
4702 	    appended_lines_mark((linenr_T)n, 1L);
4703 
4704 	vim_free(str);
4705 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4706 	update_screen(VALID);
4707 
4708 	if (VimTryEnd())
4709 	    return FAIL;
4710 
4711 	if (len_change)
4712 	    *len_change = 1;
4713 
4714 	return OK;
4715     }
4716     else if (PyList_Check(lines))
4717     {
4718 	PyInt	i;
4719 	PyInt	size = PyList_Size(lines);
4720 	char	**array;
4721 
4722 	array = PyMem_New(char *, size);
4723 	if (array == NULL)
4724 	{
4725 	    PyErr_NoMemory();
4726 	    return FAIL;
4727 	}
4728 
4729 	for (i = 0; i < size; ++i)
4730 	{
4731 	    PyObject *line;
4732 
4733 	    if (!(line = PyList_GetItem(lines, i)) ||
4734 		!(array[i] = StringToLine(line)))
4735 	    {
4736 		while (i)
4737 		    vim_free(array[--i]);
4738 		PyMem_Free(array);
4739 		return FAIL;
4740 	    }
4741 	}
4742 
4743 	PyErr_Clear();
4744 	VimTryStart();
4745 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4746 
4747 	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4748 	    RAISE_UNDO_FAIL;
4749 	else
4750 	{
4751 	    for (i = 0; i < size; ++i)
4752 	    {
4753 		if (ml_append((linenr_T)(n + i),
4754 					(char_u *)array[i], 0, FALSE) == FAIL)
4755 		{
4756 		    RAISE_INSERT_LINE_FAIL;
4757 
4758 		    /* Free the rest of the lines */
4759 		    while (i < size)
4760 			vim_free(array[i++]);
4761 
4762 		    break;
4763 		}
4764 		vim_free(array[i]);
4765 	    }
4766 	    if (i > 0 && save_curbuf.br_buf == NULL)
4767 		/* Only adjust marks if we managed to switch to a window that
4768 		 * holds the buffer, otherwise line numbers will be invalid. */
4769 		appended_lines_mark((linenr_T)n, (long)i);
4770 	}
4771 
4772 	/* Free the array of lines. All of its contents have now
4773 	 * been freed. */
4774 	PyMem_Free(array);
4775 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4776 
4777 	update_screen(VALID);
4778 
4779 	if (VimTryEnd())
4780 	    return FAIL;
4781 
4782 	if (len_change)
4783 	    *len_change = size;
4784 
4785 	return OK;
4786     }
4787     else
4788     {
4789 	PyErr_BadArgument();
4790 	return FAIL;
4791     }
4792 }
4793 
4794 /*
4795  * Common routines for buffers and line ranges
4796  * -------------------------------------------
4797  */
4798 
4799 typedef struct
4800 {
4801     PyObject_HEAD
4802     buf_T *buf;
4803 } BufferObject;
4804 
4805     static int
4806 CheckBuffer(BufferObject *self)
4807 {
4808     if (self->buf == INVALID_BUFFER_VALUE)
4809     {
4810 	PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
4811 	return -1;
4812     }
4813 
4814     return 0;
4815 }
4816 
4817     static PyObject *
4818 RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4819 {
4820     if (CheckBuffer(self))
4821 	return NULL;
4822 
4823     if (end == -1)
4824 	end = self->buf->b_ml.ml_line_count;
4825 
4826     if (n < 0)
4827 	n += end - start + 1;
4828 
4829     if (n < 0 || n > end - start)
4830     {
4831 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
4832 	return NULL;
4833     }
4834 
4835     return GetBufferLine(self->buf, n+start);
4836 }
4837 
4838     static PyObject *
4839 RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4840 {
4841     PyInt size;
4842 
4843     if (CheckBuffer(self))
4844 	return NULL;
4845 
4846     if (end == -1)
4847 	end = self->buf->b_ml.ml_line_count;
4848 
4849     size = end - start + 1;
4850 
4851     if (lo < 0)
4852 	lo = 0;
4853     else if (lo > size)
4854 	lo = size;
4855     if (hi < 0)
4856 	hi = 0;
4857     if (hi < lo)
4858 	hi = lo;
4859     else if (hi > size)
4860 	hi = size;
4861 
4862     return GetBufferLineList(self->buf, lo+start, hi+start);
4863 }
4864 
4865     static PyInt
4866 RBAsItem(
4867 	BufferObject *self,
4868 	PyInt n,
4869 	PyObject *valObject,
4870 	PyInt start,
4871 	PyInt end,
4872 	PyInt *new_end)
4873 {
4874     PyInt len_change;
4875 
4876     if (CheckBuffer(self))
4877 	return -1;
4878 
4879     if (end == -1)
4880 	end = self->buf->b_ml.ml_line_count;
4881 
4882     if (n < 0)
4883 	n += end - start + 1;
4884 
4885     if (n < 0 || n > end - start)
4886     {
4887 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
4888 	return -1;
4889     }
4890 
4891     if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
4892 	return -1;
4893 
4894     if (new_end)
4895 	*new_end = end + len_change;
4896 
4897     return 0;
4898 }
4899 
4900     static PyInt
4901 RBAsSlice(
4902 	BufferObject *self,
4903 	PyInt lo,
4904 	PyInt hi,
4905 	PyObject *valObject,
4906 	PyInt start,
4907 	PyInt end,
4908 	PyInt *new_end)
4909 {
4910     PyInt size;
4911     PyInt len_change;
4912 
4913     /* Self must be a valid buffer */
4914     if (CheckBuffer(self))
4915 	return -1;
4916 
4917     if (end == -1)
4918 	end = self->buf->b_ml.ml_line_count;
4919 
4920     /* Sort out the slice range */
4921     size = end - start + 1;
4922 
4923     if (lo < 0)
4924 	lo = 0;
4925     else if (lo > size)
4926 	lo = size;
4927     if (hi < 0)
4928 	hi = 0;
4929     if (hi < lo)
4930 	hi = lo;
4931     else if (hi > size)
4932 	hi = size;
4933 
4934     if (SetBufferLineList(self->buf, lo + start, hi + start,
4935 						valObject, &len_change) == FAIL)
4936 	return -1;
4937 
4938     if (new_end)
4939 	*new_end = end + len_change;
4940 
4941     return 0;
4942 }
4943 
4944 
4945     static PyObject *
4946 RBAppend(
4947 	BufferObject *self,
4948 	PyObject *args,
4949 	PyInt start,
4950 	PyInt end,
4951 	PyInt *new_end)
4952 {
4953     PyObject *lines;
4954     PyInt len_change;
4955     PyInt max;
4956     PyInt n;
4957 
4958     if (CheckBuffer(self))
4959 	return NULL;
4960 
4961     if (end == -1)
4962 	end = self->buf->b_ml.ml_line_count;
4963 
4964     max = n = end - start + 1;
4965 
4966     if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4967 	return NULL;
4968 
4969     if (n < 0 || n > max)
4970     {
4971 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
4972 	return NULL;
4973     }
4974 
4975     if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4976 	return NULL;
4977 
4978     if (new_end)
4979 	*new_end = end + len_change;
4980 
4981     Py_INCREF(Py_None);
4982     return Py_None;
4983 }
4984 
4985 /* Range object
4986  */
4987 
4988 static PyTypeObject RangeType;
4989 static PySequenceMethods RangeAsSeq;
4990 static PyMappingMethods RangeAsMapping;
4991 
4992 typedef struct
4993 {
4994     PyObject_HEAD
4995     BufferObject *buf;
4996     PyInt start;
4997     PyInt end;
4998 } RangeObject;
4999 
5000     static PyObject *
5001 RangeNew(buf_T *buf, PyInt start, PyInt end)
5002 {
5003     BufferObject *bufr;
5004     RangeObject *self;
5005     self = PyObject_GC_New(RangeObject, &RangeType);
5006     if (self == NULL)
5007 	return NULL;
5008 
5009     bufr = (BufferObject *)BufferNew(buf);
5010     if (bufr == NULL)
5011     {
5012 	Py_DECREF(self);
5013 	return NULL;
5014     }
5015     Py_INCREF(bufr);
5016 
5017     self->buf = bufr;
5018     self->start = start;
5019     self->end = end;
5020 
5021     return (PyObject *)(self);
5022 }
5023 
5024     static void
5025 RangeDestructor(RangeObject *self)
5026 {
5027     PyObject_GC_UnTrack((void *)(self));
5028     Py_XDECREF(self->buf);
5029     PyObject_GC_Del((void *)(self));
5030 }
5031 
5032     static int
5033 RangeTraverse(RangeObject *self, visitproc visit, void *arg)
5034 {
5035     Py_VISIT(((PyObject *)(self->buf)));
5036     return 0;
5037 }
5038 
5039     static int
5040 RangeClear(RangeObject *self)
5041 {
5042     Py_CLEAR(self->buf);
5043     return 0;
5044 }
5045 
5046     static PyInt
5047 RangeLength(RangeObject *self)
5048 {
5049     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
5050     if (CheckBuffer(self->buf))
5051 	return -1; /* ??? */
5052 
5053     return (self->end - self->start + 1);
5054 }
5055 
5056     static PyObject *
5057 RangeItem(RangeObject *self, PyInt n)
5058 {
5059     return RBItem(self->buf, n, self->start, self->end);
5060 }
5061 
5062     static PyObject *
5063 RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
5064 {
5065     return RBSlice(self->buf, lo, hi, self->start, self->end);
5066 }
5067 
5068 static char *RangeAttrs[] = {
5069     "start", "end",
5070     NULL
5071 };
5072 
5073     static PyObject *
5074 RangeDir(PyObject *self)
5075 {
5076     return ObjectDir(self, RangeAttrs);
5077 }
5078 
5079     static PyObject *
5080 RangeAppend(RangeObject *self, PyObject *args)
5081 {
5082     return RBAppend(self->buf, args, self->start, self->end, &self->end);
5083 }
5084 
5085     static PyObject *
5086 RangeRepr(RangeObject *self)
5087 {
5088     if (self->buf->buf == INVALID_BUFFER_VALUE)
5089 	return PyString_FromFormat("<range object (for deleted buffer) at %p>",
5090 				    (self));
5091     else
5092     {
5093 	char *name = (char *)self->buf->buf->b_fname;
5094 
5095 	if (name == NULL)
5096 	    name = "";
5097 
5098 	return PyString_FromFormat("<range %s (%d:%d)>",
5099 				    name, (int)self->start, (int)self->end);
5100     }
5101 }
5102 
5103 static struct PyMethodDef RangeMethods[] = {
5104     /* name,	function,			calling,	documentation */
5105     {"append",	(PyCFunction)RangeAppend,	METH_VARARGS,	"Append data to the Vim range" },
5106     {"__dir__",	(PyCFunction)RangeDir,		METH_NOARGS,	""},
5107     { NULL,	NULL,				0,		NULL}
5108 };
5109 
5110 static PyTypeObject BufferType;
5111 static PySequenceMethods BufferAsSeq;
5112 static PyMappingMethods BufferAsMapping;
5113 
5114     static PyObject *
5115 BufferNew(buf_T *buf)
5116 {
5117     /* We need to handle deletion of buffers underneath us.
5118      * If we add a "b_python*_ref" field to the buf_T structure,
5119      * then we can get at it in buf_freeall() in vim. We then
5120      * need to create only ONE Python object per buffer - if
5121      * we try to create a second, just INCREF the existing one
5122      * and return it. The (single) Python object referring to
5123      * the buffer is stored in "b_python*_ref".
5124      * Question: what to do on a buf_freeall(). We'll probably
5125      * have to either delete the Python object (DECREF it to
5126      * zero - a bad idea, as it leaves dangling refs!) or
5127      * set the buf_T * value to an invalid value (-1?), which
5128      * means we need checks in all access functions... Bah.
5129      *
5130      * Python2 and Python3 get different fields and different objects:
5131      * b_python_ref and b_python3_ref fields respectively.
5132      */
5133 
5134     BufferObject *self;
5135 
5136     if (BUF_PYTHON_REF(buf) != NULL)
5137     {
5138 	self = BUF_PYTHON_REF(buf);
5139 	Py_INCREF(self);
5140     }
5141     else
5142     {
5143 	self = PyObject_NEW(BufferObject, &BufferType);
5144 	if (self == NULL)
5145 	    return NULL;
5146 	self->buf = buf;
5147 	BUF_PYTHON_REF(buf) = self;
5148     }
5149 
5150     return (PyObject *)(self);
5151 }
5152 
5153     static void
5154 BufferDestructor(BufferObject *self)
5155 {
5156     if (self->buf && self->buf != INVALID_BUFFER_VALUE)
5157 	BUF_PYTHON_REF(self->buf) = NULL;
5158 
5159     DESTRUCTOR_FINISH(self);
5160 }
5161 
5162     static PyInt
5163 BufferLength(BufferObject *self)
5164 {
5165     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
5166     if (CheckBuffer(self))
5167 	return -1; /* ??? */
5168 
5169     return (PyInt)(self->buf->b_ml.ml_line_count);
5170 }
5171 
5172     static PyObject *
5173 BufferItem(BufferObject *self, PyInt n)
5174 {
5175     return RBItem(self, n, 1, -1);
5176 }
5177 
5178     static PyObject *
5179 BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
5180 {
5181     return RBSlice(self, lo, hi, 1, -1);
5182 }
5183 
5184 static char *BufferAttrs[] = {
5185     "name", "number", "vars", "options", "valid",
5186     NULL
5187 };
5188 
5189     static PyObject *
5190 BufferDir(PyObject *self)
5191 {
5192     return ObjectDir(self, BufferAttrs);
5193 }
5194 
5195     static PyObject *
5196 BufferAttrValid(BufferObject *self, char *name)
5197 {
5198     PyObject	*ret;
5199 
5200     if (strcmp(name, "valid") != 0)
5201 	return NULL;
5202 
5203     ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
5204     Py_INCREF(ret);
5205     return ret;
5206 }
5207 
5208     static PyObject *
5209 BufferAttr(BufferObject *self, char *name)
5210 {
5211     if (strcmp(name, "name") == 0)
5212 	return PyString_FromString((self->buf->b_ffname == NULL
5213 				    ? "" : (char *)self->buf->b_ffname));
5214     else if (strcmp(name, "number") == 0)
5215 	return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
5216     else if (strcmp(name, "vars") == 0)
5217 	return NEW_DICTIONARY(self->buf->b_vars);
5218     else if (strcmp(name, "options") == 0)
5219 	return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
5220 			(PyObject *) self);
5221     else if (strcmp(name, "__members__") == 0)
5222 	return ObjectDir(NULL, BufferAttrs);
5223     else
5224 	return NULL;
5225 }
5226 
5227     static int
5228 BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
5229 {
5230     if (CheckBuffer(self))
5231 	return -1;
5232 
5233     if (strcmp(name, "name") == 0)
5234     {
5235 	char_u		*val;
5236 	aco_save_T	aco;
5237 	int		ren_ret;
5238 	PyObject	*todecref;
5239 
5240 	if (!(val = StringToChars(valObject, &todecref)))
5241 	    return -1;
5242 
5243 	VimTryStart();
5244 	/* Using aucmd_*: autocommands will be executed by rename_buffer */
5245 	aucmd_prepbuf(&aco, self->buf);
5246 	ren_ret = rename_buffer(val);
5247 	aucmd_restbuf(&aco);
5248 	Py_XDECREF(todecref);
5249 	if (VimTryEnd())
5250 	    return -1;
5251 
5252 	if (ren_ret == FAIL)
5253 	{
5254 	    PyErr_SET_VIM(N_("failed to rename buffer"));
5255 	    return -1;
5256 	}
5257 	return 0;
5258     }
5259     else
5260     {
5261 	PyErr_SetString(PyExc_AttributeError, name);
5262 	return -1;
5263     }
5264 }
5265 
5266     static PyObject *
5267 BufferAppend(BufferObject *self, PyObject *args)
5268 {
5269     return RBAppend(self, args, 1, -1, NULL);
5270 }
5271 
5272     static PyObject *
5273 BufferMark(BufferObject *self, PyObject *pmarkObject)
5274 {
5275     pos_T	*posp;
5276     char_u	*pmark;
5277     char_u	mark;
5278     bufref_T	savebuf;
5279     PyObject	*todecref;
5280 
5281     if (CheckBuffer(self))
5282 	return NULL;
5283 
5284     if (!(pmark = StringToChars(pmarkObject, &todecref)))
5285 	return NULL;
5286 
5287     if (pmark[0] == '\0' || pmark[1] != '\0')
5288     {
5289 	PyErr_SET_STRING(PyExc_ValueError,
5290 		N_("mark name must be a single character"));
5291 	Py_XDECREF(todecref);
5292 	return NULL;
5293     }
5294 
5295     mark = *pmark;
5296 
5297     Py_XDECREF(todecref);
5298 
5299     VimTryStart();
5300     switch_buffer(&savebuf, self->buf);
5301     posp = getmark(mark, FALSE);
5302     restore_buffer(&savebuf);
5303     if (VimTryEnd())
5304 	return NULL;
5305 
5306     if (posp == NULL)
5307     {
5308 	PyErr_SET_VIM(N_("invalid mark name"));
5309 	return NULL;
5310     }
5311 
5312     if (posp->lnum <= 0)
5313     {
5314 	/* Or raise an error? */
5315 	Py_INCREF(Py_None);
5316 	return Py_None;
5317     }
5318 
5319     return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
5320 }
5321 
5322     static PyObject *
5323 BufferRange(BufferObject *self, PyObject *args)
5324 {
5325     PyInt start;
5326     PyInt end;
5327 
5328     if (CheckBuffer(self))
5329 	return NULL;
5330 
5331     if (!PyArg_ParseTuple(args, "nn", &start, &end))
5332 	return NULL;
5333 
5334     return RangeNew(self->buf, start, end);
5335 }
5336 
5337     static PyObject *
5338 BufferRepr(BufferObject *self)
5339 {
5340     if (self->buf == INVALID_BUFFER_VALUE)
5341 	return PyString_FromFormat("<buffer object (deleted) at %p>", self);
5342     else
5343     {
5344 	char	*name = (char *)self->buf->b_fname;
5345 
5346 	if (name == NULL)
5347 	    name = "";
5348 
5349 	return PyString_FromFormat("<buffer %s>", name);
5350     }
5351 }
5352 
5353 static struct PyMethodDef BufferMethods[] = {
5354     /* name,	    function,			calling,	documentation */
5355     {"append",	    (PyCFunction)BufferAppend,	METH_VARARGS,	"Append data to Vim buffer" },
5356     {"mark",	    (PyCFunction)BufferMark,	METH_O,		"Return (row,col) representing position of named mark" },
5357     {"range",	    (PyCFunction)BufferRange,	METH_VARARGS,	"Return a range object which represents the part of the given buffer between line numbers s and e" },
5358     {"__dir__",	    (PyCFunction)BufferDir,	METH_NOARGS,	""},
5359     { NULL,	    NULL,			0,		NULL}
5360 };
5361 
5362 /*
5363  * Buffer list object - Implementation
5364  */
5365 
5366 static PyTypeObject BufMapType;
5367 
5368 typedef struct
5369 {
5370     PyObject_HEAD
5371 } BufMapObject;
5372 
5373     static PyInt
5374 BufMapLength(PyObject *self UNUSED)
5375 {
5376     buf_T	*b = firstbuf;
5377     PyInt	n = 0;
5378 
5379     while (b)
5380     {
5381 	++n;
5382 	b = b->b_next;
5383     }
5384 
5385     return n;
5386 }
5387 
5388     static PyObject *
5389 BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
5390 {
5391     buf_T	*b;
5392     long	bnr;
5393 
5394     if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
5395 	return NULL;
5396 
5397     b = buflist_findnr((int) bnr);
5398 
5399     if (b)
5400 	return BufferNew(b);
5401     else
5402     {
5403 	PyErr_SetObject(PyExc_KeyError, keyObject);
5404 	return NULL;
5405     }
5406 }
5407 
5408     static void
5409 BufMapIterDestruct(PyObject *buffer)
5410 {
5411     /* Iteration was stopped before all buffers were processed */
5412     if (buffer)
5413     {
5414 	Py_DECREF(buffer);
5415     }
5416 }
5417 
5418     static int
5419 BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
5420 {
5421     if (buffer)
5422 	Py_VISIT(buffer);
5423     return 0;
5424 }
5425 
5426     static int
5427 BufMapIterClear(PyObject **buffer)
5428 {
5429     if (*buffer)
5430 	Py_CLEAR(*buffer);
5431     return 0;
5432 }
5433 
5434     static PyObject *
5435 BufMapIterNext(PyObject **buffer)
5436 {
5437     PyObject	*next;
5438     PyObject	*ret;
5439 
5440     if (!*buffer)
5441 	return NULL;
5442 
5443     ret = *buffer;
5444 
5445     if (CheckBuffer((BufferObject *)(ret)))
5446     {
5447 	*buffer = NULL;
5448 	return NULL;
5449     }
5450 
5451     if (!((BufferObject *)(ret))->buf->b_next)
5452 	next = NULL;
5453     else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
5454 	return NULL;
5455     *buffer = next;
5456     /* Do not increment reference: we no longer hold it (decref), but whoever
5457      * on other side will hold (incref). Decref+incref = nothing. */
5458     return ret;
5459 }
5460 
5461     static PyObject *
5462 BufMapIter(PyObject *self UNUSED)
5463 {
5464     PyObject *buffer;
5465 
5466     buffer = BufferNew(firstbuf);
5467     return IterNew(buffer,
5468 	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
5469 	    (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
5470 }
5471 
5472 static PyMappingMethods BufMapAsMapping = {
5473     (lenfunc)       BufMapLength,
5474     (binaryfunc)    BufMapItem,
5475     (objobjargproc) 0,
5476 };
5477 
5478 /* Current items object
5479  */
5480 
5481 static char *CurrentAttrs[] = {
5482     "buffer", "window", "line", "range", "tabpage",
5483     NULL
5484 };
5485 
5486     static PyObject *
5487 CurrentDir(PyObject *self)
5488 {
5489     return ObjectDir(self, CurrentAttrs);
5490 }
5491 
5492     static PyObject *
5493 CurrentGetattr(PyObject *self UNUSED, char *name)
5494 {
5495     if (strcmp(name, "buffer") == 0)
5496 	return (PyObject *)BufferNew(curbuf);
5497     else if (strcmp(name, "window") == 0)
5498 	return (PyObject *)WindowNew(curwin, curtab);
5499     else if (strcmp(name, "tabpage") == 0)
5500 	return (PyObject *)TabPageNew(curtab);
5501     else if (strcmp(name, "line") == 0)
5502 	return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
5503     else if (strcmp(name, "range") == 0)
5504 	return RangeNew(curbuf, RangeStart, RangeEnd);
5505     else if (strcmp(name, "__members__") == 0)
5506 	return ObjectDir(NULL, CurrentAttrs);
5507     else
5508 #if PY_MAJOR_VERSION < 3
5509 	return Py_FindMethod(WindowMethods, self, name);
5510 #else
5511 	return NULL;
5512 #endif
5513 }
5514 
5515     static int
5516 CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
5517 {
5518     if (strcmp(name, "line") == 0)
5519     {
5520 	if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
5521 			  NULL) == FAIL)
5522 	    return -1;
5523 
5524 	return 0;
5525     }
5526     else if (strcmp(name, "buffer") == 0)
5527     {
5528 	int count;
5529 
5530 	if (valObject->ob_type != &BufferType)
5531 	{
5532 	    PyErr_FORMAT(PyExc_TypeError,
5533 		    N_("expected vim.Buffer object, but got %s"),
5534 		    Py_TYPE_NAME(valObject));
5535 	    return -1;
5536 	}
5537 
5538 	if (CheckBuffer((BufferObject *)(valObject)))
5539 	    return -1;
5540 	count = ((BufferObject *)(valObject))->buf->b_fnum;
5541 
5542 	VimTryStart();
5543 	if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
5544 	{
5545 	    if (VimTryEnd())
5546 		return -1;
5547 	    PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
5548 	    return -1;
5549 	}
5550 
5551 	return VimTryEnd();
5552     }
5553     else if (strcmp(name, "window") == 0)
5554     {
5555 	int count;
5556 
5557 	if (valObject->ob_type != &WindowType)
5558 	{
5559 	    PyErr_FORMAT(PyExc_TypeError,
5560 		    N_("expected vim.Window object, but got %s"),
5561 		    Py_TYPE_NAME(valObject));
5562 	    return -1;
5563 	}
5564 
5565 	if (CheckWindow((WindowObject *)(valObject)))
5566 	    return -1;
5567 	count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
5568 
5569 	if (!count)
5570 	{
5571 	    PyErr_SET_STRING(PyExc_ValueError,
5572 		    N_("failed to find window in the current tab page"));
5573 	    return -1;
5574 	}
5575 
5576 	VimTryStart();
5577 	win_goto(((WindowObject *)(valObject))->win);
5578 	if (((WindowObject *)(valObject))->win != curwin)
5579 	{
5580 	    if (VimTryEnd())
5581 		return -1;
5582 	    PyErr_SET_STRING(PyExc_RuntimeError,
5583 		    N_("did not switch to the specified window"));
5584 	    return -1;
5585 	}
5586 
5587 	return VimTryEnd();
5588     }
5589     else if (strcmp(name, "tabpage") == 0)
5590     {
5591 	if (valObject->ob_type != &TabPageType)
5592 	{
5593 	    PyErr_FORMAT(PyExc_TypeError,
5594 		    N_("expected vim.TabPage object, but got %s"),
5595 		    Py_TYPE_NAME(valObject));
5596 	    return -1;
5597 	}
5598 
5599 	if (CheckTabPage((TabPageObject *)(valObject)))
5600 	    return -1;
5601 
5602 	VimTryStart();
5603 	goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5604 	if (((TabPageObject *)(valObject))->tab != curtab)
5605 	{
5606 	    if (VimTryEnd())
5607 		return -1;
5608 	    PyErr_SET_STRING(PyExc_RuntimeError,
5609 		    N_("did not switch to the specified tab page"));
5610 	    return -1;
5611 	}
5612 
5613 	return VimTryEnd();
5614     }
5615     else
5616     {
5617 	PyErr_SetString(PyExc_AttributeError, name);
5618 	return -1;
5619     }
5620 }
5621 
5622 static struct PyMethodDef CurrentMethods[] = {
5623     /* name,	    function,			calling,	documentation */
5624     {"__dir__",	    (PyCFunction)CurrentDir,	METH_NOARGS,	""},
5625     { NULL,	    NULL,			0,		NULL}
5626 };
5627 
5628     static void
5629 init_range_cmd(exarg_T *eap)
5630 {
5631     RangeStart = eap->line1;
5632     RangeEnd = eap->line2;
5633 }
5634 
5635     static void
5636 init_range_eval(typval_T *rettv UNUSED)
5637 {
5638     RangeStart = (PyInt) curwin->w_cursor.lnum;
5639     RangeEnd = RangeStart;
5640 }
5641 
5642     static void
5643 run_cmd(const char *cmd, void *arg UNUSED
5644 #ifdef PY_CAN_RECURSE
5645 	, PyGILState_STATE *pygilstate UNUSED
5646 #endif
5647 	)
5648 {
5649     PyObject	*run_ret;
5650     run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5651     if (run_ret != NULL)
5652     {
5653 	Py_DECREF(run_ret);
5654     }
5655     else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5656     {
5657 	semsg(_(e_py_systemexit), "python");
5658 	PyErr_Clear();
5659     }
5660     else
5661 	PyErr_PrintEx(1);
5662 }
5663 
5664 static const char	*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5665 static int		code_hdr_len = 30;
5666 
5667     static void
5668 run_do(const char *cmd, void *arg UNUSED
5669 #ifdef PY_CAN_RECURSE
5670 	, PyGILState_STATE *pygilstate
5671 #endif
5672 	)
5673 {
5674     PyInt	lnum;
5675     size_t	len;
5676     char	*code;
5677     int		status;
5678     PyObject	*pyfunc, *pymain;
5679     PyObject	*run_ret;
5680     buf_T	*was_curbuf = curbuf;
5681 
5682     if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
5683     {
5684 	emsg(_("cannot save undo information"));
5685 	return;
5686     }
5687 
5688     len = code_hdr_len + STRLEN(cmd);
5689     code = PyMem_New(char, len + 1);
5690     memcpy(code, code_hdr, code_hdr_len);
5691     STRCPY(code + code_hdr_len, cmd);
5692     run_ret = PyRun_String(code, Py_file_input, globals, globals);
5693     status = -1;
5694     if (run_ret != NULL)
5695     {
5696 	status = 0;
5697 	Py_DECREF(run_ret);
5698     }
5699     else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5700     {
5701 	PyMem_Free(code);
5702 	semsg(_(e_py_systemexit), "python");
5703 	PyErr_Clear();
5704 	return;
5705     }
5706     else
5707 	PyErr_PrintEx(1);
5708 
5709     PyMem_Free(code);
5710 
5711     if (status)
5712     {
5713 	emsg(_("failed to run the code"));
5714 	return;
5715     }
5716 
5717     status = 0;
5718     pymain = PyImport_AddModule("__main__");
5719     pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
5720 #ifdef PY_CAN_RECURSE
5721     PyGILState_Release(*pygilstate);
5722 #endif
5723 
5724     for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5725     {
5726 	PyObject	*line;
5727 	PyObject	*linenr;
5728 	PyObject	*ret;
5729 
5730 #ifdef PY_CAN_RECURSE
5731 	*pygilstate = PyGILState_Ensure();
5732 #endif
5733 	/* Check the line number, the command my have deleted lines. */
5734 	if (lnum > curbuf->b_ml.ml_line_count
5735 		|| !(line = GetBufferLine(curbuf, lnum)))
5736 	    goto err;
5737 	if (!(linenr = PyInt_FromLong((long) lnum)))
5738 	{
5739 	    Py_DECREF(line);
5740 	    goto err;
5741 	}
5742 	ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5743 	Py_DECREF(line);
5744 	Py_DECREF(linenr);
5745 	if (!ret)
5746 	    goto err;
5747 
5748 	/* Check that the command didn't switch to another buffer. */
5749 	if (curbuf != was_curbuf)
5750 	{
5751 	    Py_XDECREF(ret);
5752 	    goto err;
5753 	}
5754 
5755 	if (ret != Py_None)
5756 	    if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
5757 	    {
5758 		Py_XDECREF(ret);
5759 		goto err;
5760 	    }
5761 
5762 	Py_XDECREF(ret);
5763 	PythonIO_Flush();
5764 #ifdef PY_CAN_RECURSE
5765 	PyGILState_Release(*pygilstate);
5766 #endif
5767     }
5768     goto out;
5769 err:
5770 #ifdef PY_CAN_RECURSE
5771     *pygilstate = PyGILState_Ensure();
5772 #endif
5773     PyErr_PrintEx(0);
5774     PythonIO_Flush();
5775     status = 1;
5776 out:
5777 #ifdef PY_CAN_RECURSE
5778     if (!status)
5779 	*pygilstate = PyGILState_Ensure();
5780 #endif
5781     Py_DECREF(pyfunc);
5782     PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5783     if (status)
5784 	return;
5785     check_cursor();
5786     update_curbuf(NOT_VALID);
5787 }
5788 
5789     static void
5790 run_eval(const char *cmd, typval_T *rettv
5791 #ifdef PY_CAN_RECURSE
5792 	, PyGILState_STATE *pygilstate UNUSED
5793 #endif
5794 	)
5795 {
5796     PyObject	*run_ret;
5797 
5798     run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
5799     if (run_ret == NULL)
5800     {
5801 	if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5802 	{
5803 	    semsg(_(e_py_systemexit), "python");
5804 	    PyErr_Clear();
5805 	}
5806 	else
5807 	{
5808 	    if (PyErr_Occurred() && !msg_silent)
5809 		PyErr_PrintEx(0);
5810 	    emsg(_("E858: Eval did not return a valid python object"));
5811 	}
5812     }
5813     else
5814     {
5815 	if (ConvertFromPyObject(run_ret, rettv) == -1)
5816 	    emsg(_("E859: Failed to convert returned python object to vim value"));
5817 	Py_DECREF(run_ret);
5818     }
5819     PyErr_Clear();
5820 }
5821 
5822     static int
5823 set_ref_in_py(const int copyID)
5824 {
5825     pylinkedlist_T	*cur;
5826     dict_T	*dd;
5827     list_T	*ll;
5828     int		i;
5829     int		abort = FALSE;
5830     FunctionObject	*func;
5831 
5832     if (lastdict != NULL)
5833     {
5834 	for (cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
5835 	{
5836 	    dd = ((DictionaryObject *) (cur->pll_obj))->dict;
5837 	    if (dd->dv_copyID != copyID)
5838 	    {
5839 		dd->dv_copyID = copyID;
5840 		abort = abort || set_ref_in_ht(&dd->dv_hashtab, copyID, NULL);
5841 	    }
5842 	}
5843     }
5844 
5845     if (lastlist != NULL)
5846     {
5847 	for (cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
5848 	{
5849 	    ll = ((ListObject *) (cur->pll_obj))->list;
5850 	    if (ll->lv_copyID != copyID)
5851 	    {
5852 		ll->lv_copyID = copyID;
5853 		abort = abort || set_ref_in_list(ll, copyID, NULL);
5854 	    }
5855 	}
5856     }
5857 
5858     if (lastfunc != NULL)
5859     {
5860 	for (cur = lastfunc ; !abort && cur != NULL ; cur = cur->pll_prev)
5861 	{
5862 	    func = (FunctionObject *) cur->pll_obj;
5863 	    if (func->self != NULL && func->self->dv_copyID != copyID)
5864 	    {
5865 		func->self->dv_copyID = copyID;
5866 		abort = abort || set_ref_in_ht(
5867 			&func->self->dv_hashtab, copyID, NULL);
5868 	    }
5869 	    if (func->argc)
5870 		for (i = 0; !abort && i < func->argc; ++i)
5871 		    abort = abort
5872 			|| set_ref_in_item(&func->argv[i], copyID, NULL, NULL);
5873 	}
5874     }
5875 
5876     return abort;
5877 }
5878 
5879     static int
5880 set_string_copy(char_u *str, typval_T *tv)
5881 {
5882     tv->vval.v_string = vim_strsave(str);
5883     if (tv->vval.v_string == NULL)
5884     {
5885 	PyErr_NoMemory();
5886 	return -1;
5887     }
5888     return 0;
5889 }
5890 
5891     static int
5892 pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
5893 {
5894     dict_T	*dict;
5895     char_u	*key;
5896     dictitem_T	*di;
5897     PyObject	*keyObject;
5898     PyObject	*valObject;
5899     Py_ssize_t	iter = 0;
5900 
5901     if (!(dict = py_dict_alloc()))
5902 	return -1;
5903 
5904     tv->v_type = VAR_DICT;
5905     tv->vval.v_dict = dict;
5906 
5907     while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5908     {
5909 	PyObject	*todecref = NULL;
5910 
5911 	if (keyObject == NULL || valObject == NULL)
5912 	{
5913 	    dict_unref(dict);
5914 	    return -1;
5915 	}
5916 
5917 	if (!(key = StringToChars(keyObject, &todecref)))
5918 	{
5919 	    dict_unref(dict);
5920 	    return -1;
5921 	}
5922 
5923 	if (*key == NUL)
5924 	{
5925 	    dict_unref(dict);
5926 	    Py_XDECREF(todecref);
5927 	    RAISE_NO_EMPTY_KEYS;
5928 	    return -1;
5929 	}
5930 
5931 	di = dictitem_alloc(key);
5932 
5933 	Py_XDECREF(todecref);
5934 
5935 	if (di == NULL)
5936 	{
5937 	    PyErr_NoMemory();
5938 	    dict_unref(dict);
5939 	    return -1;
5940 	}
5941 
5942 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
5943 	{
5944 	    vim_free(di);
5945 	    dict_unref(dict);
5946 	    return -1;
5947 	}
5948 
5949 	if (dict_add(dict, di) == FAIL)
5950 	{
5951 	    RAISE_KEY_ADD_FAIL(di->di_key);
5952 	    clear_tv(&di->di_tv);
5953 	    vim_free(di);
5954 	    dict_unref(dict);
5955 	    return -1;
5956 	}
5957     }
5958 
5959     --dict->dv_refcount;
5960     return 0;
5961 }
5962 
5963     static int
5964 pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
5965 {
5966     dict_T	*dict;
5967     char_u	*key;
5968     dictitem_T	*di;
5969     PyObject	*list;
5970     PyObject	*iterator;
5971     PyObject	*keyObject;
5972     PyObject	*valObject;
5973 
5974     if (!(dict = py_dict_alloc()))
5975 	return -1;
5976 
5977     tv->v_type = VAR_DICT;
5978     tv->vval.v_dict = dict;
5979 
5980     if (!(list = PyMapping_Keys(obj)))
5981     {
5982 	dict_unref(dict);
5983 	return -1;
5984     }
5985 
5986     if (!(iterator = PyObject_GetIter(list)))
5987     {
5988 	dict_unref(dict);
5989 	Py_DECREF(list);
5990 	return -1;
5991     }
5992     Py_DECREF(list);
5993 
5994     while ((keyObject = PyIter_Next(iterator)))
5995     {
5996 	PyObject	*todecref;
5997 
5998 	if (!(key = StringToChars(keyObject, &todecref)))
5999 	{
6000 	    Py_DECREF(keyObject);
6001 	    Py_DECREF(iterator);
6002 	    dict_unref(dict);
6003 	    return -1;
6004 	}
6005 
6006 	if (*key == NUL)
6007 	{
6008 	    Py_DECREF(keyObject);
6009 	    Py_DECREF(iterator);
6010 	    Py_XDECREF(todecref);
6011 	    dict_unref(dict);
6012 	    RAISE_NO_EMPTY_KEYS;
6013 	    return -1;
6014 	}
6015 
6016 	if (!(valObject = PyObject_GetItem(obj, keyObject)))
6017 	{
6018 	    Py_DECREF(keyObject);
6019 	    Py_DECREF(iterator);
6020 	    Py_XDECREF(todecref);
6021 	    dict_unref(dict);
6022 	    return -1;
6023 	}
6024 
6025 	di = dictitem_alloc(key);
6026 
6027 	Py_DECREF(keyObject);
6028 	Py_XDECREF(todecref);
6029 
6030 	if (di == NULL)
6031 	{
6032 	    Py_DECREF(iterator);
6033 	    Py_DECREF(valObject);
6034 	    dict_unref(dict);
6035 	    PyErr_NoMemory();
6036 	    return -1;
6037 	}
6038 
6039 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
6040 	{
6041 	    Py_DECREF(iterator);
6042 	    Py_DECREF(valObject);
6043 	    vim_free(di);
6044 	    dict_unref(dict);
6045 	    return -1;
6046 	}
6047 
6048 	Py_DECREF(valObject);
6049 
6050 	if (dict_add(dict, di) == FAIL)
6051 	{
6052 	    RAISE_KEY_ADD_FAIL(di->di_key);
6053 	    Py_DECREF(iterator);
6054 	    dictitem_free(di);
6055 	    dict_unref(dict);
6056 	    return -1;
6057 	}
6058     }
6059     Py_DECREF(iterator);
6060     --dict->dv_refcount;
6061     return 0;
6062 }
6063 
6064     static int
6065 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
6066 {
6067     list_T	*l;
6068 
6069     if (!(l = py_list_alloc()))
6070 	return -1;
6071 
6072     tv->v_type = VAR_LIST;
6073     tv->vval.v_list = l;
6074 
6075     if (list_py_concat(l, obj, lookup_dict) == -1)
6076     {
6077 	list_unref(l);
6078 	return -1;
6079     }
6080 
6081     --l->lv_refcount;
6082     return 0;
6083 }
6084 
6085 typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
6086 
6087     static int
6088 convert_dl(PyObject *obj, typval_T *tv,
6089 				    pytotvfunc py_to_tv, PyObject *lookup_dict)
6090 {
6091     PyObject	*capsule;
6092     char	hexBuf[sizeof(void *) * 2 + 3];
6093 
6094     sprintf(hexBuf, "%p", (void *)obj);
6095 
6096 # ifdef PY_USE_CAPSULE
6097     capsule = PyDict_GetItemString(lookup_dict, hexBuf);
6098 # else
6099     capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
6100 # endif
6101     if (capsule == NULL)
6102     {
6103 # ifdef PY_USE_CAPSULE
6104 	capsule = PyCapsule_New(tv, NULL, NULL);
6105 # else
6106 	capsule = PyCObject_FromVoidPtr(tv, NULL);
6107 # endif
6108 	if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
6109 	{
6110 	    Py_DECREF(capsule);
6111 	    tv->v_type = VAR_UNKNOWN;
6112 	    return -1;
6113 	}
6114 
6115 	Py_DECREF(capsule);
6116 
6117 	if (py_to_tv(obj, tv, lookup_dict) == -1)
6118 	{
6119 	    tv->v_type = VAR_UNKNOWN;
6120 	    return -1;
6121 	}
6122 	/* As we are not using copy_tv which increments reference count we must
6123 	 * do it ourself. */
6124 	if (tv->v_type == VAR_DICT)
6125 	    ++tv->vval.v_dict->dv_refcount;
6126 	else if (tv->v_type == VAR_LIST)
6127 	    ++tv->vval.v_list->lv_refcount;
6128     }
6129     else
6130     {
6131 	typval_T	*v;
6132 
6133 # ifdef PY_USE_CAPSULE
6134 	v = PyCapsule_GetPointer(capsule, NULL);
6135 # else
6136 	v = PyCObject_AsVoidPtr(capsule);
6137 # endif
6138 	copy_tv(v, tv);
6139     }
6140     return 0;
6141 }
6142 
6143     static int
6144 ConvertFromPyMapping(PyObject *obj, typval_T *tv)
6145 {
6146     PyObject	*lookup_dict;
6147     int		ret;
6148 
6149     if (!(lookup_dict = PyDict_New()))
6150 	return -1;
6151 
6152     if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
6153     {
6154 	tv->v_type = VAR_DICT;
6155 	tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6156 	++tv->vval.v_dict->dv_refcount;
6157 	ret = 0;
6158     }
6159     else if (PyDict_Check(obj))
6160 	ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
6161     else if (PyMapping_Check(obj))
6162 	ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6163     else
6164     {
6165 	PyErr_FORMAT(PyExc_TypeError,
6166 		N_("unable to convert %s to vim dictionary"),
6167 		Py_TYPE_NAME(obj));
6168 	ret = -1;
6169     }
6170     Py_DECREF(lookup_dict);
6171     return ret;
6172 }
6173 
6174     static int
6175 ConvertFromPySequence(PyObject *obj, typval_T *tv)
6176 {
6177     PyObject	*lookup_dict;
6178     int		ret;
6179 
6180     if (!(lookup_dict = PyDict_New()))
6181 	return -1;
6182 
6183     if (PyType_IsSubtype(obj->ob_type, &ListType))
6184     {
6185 	tv->v_type = VAR_LIST;
6186 	tv->vval.v_list = (((ListObject *)(obj))->list);
6187 	++tv->vval.v_list->lv_refcount;
6188 	ret = 0;
6189     }
6190     else if (PyIter_Check(obj) || PySequence_Check(obj))
6191 	ret = convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
6192     else
6193     {
6194 	PyErr_FORMAT(PyExc_TypeError,
6195 		N_("unable to convert %s to vim list"),
6196 		Py_TYPE_NAME(obj));
6197 	ret = -1;
6198     }
6199     Py_DECREF(lookup_dict);
6200     return ret;
6201 }
6202 
6203     static int
6204 ConvertFromPyObject(PyObject *obj, typval_T *tv)
6205 {
6206     PyObject	*lookup_dict;
6207     int		ret;
6208 
6209     if (!(lookup_dict = PyDict_New()))
6210 	return -1;
6211     ret = _ConvertFromPyObject(obj, tv, lookup_dict);
6212     Py_DECREF(lookup_dict);
6213     return ret;
6214 }
6215 
6216     static int
6217 _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
6218 {
6219     if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
6220     {
6221 	tv->v_type = VAR_DICT;
6222 	tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6223 	++tv->vval.v_dict->dv_refcount;
6224     }
6225     else if (PyType_IsSubtype(obj->ob_type, &ListType))
6226     {
6227 	tv->v_type = VAR_LIST;
6228 	tv->vval.v_list = (((ListObject *)(obj))->list);
6229 	++tv->vval.v_list->lv_refcount;
6230     }
6231     else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
6232     {
6233 	FunctionObject *func = (FunctionObject *) obj;
6234 	if (func->self != NULL || func->argv != NULL)
6235 	{
6236 	    partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
6237 	    set_partial(func, pt, TRUE);
6238 	    tv->vval.v_partial = pt;
6239 	    tv->v_type = VAR_PARTIAL;
6240 	}
6241 	else
6242 	{
6243 	    if (set_string_copy(func->name, tv) == -1)
6244 		return -1;
6245 
6246 	    tv->v_type = VAR_FUNC;
6247 	}
6248 	func_ref(func->name);
6249     }
6250     else if (PyBytes_Check(obj))
6251     {
6252 	char_u	*str;
6253 
6254 	if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
6255 	    return -1;
6256 	if (str == NULL)
6257 	    return -1;
6258 
6259 	if (set_string_copy(str, tv) == -1)
6260 	    return -1;
6261 
6262 	tv->v_type = VAR_STRING;
6263     }
6264     else if (PyUnicode_Check(obj))
6265     {
6266 	PyObject	*bytes;
6267 	char_u	*str;
6268 
6269 	bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
6270 	if (bytes == NULL)
6271 	    return -1;
6272 
6273 	if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
6274 	    return -1;
6275 	if (str == NULL)
6276 	    return -1;
6277 
6278 	if (set_string_copy(str, tv))
6279 	{
6280 	    Py_XDECREF(bytes);
6281 	    return -1;
6282 	}
6283 	Py_XDECREF(bytes);
6284 
6285 	tv->v_type = VAR_STRING;
6286     }
6287 #if PY_MAJOR_VERSION < 3
6288     else if (PyInt_Check(obj))
6289     {
6290 	tv->v_type = VAR_NUMBER;
6291 	tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
6292 	if (PyErr_Occurred())
6293 	    return -1;
6294     }
6295 #endif
6296     else if (PyLong_Check(obj))
6297     {
6298 	tv->v_type = VAR_NUMBER;
6299 	tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
6300 	if (PyErr_Occurred())
6301 	    return -1;
6302     }
6303     else if (PyDict_Check(obj))
6304 	return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
6305 #ifdef FEAT_FLOAT
6306     else if (PyFloat_Check(obj))
6307     {
6308 	tv->v_type = VAR_FLOAT;
6309 	tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
6310     }
6311 #endif
6312     else if (PyObject_HasAttrString(obj, "keys"))
6313 	return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6314     /* PyObject_GetIter can create built-in iterator for any sequence object */
6315     else if (PyIter_Check(obj) || PySequence_Check(obj))
6316 	return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
6317     else if (PyMapping_Check(obj))
6318 	return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6319     else if (PyNumber_Check(obj))
6320     {
6321 	PyObject	*num;
6322 
6323 	if (!(num = PyNumber_Long(obj)))
6324 	    return -1;
6325 
6326 	tv->v_type = VAR_NUMBER;
6327 	tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
6328 
6329 	Py_DECREF(num);
6330     }
6331     else if (obj == Py_None)
6332     {
6333 	tv->v_type = VAR_SPECIAL;
6334 	tv->vval.v_number = VVAL_NONE;
6335     }
6336     else
6337     {
6338 	PyErr_FORMAT(PyExc_TypeError,
6339 		N_("unable to convert %s to vim structure"),
6340 		Py_TYPE_NAME(obj));
6341 	return -1;
6342     }
6343     return 0;
6344 }
6345 
6346     static PyObject *
6347 ConvertToPyObject(typval_T *tv)
6348 {
6349     typval_T *argv;
6350     int i;
6351     if (tv == NULL)
6352     {
6353 	PyErr_SET_VIM(N_("internal error: NULL reference passed"));
6354 	return NULL;
6355     }
6356     switch (tv->v_type)
6357     {
6358 	case VAR_STRING:
6359 	    return PyBytes_FromString(tv->vval.v_string == NULL
6360 					    ? "" : (char *)tv->vval.v_string);
6361 	case VAR_NUMBER:
6362 	    return PyLong_FromLong((long) tv->vval.v_number);
6363 #ifdef FEAT_FLOAT
6364 	case VAR_FLOAT:
6365 	    return PyFloat_FromDouble((double) tv->vval.v_float);
6366 #endif
6367 	case VAR_LIST:
6368 	    return NEW_LIST(tv->vval.v_list);
6369 	case VAR_DICT:
6370 	    return NEW_DICTIONARY(tv->vval.v_dict);
6371 	case VAR_FUNC:
6372 	    return NEW_FUNCTION(tv->vval.v_string == NULL
6373 					  ? (char_u *)"" : tv->vval.v_string,
6374 					  0, NULL, NULL, TRUE);
6375 	case VAR_PARTIAL:
6376 	    if (tv->vval.v_partial->pt_argc)
6377 	    {
6378 		argv = PyMem_New(typval_T, (size_t)tv->vval.v_partial->pt_argc);
6379 		for (i = 0; i < tv->vval.v_partial->pt_argc; i++)
6380 		    copy_tv(&tv->vval.v_partial->pt_argv[i], &argv[i]);
6381 	    }
6382 	    else
6383 		argv = NULL;
6384 	    if (tv->vval.v_partial->pt_dict != NULL)
6385 		tv->vval.v_partial->pt_dict->dv_refcount++;
6386 	    return NEW_FUNCTION(tv->vval.v_partial == NULL
6387 			     ? (char_u *)"" : partial_name(tv->vval.v_partial),
6388 				tv->vval.v_partial->pt_argc, argv,
6389 				tv->vval.v_partial->pt_dict,
6390 				tv->vval.v_partial->pt_auto);
6391 	case VAR_BLOB:
6392 	    return PyBytes_FromStringAndSize(
6393 		(char*) tv->vval.v_blob->bv_ga.ga_data,
6394 		(Py_ssize_t) tv->vval.v_blob->bv_ga.ga_len);
6395 	case VAR_UNKNOWN:
6396 	case VAR_CHANNEL:
6397 	case VAR_JOB:
6398 	    Py_INCREF(Py_None);
6399 	    return Py_None;
6400 	case VAR_SPECIAL:
6401 	    switch (tv->vval.v_number)
6402 	    {
6403 		case VVAL_FALSE: return AlwaysFalse(NULL);
6404 		case VVAL_TRUE:  return AlwaysTrue(NULL);
6405 		case VVAL_NONE:
6406 		case VVAL_NULL:  return AlwaysNone(NULL);
6407 	    }
6408 	    PyErr_SET_VIM(N_("internal error: invalid value type"));
6409 	    return NULL;
6410     }
6411     return NULL;
6412 }
6413 
6414 typedef struct
6415 {
6416     PyObject_HEAD
6417 } CurrentObject;
6418 static PyTypeObject CurrentType;
6419 
6420     static void
6421 init_structs(void)
6422 {
6423     vim_memset(&OutputType, 0, sizeof(OutputType));
6424     OutputType.tp_name = "vim.message";
6425     OutputType.tp_basicsize = sizeof(OutputObject);
6426     OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
6427     OutputType.tp_doc = "vim message object";
6428     OutputType.tp_methods = OutputMethods;
6429 #if PY_MAJOR_VERSION >= 3
6430     OutputType.tp_getattro = (getattrofunc)OutputGetattro;
6431     OutputType.tp_setattro = (setattrofunc)OutputSetattro;
6432     OutputType.tp_alloc = call_PyType_GenericAlloc;
6433     OutputType.tp_new = call_PyType_GenericNew;
6434     OutputType.tp_free = call_PyObject_Free;
6435     OutputType.tp_base = &PyStdPrinter_Type;
6436 #else
6437     OutputType.tp_getattr = (getattrfunc)OutputGetattr;
6438     OutputType.tp_setattr = (setattrfunc)OutputSetattr;
6439     // Disabled, because this causes a crash in test86
6440     // OutputType.tp_base = &PyFile_Type;
6441 #endif
6442 
6443     vim_memset(&IterType, 0, sizeof(IterType));
6444     IterType.tp_name = "vim.iter";
6445     IterType.tp_basicsize = sizeof(IterObject);
6446     IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6447     IterType.tp_doc = "generic iterator object";
6448     IterType.tp_iter = (getiterfunc)IterIter;
6449     IterType.tp_iternext = (iternextfunc)IterNext;
6450     IterType.tp_dealloc = (destructor)IterDestructor;
6451     IterType.tp_traverse = (traverseproc)IterTraverse;
6452     IterType.tp_clear = (inquiry)IterClear;
6453 
6454     vim_memset(&BufferType, 0, sizeof(BufferType));
6455     BufferType.tp_name = "vim.buffer";
6456     BufferType.tp_basicsize = sizeof(BufferType);
6457     BufferType.tp_dealloc = (destructor)BufferDestructor;
6458     BufferType.tp_repr = (reprfunc)BufferRepr;
6459     BufferType.tp_as_sequence = &BufferAsSeq;
6460     BufferType.tp_as_mapping = &BufferAsMapping;
6461     BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
6462     BufferType.tp_doc = "vim buffer object";
6463     BufferType.tp_methods = BufferMethods;
6464 #if PY_MAJOR_VERSION >= 3
6465     BufferType.tp_getattro = (getattrofunc)BufferGetattro;
6466     BufferType.tp_setattro = (setattrofunc)BufferSetattro;
6467     BufferType.tp_alloc = call_PyType_GenericAlloc;
6468     BufferType.tp_new = call_PyType_GenericNew;
6469     BufferType.tp_free = call_PyObject_Free;
6470 #else
6471     BufferType.tp_getattr = (getattrfunc)BufferGetattr;
6472     BufferType.tp_setattr = (setattrfunc)BufferSetattr;
6473 #endif
6474 
6475     vim_memset(&WindowType, 0, sizeof(WindowType));
6476     WindowType.tp_name = "vim.window";
6477     WindowType.tp_basicsize = sizeof(WindowObject);
6478     WindowType.tp_dealloc = (destructor)WindowDestructor;
6479     WindowType.tp_repr = (reprfunc)WindowRepr;
6480     WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6481     WindowType.tp_doc = "vim Window object";
6482     WindowType.tp_methods = WindowMethods;
6483     WindowType.tp_traverse = (traverseproc)WindowTraverse;
6484     WindowType.tp_clear = (inquiry)WindowClear;
6485 #if PY_MAJOR_VERSION >= 3
6486     WindowType.tp_getattro = (getattrofunc)WindowGetattro;
6487     WindowType.tp_setattro = (setattrofunc)WindowSetattro;
6488     WindowType.tp_alloc = call_PyType_GenericAlloc;
6489     WindowType.tp_new = call_PyType_GenericNew;
6490     WindowType.tp_free = call_PyObject_Free;
6491 #else
6492     WindowType.tp_getattr = (getattrfunc)WindowGetattr;
6493     WindowType.tp_setattr = (setattrfunc)WindowSetattr;
6494 #endif
6495 
6496     vim_memset(&TabPageType, 0, sizeof(TabPageType));
6497     TabPageType.tp_name = "vim.tabpage";
6498     TabPageType.tp_basicsize = sizeof(TabPageObject);
6499     TabPageType.tp_dealloc = (destructor)TabPageDestructor;
6500     TabPageType.tp_repr = (reprfunc)TabPageRepr;
6501     TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
6502     TabPageType.tp_doc = "vim tab page object";
6503     TabPageType.tp_methods = TabPageMethods;
6504 #if PY_MAJOR_VERSION >= 3
6505     TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
6506     TabPageType.tp_alloc = call_PyType_GenericAlloc;
6507     TabPageType.tp_new = call_PyType_GenericNew;
6508     TabPageType.tp_free = call_PyObject_Free;
6509 #else
6510     TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
6511 #endif
6512 
6513     vim_memset(&BufMapType, 0, sizeof(BufMapType));
6514     BufMapType.tp_name = "vim.bufferlist";
6515     BufMapType.tp_basicsize = sizeof(BufMapObject);
6516     BufMapType.tp_as_mapping = &BufMapAsMapping;
6517     BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
6518     BufMapType.tp_iter = BufMapIter;
6519     BufferType.tp_doc = "vim buffer list";
6520 
6521     vim_memset(&WinListType, 0, sizeof(WinListType));
6522     WinListType.tp_name = "vim.windowlist";
6523     WinListType.tp_basicsize = sizeof(WinListType);
6524     WinListType.tp_as_sequence = &WinListAsSeq;
6525     WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
6526     WinListType.tp_doc = "vim window list";
6527     WinListType.tp_dealloc = (destructor)WinListDestructor;
6528 
6529     vim_memset(&TabListType, 0, sizeof(TabListType));
6530     TabListType.tp_name = "vim.tabpagelist";
6531     TabListType.tp_basicsize = sizeof(TabListType);
6532     TabListType.tp_as_sequence = &TabListAsSeq;
6533     TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
6534     TabListType.tp_doc = "vim tab page list";
6535 
6536     vim_memset(&RangeType, 0, sizeof(RangeType));
6537     RangeType.tp_name = "vim.range";
6538     RangeType.tp_basicsize = sizeof(RangeObject);
6539     RangeType.tp_dealloc = (destructor)RangeDestructor;
6540     RangeType.tp_repr = (reprfunc)RangeRepr;
6541     RangeType.tp_as_sequence = &RangeAsSeq;
6542     RangeType.tp_as_mapping = &RangeAsMapping;
6543     RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6544     RangeType.tp_doc = "vim Range object";
6545     RangeType.tp_methods = RangeMethods;
6546     RangeType.tp_traverse = (traverseproc)RangeTraverse;
6547     RangeType.tp_clear = (inquiry)RangeClear;
6548 #if PY_MAJOR_VERSION >= 3
6549     RangeType.tp_getattro = (getattrofunc)RangeGetattro;
6550     RangeType.tp_alloc = call_PyType_GenericAlloc;
6551     RangeType.tp_new = call_PyType_GenericNew;
6552     RangeType.tp_free = call_PyObject_Free;
6553 #else
6554     RangeType.tp_getattr = (getattrfunc)RangeGetattr;
6555 #endif
6556 
6557     vim_memset(&CurrentType, 0, sizeof(CurrentType));
6558     CurrentType.tp_name = "vim.currentdata";
6559     CurrentType.tp_basicsize = sizeof(CurrentObject);
6560     CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
6561     CurrentType.tp_doc = "vim current object";
6562     CurrentType.tp_methods = CurrentMethods;
6563 #if PY_MAJOR_VERSION >= 3
6564     CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
6565     CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
6566 #else
6567     CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
6568     CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
6569 #endif
6570 
6571     vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
6572     DictionaryType.tp_name = "vim.dictionary";
6573     DictionaryType.tp_basicsize = sizeof(DictionaryObject);
6574     DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
6575     DictionaryType.tp_as_sequence = &DictionaryAsSeq;
6576     DictionaryType.tp_as_mapping = &DictionaryAsMapping;
6577     DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6578     DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
6579     DictionaryType.tp_methods = DictionaryMethods;
6580     DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
6581     DictionaryType.tp_new = (newfunc)DictionaryConstructor;
6582     DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6583 #if PY_MAJOR_VERSION >= 3
6584     DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
6585     DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
6586 #else
6587     DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
6588     DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
6589 #endif
6590 
6591     vim_memset(&ListType, 0, sizeof(ListType));
6592     ListType.tp_name = "vim.list";
6593     ListType.tp_dealloc = (destructor)ListDestructor;
6594     ListType.tp_basicsize = sizeof(ListObject);
6595     ListType.tp_as_sequence = &ListAsSeq;
6596     ListType.tp_as_mapping = &ListAsMapping;
6597     ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6598     ListType.tp_doc = "list pushing modifications to vim structure";
6599     ListType.tp_methods = ListMethods;
6600     ListType.tp_iter = (getiterfunc)ListIter;
6601     ListType.tp_new = (newfunc)ListConstructor;
6602     ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6603 #if PY_MAJOR_VERSION >= 3
6604     ListType.tp_getattro = (getattrofunc)ListGetattro;
6605     ListType.tp_setattro = (setattrofunc)ListSetattro;
6606 #else
6607     ListType.tp_getattr = (getattrfunc)ListGetattr;
6608     ListType.tp_setattr = (setattrfunc)ListSetattr;
6609 #endif
6610 
6611     vim_memset(&FunctionType, 0, sizeof(FunctionType));
6612     FunctionType.tp_name = "vim.function";
6613     FunctionType.tp_basicsize = sizeof(FunctionObject);
6614     FunctionType.tp_dealloc = (destructor)FunctionDestructor;
6615     FunctionType.tp_call = (ternaryfunc)FunctionCall;
6616     FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6617     FunctionType.tp_doc = "object that calls vim function";
6618     FunctionType.tp_methods = FunctionMethods;
6619     FunctionType.tp_repr = (reprfunc)FunctionRepr;
6620     FunctionType.tp_new = (newfunc)FunctionConstructor;
6621     FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6622 #if PY_MAJOR_VERSION >= 3
6623     FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
6624 #else
6625     FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
6626 #endif
6627 
6628     vim_memset(&OptionsType, 0, sizeof(OptionsType));
6629     OptionsType.tp_name = "vim.options";
6630     OptionsType.tp_basicsize = sizeof(OptionsObject);
6631     OptionsType.tp_as_sequence = &OptionsAsSeq;
6632     OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6633     OptionsType.tp_doc = "object for manipulating options";
6634     OptionsType.tp_iter = (getiterfunc)OptionsIter;
6635     OptionsType.tp_as_mapping = &OptionsAsMapping;
6636     OptionsType.tp_dealloc = (destructor)OptionsDestructor;
6637     OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
6638     OptionsType.tp_clear = (inquiry)OptionsClear;
6639 
6640 #if PY_VERSION_HEX < 0x030700f0
6641     vim_memset(&LoaderType, 0, sizeof(LoaderType));
6642     LoaderType.tp_name = "vim.Loader";
6643     LoaderType.tp_basicsize = sizeof(LoaderObject);
6644     LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
6645     LoaderType.tp_doc = "vim message object";
6646     LoaderType.tp_methods = LoaderMethods;
6647     LoaderType.tp_dealloc = (destructor)LoaderDestructor;
6648 #endif
6649 
6650 #if PY_MAJOR_VERSION >= 3
6651     vim_memset(&vimmodule, 0, sizeof(vimmodule));
6652     vimmodule.m_name = "vim";
6653     vimmodule.m_doc = "Vim Python interface\n";
6654     vimmodule.m_size = -1;
6655     vimmodule.m_methods = VimMethods;
6656 #endif
6657 }
6658 
6659 #define PYTYPE_READY(type) \
6660     if (PyType_Ready(&type)) \
6661 	return -1;
6662 
6663     static int
6664 init_types(void)
6665 {
6666     PYTYPE_READY(IterType);
6667     PYTYPE_READY(BufferType);
6668     PYTYPE_READY(RangeType);
6669     PYTYPE_READY(WindowType);
6670     PYTYPE_READY(TabPageType);
6671     PYTYPE_READY(BufMapType);
6672     PYTYPE_READY(WinListType);
6673     PYTYPE_READY(TabListType);
6674     PYTYPE_READY(CurrentType);
6675     PYTYPE_READY(DictionaryType);
6676     PYTYPE_READY(ListType);
6677     PYTYPE_READY(FunctionType);
6678     PYTYPE_READY(OptionsType);
6679     PYTYPE_READY(OutputType);
6680 #if PY_VERSION_HEX < 0x030700f0
6681     PYTYPE_READY(LoaderType);
6682 #endif
6683     return 0;
6684 }
6685 
6686     static int
6687 init_sys_path(void)
6688 {
6689     PyObject	*path;
6690     PyObject	*path_hook;
6691     PyObject	*path_hooks;
6692 
6693     if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
6694 	return -1;
6695 
6696     if (!(path_hooks = PySys_GetObject("path_hooks")))
6697     {
6698 	PyErr_Clear();
6699 	path_hooks = PyList_New(1);
6700 	PyList_SET_ITEM(path_hooks, 0, path_hook);
6701 	if (PySys_SetObject("path_hooks", path_hooks))
6702 	{
6703 	    Py_DECREF(path_hooks);
6704 	    return -1;
6705 	}
6706 	Py_DECREF(path_hooks);
6707     }
6708     else if (PyList_Check(path_hooks))
6709     {
6710 	if (PyList_Append(path_hooks, path_hook))
6711 	{
6712 	    Py_DECREF(path_hook);
6713 	    return -1;
6714 	}
6715 	Py_DECREF(path_hook);
6716     }
6717     else
6718     {
6719 	VimTryStart();
6720 	emsg(_("Failed to set path hook: sys.path_hooks is not a list\n"
6721 	       "You should now do the following:\n"
6722 	       "- append vim.path_hook to sys.path_hooks\n"
6723 	       "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
6724 	VimTryEnd(); /* Discard the error */
6725 	Py_DECREF(path_hook);
6726 	return 0;
6727     }
6728 
6729     if (!(path = PySys_GetObject("path")))
6730     {
6731 	PyErr_Clear();
6732 	path = PyList_New(1);
6733 	Py_INCREF(vim_special_path_object);
6734 	PyList_SET_ITEM(path, 0, vim_special_path_object);
6735 	if (PySys_SetObject("path", path))
6736 	{
6737 	    Py_DECREF(path);
6738 	    return -1;
6739 	}
6740 	Py_DECREF(path);
6741     }
6742     else if (PyList_Check(path))
6743     {
6744 	if (PyList_Append(path, vim_special_path_object))
6745 	    return -1;
6746     }
6747     else
6748     {
6749 	VimTryStart();
6750 	emsg(_("Failed to set path: sys.path is not a list\n"
6751 	       "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6752 	VimTryEnd(); /* Discard the error */
6753     }
6754 
6755     return 0;
6756 }
6757 
6758 static BufMapObject TheBufferMap =
6759 {
6760     PyObject_HEAD_INIT(&BufMapType)
6761 };
6762 
6763 static WinListObject TheWindowList =
6764 {
6765     PyObject_HEAD_INIT(&WinListType)
6766     NULL
6767 };
6768 
6769 static CurrentObject TheCurrent =
6770 {
6771     PyObject_HEAD_INIT(&CurrentType)
6772 };
6773 
6774 static TabListObject TheTabPageList =
6775 {
6776     PyObject_HEAD_INIT(&TabListType)
6777 };
6778 
6779 static struct numeric_constant {
6780     char	*name;
6781     int		val;
6782 } numeric_constants[] = {
6783     {"VAR_LOCKED",	VAR_LOCKED},
6784     {"VAR_FIXED",	VAR_FIXED},
6785     {"VAR_SCOPE",	VAR_SCOPE},
6786     {"VAR_DEF_SCOPE",	VAR_DEF_SCOPE},
6787 };
6788 
6789 static struct object_constant {
6790     char	*name;
6791     PyObject	*valObject;
6792 } object_constants[] = {
6793     {"buffers",  (PyObject *)(void *)&TheBufferMap},
6794     {"windows",  (PyObject *)(void *)&TheWindowList},
6795     {"tabpages", (PyObject *)(void *)&TheTabPageList},
6796     {"current",  (PyObject *)(void *)&TheCurrent},
6797 
6798     {"Buffer",     (PyObject *)&BufferType},
6799     {"Range",      (PyObject *)&RangeType},
6800     {"Window",     (PyObject *)&WindowType},
6801     {"TabPage",    (PyObject *)&TabPageType},
6802     {"Dictionary", (PyObject *)&DictionaryType},
6803     {"List",       (PyObject *)&ListType},
6804     {"Function",   (PyObject *)&FunctionType},
6805     {"Options",    (PyObject *)&OptionsType},
6806 #if PY_VERSION_HEX < 0x030700f0
6807     {"_Loader",    (PyObject *)&LoaderType},
6808 #endif
6809 };
6810 
6811 #define ADD_OBJECT(m, name, obj) \
6812     if (PyModule_AddObject(m, name, obj)) \
6813 	return -1;
6814 
6815 #define ADD_CHECKED_OBJECT(m, name, obj) \
6816     { \
6817 	PyObject	*valObject = obj; \
6818 	if (!valObject) \
6819 	    return -1; \
6820 	ADD_OBJECT(m, name, valObject); \
6821     }
6822 
6823     static int
6824 populate_module(PyObject *m)
6825 {
6826     int		i;
6827     PyObject	*other_module;
6828     PyObject	*attr;
6829     PyObject	*imp;
6830 #if PY_VERSION_HEX >= 0x030700f0
6831     PyObject	*dict;
6832     PyObject	*cls;
6833 #endif
6834 
6835     for (i = 0; i < (int)(sizeof(numeric_constants)
6836 					   / sizeof(struct numeric_constant));
6837 	    ++i)
6838 	ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
6839 		PyInt_FromLong(numeric_constants[i].val));
6840 
6841     for (i = 0; i < (int)(sizeof(object_constants)
6842 					    / sizeof(struct object_constant));
6843 	    ++i)
6844     {
6845 	PyObject	*valObject;
6846 
6847 	valObject = object_constants[i].valObject;
6848 	Py_INCREF(valObject);
6849 	ADD_OBJECT(m, object_constants[i].name, valObject);
6850     }
6851 
6852     if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6853 	return -1;
6854     ADD_OBJECT(m, "error", VimError);
6855 
6856     ADD_CHECKED_OBJECT(m, "vars",  NEW_DICTIONARY(&globvardict));
6857     ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
6858     ADD_CHECKED_OBJECT(m, "options",
6859 	    OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
6860 
6861     if (!(other_module = PyImport_ImportModule("os")))
6862 	return -1;
6863     ADD_OBJECT(m, "os", other_module);
6864 
6865 #if PY_MAJOR_VERSION >= 3
6866     if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
6867 	return -1;
6868 #else
6869     if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwdu")))
6870 	return -1;
6871 #endif
6872     ADD_OBJECT(m, "_getcwd", py_getcwd)
6873 
6874     if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
6875 	return -1;
6876     ADD_OBJECT(m, "_chdir", py_chdir);
6877     if (!(attr = PyObject_GetAttrString(m, "chdir")))
6878 	return -1;
6879     if (PyObject_SetAttrString(other_module, "chdir", attr))
6880     {
6881 	Py_DECREF(attr);
6882 	return -1;
6883     }
6884     Py_DECREF(attr);
6885 
6886     if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
6887     {
6888 	ADD_OBJECT(m, "_fchdir", py_fchdir);
6889 	if (!(attr = PyObject_GetAttrString(m, "fchdir")))
6890 	    return -1;
6891 	if (PyObject_SetAttrString(other_module, "fchdir", attr))
6892 	{
6893 	    Py_DECREF(attr);
6894 	    return -1;
6895 	}
6896 	Py_DECREF(attr);
6897     }
6898     else
6899 	PyErr_Clear();
6900 
6901     if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6902 	return -1;
6903 
6904     ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6905 
6906 #if PY_VERSION_HEX >= 0x030700f0
6907     if (!(imp = PyImport_ImportModule("importlib.machinery")))
6908 	return -1;
6909 
6910     dict = PyModule_GetDict(imp);
6911 
6912     if (!(cls = PyDict_GetItemString(dict, "PathFinder")))
6913     {
6914 	Py_DECREF(imp);
6915 	return -1;
6916     }
6917 
6918     if (!(py_find_spec = PyObject_GetAttrString(cls, "find_spec")))
6919     {
6920 	Py_DECREF(imp);
6921 	return -1;
6922     }
6923 
6924     Py_DECREF(imp);
6925 
6926     ADD_OBJECT(m, "_find_spec", py_find_spec);
6927 #else
6928     if (!(imp = PyImport_ImportModule("imp")))
6929 	return -1;
6930 
6931     if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6932     {
6933 	Py_DECREF(imp);
6934 	return -1;
6935     }
6936 
6937     if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6938     {
6939 	Py_DECREF(py_find_module);
6940 	Py_DECREF(imp);
6941 	return -1;
6942     }
6943 
6944     Py_DECREF(imp);
6945 
6946     ADD_OBJECT(m, "_find_module", py_find_module);
6947     ADD_OBJECT(m, "_load_module", py_load_module);
6948 #endif
6949 
6950     return 0;
6951 }
6952