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