*if_pyth.txt*   For Vim version 8.2.  Last change: 2019 Dec 07


		  VIM REFERENCE MANUAL    by Paul Moore


The Python Interface to Vim				*python* *Python*

1. Commands					|python-commands|
2. The vim module				|python-vim|
3. Buffer objects				|python-buffer|
4. Range objects				|python-range|
5. Window objects				|python-window|
6. Tab page objects				|python-tabpage|
7. vim.bindeval objects				|python-bindeval-objects|
8. pyeval(), py3eval() Vim functions		|python-pyeval|
9. Dynamic loading				|python-dynamic|
10. Python 3					|python3|
11. Python X					|python_x|
12. Building with Python support		|python-building|

The Python 2.x interface is available only when Vim was compiled with the
|+python| feature.
The Python 3 interface is available only when Vim was compiled with the
|+python3| feature.
Both can be available at the same time, but read |python-2-and-3|.

==============================================================================
1. Commands						*python-commands*

					*:python* *:py* *E263* *E264* *E887*
:[range]py[thon] {stmt}
			Execute Python statement {stmt}.  A simple check if
			the `:python` command is working: >
				:python print "Hello"

:[range]py[thon] << [endmarker]
{script}
{endmarker}
			Execute Python script {script}.
			Note: This command doesn't work when the Python
			feature wasn't compiled in.  To avoid errors, see
			|script-here|.

The {endmarker} below the {script} must NOT be preceded by any white space.

If [endmarker] is omitted from after the "<<", a dot '.' must be used after
{script}, like for the |:append| and |:insert| commands.

This form of the |:python| command is mainly useful for including python code
in Vim scripts.

Example: >
	function! IcecreamInitialize()
	python << EOF
	class StrawberryIcecream:
		def __call__(self):
			print 'EAT ME'
	EOF
	endfunction

To see what version of Python you have: >
	:python print(sys.version)

There is no need to import sys, it's done by default.

Note: Python is very sensitive to the indenting.  Make sure the "class" line
and "EOF" do not have any indent.

							*:pydo*
:[range]pydo {body}	Execute Python function "def _vim_pydo(line, linenr):
			{body}" for each line in the [range], with the
			function arguments being set to the text of each line
			in turn, without a trailing <EOL>, and the current
			line number. The function should return a string or
			None. If a string is returned, it becomes the text of
			the line in the current turn. The default for [range]
			is the whole file: "1,$".

Examples:
>
	:pydo return "%s\t%d" % (line[::-1], len(line))
	:pydo if line: return "%4d: %s" % (linenr, line)
<
One can use `:pydo` in possible conjunction with `:py` to filter a range using
python. For example: >

	:py3 << EOF
	needle = vim.eval('@a')
	replacement = vim.eval('@b')

	def py_vim_string_replace(str):
		return str.replace(needle, replacement)
	EOF
	:'<,'>py3do return py_vim_string_replace(line)
<
							*:pyfile* *:pyf*
:[range]pyf[ile] {file}
			Execute the Python script in {file}.  The whole
			argument is used as a single file name.

Both of these commands do essentially the same thing - they execute a piece of
Python code, with the "current range" |python-range| set to the given line
range.

In the case of :python, the code to execute is in the command-line.
In the case of :pyfile, the code to execute is the contents of the given file.

Python commands cannot be used in the |sandbox|.

To pass arguments you need to set sys.argv[] explicitly.  Example: >

	:python sys.argv = ["foo", "bar"]
	:pyfile myscript.py

Here are some examples					*python-examples*  >

	:python from vim import *
	:python from string import upper
	:python current.line = upper(current.line)
	:python print "Hello"
	:python str = current.buffer[42]

(Note that changes - like the imports - persist from one command to the next,
just like in the Python interpreter.)

==============================================================================
2. The vim module					*python-vim*

Python code gets all of its access to vim (with one exception - see
|python-output| below) via the "vim" module.  The vim module implements two
methods, three constants, and one error object.  You need to import the vim
module before using it: >
	:python import vim

Overview >
	:py print "Hello"		# displays a message
	:py vim.command(cmd)		# execute an Ex command
	:py w = vim.windows[n]		# gets window "n"
	:py cw = vim.current.window	# gets the current window
	:py b = vim.buffers[n]		# gets buffer "n"
	:py cb = vim.current.buffer	# gets the current buffer
	:py w.height = lines		# sets the window height
	:py w.cursor = (row, col)	# sets the window cursor position
	:py pos = w.cursor		# gets a tuple (row, col)
	:py name = b.name		# gets the buffer file name
	:py line = b[n]			# gets a line from the buffer
	:py lines = b[n:m]		# gets a list of lines
	:py num = len(b)		# gets the number of lines
	:py b[n] = str			# sets a line in the buffer
	:py b[n:m] = [str1, str2, str3]	# sets a number of lines at once
	:py del b[n]			# deletes a line
	:py del b[n:m]			# deletes a number of lines


Methods of the "vim" module

vim.command(str)					*python-command*
	Executes the vim (ex-mode) command str.  Returns None.
	Examples: >
	    :py vim.command("set tw=72")
	    :py vim.command("%s/aaa/bbb/g")
<	The following definition executes Normal mode commands: >
		def normal(str):
			vim.command("normal "+str)
		# Note the use of single quotes to delimit a string containing
		# double quotes
		normal('"a2dd"aP')
<								*E659*
	The ":python" command cannot be used recursively with Python 2.2 and
	older.  This only works with Python 2.3 and later: >
	    :py vim.command("python print 'Hello again Python'")

vim.eval(str)						*python-eval*
	Evaluates the expression str using the vim internal expression
	evaluator (see |expression|).  Returns the expression result as:
	- a string if the Vim expression evaluates to a string or number
	- a list if the Vim expression evaluates to a Vim list
	- a dictionary if the Vim expression evaluates to a Vim dictionary
	Dictionaries and lists are recursively expanded.
	Examples: >
	    :" value of the 'textwidth' option
	    :py text_width = vim.eval("&tw")
	    :
	    :" contents of the 'a' register
	    :py a_reg = vim.eval("@a")
	    :
	    :" Result is a string! Use string.atoi() to convert to a number.
	    :py str = vim.eval("12+12")
	    :
	    :py tagList = vim.eval('taglist("eval_expr")')
<	The latter will return a python list of python dicts, for instance:
	[{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name': ~
	'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}] ~

vim.bindeval(str)					*python-bindeval*
	Like |python-eval|, but returns special objects described in
	|python-bindeval-objects|. These python objects let you modify (|List|
	or |Dictionary|) or call (|Funcref|) vim objects.

vim.strwidth(str)					*python-strwidth*
	Like |strwidth()|: returns number of display cells str occupies, tab
	is counted as one cell.

vim.foreach_rtp(callable)				*python-foreach_rtp*
	Call the given callable for each path in 'runtimepath' until either
	callable returns something but None, the exception is raised or there
	are no longer paths. If stopped in case callable returned non-None,
	vim.foreach_rtp function returns the value returned by callable.

vim.chdir(*args, **kwargs)				*python-chdir*
vim.fchdir(*args, **kwargs)				*python-fchdir*
	Run os.chdir or os.fchdir, then all appropriate vim stuff.
	Note: you should not use these functions directly, use os.chdir and
	      os.fchdir instead. Behavior of vim.fchdir is undefined in case
	      os.fchdir does not exist.

Error object of the "vim" module

vim.error						*python-error*
	Upon encountering a Vim error, Python raises an exception of type
	vim.error.
	Example: >
		try:
			vim.command("put a")
		except vim.error:
			# nothing in register a

Constants of the "vim" module

	Note that these are not actually constants - you could reassign them.
	But this is silly, as you would then lose access to the vim objects
	to which the variables referred.

vim.buffers						*python-buffers*
	A mapping object providing access to the list of vim buffers.  The
	object supports the following operations: >
	    :py b = vim.buffers[i]	# Indexing (read-only)
	    :py b in vim.buffers	# Membership test
	    :py n = len(vim.buffers)	# Number of elements
	    :py for b in vim.buffers:	# Iterating over buffer list
<
vim.windows						*python-windows*
	A sequence object providing access to the list of vim windows.  The
	object supports the following operations: >
	    :py w = vim.windows[i]	# Indexing (read-only)
	    :py w in vim.windows	# Membership test
	    :py n = len(vim.windows)	# Number of elements
	    :py for w in vim.windows:	# Sequential access
<	Note: vim.windows object always accesses current tab page.
	|python-tabpage|.windows objects are bound to parent |python-tabpage|
	object and always use windows from that tab page (or throw vim.error
	in case tab page was deleted). You can keep a reference to both
	without keeping a reference to vim module object or |python-tabpage|,
	they will not lose their properties in this case.

vim.tabpages						*python-tabpages*
	A sequence object providing access to the list of vim tab pages. The
	object supports the following operations: >
	    :py t = vim.tabpages[i]	# Indexing (read-only)
	    :py t in vim.tabpages	# Membership test
	    :py n = len(vim.tabpages)	# Number of elements
	    :py for t in vim.tabpages:	# Sequential access
<
vim.current						*python-current*
	An object providing access (via specific attributes) to various
	"current" objects available in vim:
		vim.current.line	The current line (RW)		String
		vim.current.buffer	The current buffer (RW)		Buffer
		vim.current.window	The current window (RW)		Window
		vim.current.tabpage	The current tab page (RW)	TabPage
		vim.current.range	The current line range (RO)	Range

	The last case deserves a little explanation.  When the :python or
	:pyfile command specifies a range, this range of lines becomes the
	"current range".  A range is a bit like a buffer, but with all access
	restricted to a subset of lines.  See |python-range| for more details.

	Note: When assigning to vim.current.{buffer,window,tabpage} it expects
	valid |python-buffer|, |python-window| or |python-tabpage| objects
	respectively. Assigning triggers normal (with |autocommand|s)
	switching to given buffer, window or tab page. It is the only way to
	switch UI objects in python: you can't assign to
	|python-tabpage|.window attribute. To switch without triggering
	autocommands use >
	    py << EOF
	    saved_eventignore = vim.options['eventignore']
	    vim.options['eventignore'] = 'all'
	    try:
	        vim.current.buffer = vim.buffers[2] # Switch to buffer 2
	    finally:
	        vim.options['eventignore'] = saved_eventignore
	    EOF
<
vim.vars						*python-vars*
vim.vvars						*python-vvars*
	Dictionary-like objects holding dictionaries with global (|g:|) and
	vim (|v:|) variables respectively. Identical to `vim.bindeval("g:")`,
	but faster.

vim.options						*python-options*
	Object partly supporting mapping protocol (supports setting and
	getting items) providing a read-write access to global options.
	Note: unlike |:set| this provides access only to global options. You
	cannot use this object to obtain or set local options' values or
	access local-only options in any fashion. Raises KeyError if no global
	option with such name exists (i.e. does not raise KeyError for
	|global-local| options and global only options, but does for window-
	and buffer-local ones).  Use |python-buffer| objects to access to
	buffer-local options and |python-window| objects to access to
	window-local options.

	Type of this object is available via "Options" attribute of vim
	module.

Output from Python					*python-output*
	Vim displays all Python code output in the Vim message area.  Normal
	output appears as information messages, and error output appears as
	error messages.

	In implementation terms, this means that all output to sys.stdout
	(including the output from print statements) appears as information
	messages, and all output to sys.stderr (including error tracebacks)
	appears as error messages.

							*python-input*
	Input (via sys.stdin, including input() and raw_input()) is not
	supported, and may cause the program to crash.  This should probably be
	fixed.

		    *python2-directory* *python3-directory* *pythonx-directory*
Python 'runtimepath' handling				*python-special-path*

In python vim.VIM_SPECIAL_PATH special directory is used as a replacement for
the list of paths found in 'runtimepath': with this directory in sys.path and
vim.path_hooks in sys.path_hooks python will try to load module from
{rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for
each {rtp} found in 'runtimepath'.

Implementation is similar to the following, but written in C: >

    from imp import find_module, load_module
    import vim
    import sys

    class VimModuleLoader(object):
        def __init__(self, module):
            self.module = module

        def load_module(self, fullname, path=None):
            return self.module

    def _find_module(fullname, oldtail, path):
        idx = oldtail.find('.')
        if idx > 0:
            name = oldtail[:idx]
            tail = oldtail[idx+1:]
            fmr = find_module(name, path)
            module = load_module(fullname[:-len(oldtail)] + name, *fmr)
            return _find_module(fullname, tail, module.__path__)
        else:
            fmr = find_module(fullname, path)
            return load_module(fullname, *fmr)

    # It uses vim module itself in place of VimPathFinder class: it does not
    # matter for python which object has find_module function attached to as
    # an attribute.
    class VimPathFinder(object):
        @classmethod
        def find_module(cls, fullname, path=None):
            try:
                return VimModuleLoader(_find_module(fullname, fullname, path or vim._get_paths()))
            except ImportError:
                return None

        @classmethod
        def load_module(cls, fullname, path=None):
            return _find_module(fullname, fullname, path or vim._get_paths())

    def hook(path):
        if path == vim.VIM_SPECIAL_PATH:
            return VimPathFinder
        else:
            raise ImportError

    sys.path_hooks.append(hook)

vim.VIM_SPECIAL_PATH					*python-VIM_SPECIAL_PATH*
	String constant used in conjunction with vim path hook. If path hook
	installed by vim is requested to handle anything but path equal to
	vim.VIM_SPECIAL_PATH constant it raises ImportError. In the only other
	case it uses special loader.

	Note: you must not use value of this constant directly, always use
	      vim.VIM_SPECIAL_PATH object.

vim.find_module(...)					*python-find_module*
vim.path_hook(path)					*python-path_hook*
	Methods or objects used to implement path loading as described above.
	You should not be using any of these directly except for vim.path_hook
	in case you need to do something with sys.meta_path. It is not
	guaranteed that any of the objects will exist in the future vim
	versions.

vim._get_paths						*python-_get_paths*
	Methods returning a list of paths which will be searched for by path
	hook. You should not rely on this method being present in future
	versions, but can use it for debugging.

	It returns a list of {rtp}/python2 (or {rtp}/python3) and
	{rtp}/pythonx directories for each {rtp} in 'runtimepath'.

==============================================================================
3. Buffer objects					*python-buffer*

Buffer objects represent vim buffers.  You can obtain them in a number of ways:
	- via vim.current.buffer (|python-current|)
	- from indexing vim.buffers (|python-buffers|)
	- from the "buffer" attribute of a window (|python-window|)

Buffer objects have two read-only attributes - name - the full file name for
the buffer, and number - the buffer number.  They also have three methods
(append, mark, and range; see below).

You can also treat buffer objects as sequence objects.  In this context, they
act as if they were lists (yes, they are mutable) of strings, with each
element being a line of the buffer.  All of the usual sequence operations,
including indexing, index assignment, slicing and slice assignment, work as
you would expect.  Note that the result of indexing (slicing) a buffer is a
string (list of strings).  This has one unusual consequence - b[:] is different
from b.  In particular, "b[:] = None" deletes the whole of the buffer, whereas
"b = None" merely updates the variable b, with no effect on the buffer.

Buffer indexes start at zero, as is normal in Python.  This differs from vim
line numbers, which start from 1.  This is particularly relevant when dealing
with marks (see below) which use vim line numbers.

The buffer object attributes are:
	b.vars		Dictionary-like object used to access
			|buffer-variable|s.
	b.options	Mapping object (supports item getting, setting and
			deleting) that provides access to buffer-local options
			and buffer-local values of |global-local| options. Use
			|python-window|.options if option is window-local,
			this object will raise KeyError. If option is
			|global-local| and local value is missing getting it
			will return None.
	b.name		String, RW. Contains buffer name (full path).
			Note: when assigning to b.name |BufFilePre| and
			|BufFilePost| autocommands are launched.
	b.number	Buffer number. Can be used as |python-buffers| key.
			Read-only.
	b.valid		True or False. Buffer object becomes invalid when
			corresponding buffer is wiped out.

The buffer object methods are:
	b.append(str)	Append a line to the buffer
	b.append(str, nr)  Idem, below line "nr"
	b.append(list)	Append a list of lines to the buffer
			Note that the option of supplying a list of strings to
			the append method differs from the equivalent method
			for Python's built-in list objects.
	b.append(list, nr)  Idem, below line "nr"
	b.mark(name)	Return a tuple (row,col) representing the position
			of the named mark (can also get the []"<> marks)
	b.range(s,e)	Return a range object (see |python-range|) which
			represents the part of the given buffer between line
			numbers s and e |inclusive|.

Note that when adding a line it must not contain a line break character '\n'.
A trailing '\n' is allowed and ignored, so that you can do: >
	:py b.append(f.readlines())

Buffer object type is available using "Buffer" attribute of vim module.

Examples (assume b is the current buffer) >
	:py print b.name		# write the buffer file name
	:py b[0] = "hello!!!"		# replace the top line
	:py b[:] = None			# delete the whole buffer
	:py del b[:]			# delete the whole buffer
	:py b[0:0] = [ "a line" ]	# add a line at the top
	:py del b[2]			# delete a line (the third)
	:py b.append("bottom")		# add a line at the bottom
	:py n = len(b)			# number of lines
	:py (row,col) = b.mark('a')	# named mark
	:py r = b.range(1,5)		# a sub-range of the buffer
	:py b.vars["foo"] = "bar"	# assign b:foo variable
	:py b.options["ff"] = "dos"	# set fileformat
	:py del b.options["ar"]		# same as :set autoread<

==============================================================================
4. Range objects					*python-range*

Range objects represent a part of a vim buffer.  You can obtain them in a
number of ways:
	- via vim.current.range (|python-current|)
	- from a buffer's range() method (|python-buffer|)

A range object is almost identical in operation to a buffer object.  However,
all operations are restricted to the lines within the range (this line range
can, of course, change as a result of slice assignments, line deletions, or
the range.append() method).

The range object attributes are:
	r.start		Index of first line into the buffer
	r.end		Index of last line into the buffer

The range object methods are:
	r.append(str)	Append a line to the range
	r.append(str, nr)  Idem, after line "nr"
	r.append(list)	Append a list of lines to the range
			Note that the option of supplying a list of strings to
			the append method differs from the equivalent method
			for Python's built-in list objects.
	r.append(list, nr)  Idem, after line "nr"

Range object type is available using "Range" attribute of vim module.

Example (assume r is the current range):
	# Send all lines in a range to the default printer
	vim.command("%d,%dhardcopy!" % (r.start+1,r.end+1))

==============================================================================
5. Window objects					*python-window*

Window objects represent vim windows.  You can obtain them in a number of ways:
	- via vim.current.window (|python-current|)
	- from indexing vim.windows (|python-windows|)
	- from indexing "windows" attribute of a tab page (|python-tabpage|)
	- from the "window" attribute of a tab page (|python-tabpage|)

You can manipulate window objects only through their attributes.  They have no
methods, and no sequence or other interface.

Window attributes are:
	buffer (read-only)	The buffer displayed in this window
	cursor (read-write)	The current cursor position in the window
				This is a tuple, (row,col).
	height (read-write)	The window height, in rows
	width (read-write)	The window width, in columns
	vars (read-only)	The window |w:| variables. Attribute is
				unassignable, but you can change window
				variables this way
	options (read-only)	The window-local options. Attribute is
				unassignable, but you can change window
				options this way. Provides access only to
				window-local options, for buffer-local use
				|python-buffer| and for global ones use
				|python-options|. If option is |global-local|
				and local value is missing getting it will
				return None.
	number (read-only)	Window number.  The first window has number 1.
				This is zero in case it cannot be determined
				(e.g. when the window object belongs to other
				tab page).
	row, col (read-only)	On-screen window position in display cells.
				First position is zero.
	tabpage (read-only)	Window tab page.
	valid (read-write)	True or False. Window object becomes invalid
				when corresponding window is closed.

The height attribute is writable only if the screen is split horizontally.
The width attribute is writable only if the screen is split vertically.

Window object type is available using "Window" attribute of vim module.

==============================================================================
6. Tab page objects					*python-tabpage*

Tab page objects represent vim tab pages. You can obtain them in a number of
ways:
	- via vim.current.tabpage (|python-current|)
	- from indexing vim.tabpages (|python-tabpages|)

You can use this object to access tab page windows. They have no methods and
no sequence or other interfaces.

Tab page attributes are:
	number		The tab page number like the one returned by
			|tabpagenr()|.
	windows		Like |python-windows|, but for current tab page.
	vars		The tab page |t:| variables.
	window		Current tabpage window.
	valid		True or False. Tab page object becomes invalid when
			corresponding tab page is closed.

TabPage object type is available using "TabPage" attribute of vim module.

==============================================================================
7. vim.bindeval objects				*python-bindeval-objects*

vim.Dictionary object				*python-Dictionary*
    Dictionary-like object providing access to vim |Dictionary| type.
    Attributes:
        Attribute  Description ~
        locked     One of                       *python-.locked*
                    Value           Description ~
                    zero            Variable is not locked
                    vim.VAR_LOCKED  Variable is locked, but can be unlocked
                    vim.VAR_FIXED   Variable is locked and can't be unlocked
                   Read-write. You can unlock locked variable by assigning
                   `True` or `False` to this attribute. No recursive locking
                   is supported.
        scope      One of
                    Value              Description ~
                    zero               Dictionary is not a scope one
                    vim.VAR_DEF_SCOPE  |g:| or |l:| dictionary
                    vim.VAR_SCOPE      Other scope dictionary,
                                       see |internal-variables|
    Methods (note: methods do not support keyword arguments):
        Method      Description ~
        keys()      Returns a list with dictionary keys.
        values()    Returns a list with dictionary values.
        items()     Returns a list of 2-tuples with dictionary contents.
        update(iterable), update(dictionary), update(**kwargs)
                    Adds keys to dictionary.
        get(key[, default=None])
                    Obtain key from dictionary, returning the default if it is
                    not present.
        pop(key[, default])
                    Remove specified key from dictionary and return
                    corresponding value. If key is not found and default is
                    given returns the default, otherwise raises KeyError.
        popitem()
                    Remove random key from dictionary and return (key, value)
                    pair.
        has_key(key)
                    Check whether dictionary contains specified key, similar
                    to `key in dict`.

        __new__(), __new__(iterable), __new__(dictionary), __new__(update)
                    You can use `vim.Dictionary()` to create new vim
                    dictionaries. `d=vim.Dictionary(arg)` is the same as
                    `d=vim.bindeval('{}');d.update(arg)`. Without arguments
                    constructs empty dictionary.

    Examples: >
        d = vim.Dictionary(food="bar")		# Constructor
        d['a'] = 'b'				# Item assignment
        print d['a']				# getting item
        d.update({'c': 'd'})			# .update(dictionary)
        d.update(e='f')				# .update(**kwargs)
        d.update((('g', 'h'), ('i', 'j')))	# .update(iterable)
        for key in d.keys():			# .keys()
        for val in d.values():			# .values()
        for key, val in d.items():		# .items()
        print isinstance(d, vim.Dictionary)	# True
        for key in d:				# Iteration over keys
        class Dict(vim.Dictionary):		# Subclassing
<
    Note: when iterating over keys you should not modify dictionary.

vim.List object					*python-List*
    Sequence-like object providing access to vim |List| type.
    Supports `.locked` attribute, see |python-.locked|. Also supports the
    following methods:
        Method          Description ~
        extend(item)    Add items to the list.

        __new__(), __new__(iterable)
                        You can use `vim.List()` to create new vim lists.
                        `l=vim.List(iterable)` is the same as
                        `l=vim.bindeval('[]');l.extend(iterable)`. Without
                        arguments constructs empty list.
    Examples: >
        l = vim.List("abc")		# Constructor, result: ['a', 'b', 'c']
        l.extend(['abc', 'def'])	# .extend() method
        print l[1:]			# slicing
        l[:0] = ['ghi', 'jkl']		# slice assignment
        print l[0]			# getting item
        l[0] = 'mno'			# assignment
        for i in l:			# iteration
        print isinstance(l, vim.List)	# True
        class List(vim.List):		# Subclassing

vim.Function object				*python-Function*
    Function-like object, acting like vim |Funcref| object. Accepts special
    keyword argument `self`, see |Dictionary-function|. You can also use
    `vim.Function(name)` constructor, it is the same as
    `vim.bindeval('function(%s)'%json.dumps(name))`.

    Attributes (read-only):
        Attribute    Description ~
        name         Function name.
        args         `None` or a |python-List| object with arguments.  Note
                     that this is a copy of the arguments list, constructed
                     each time you request this attribute. Modifications made
                     to the list will be ignored (but not to the containers
                     inside argument list: this is like |copy()| and not
                     |deepcopy()|).
        self         `None` or a |python-Dictionary| object with self
                     dictionary. Note that explicit `self` keyword used when
                     calling resulting object overrides this attribute.
        auto_rebind  Boolean. True if partial created from this Python object
                     and stored in the Vim script dictionary should be
                     automatically rebound to the dictionary it is stored in
                     when this dictionary is indexed. Exposes Vim internal
                     difference between `dict.func` (auto_rebind=True) and
                     `function(dict.func,dict)` (auto_rebind=False). This
                     attribute makes no sense if `self` attribute is `None`.

    Constructor additionally accepts `args`, `self` and `auto_rebind`
    keywords.  If `args` and/or `self` argument is given then it constructs
    a partial, see |function()|.  `auto_rebind` is only used when `self`
    argument is given, otherwise it is assumed to be `True` regardless of
    whether it was given or not.  If `self` is given then it defaults to
    `False`.

    Examples: >
        f = vim.Function('tr')			# Constructor
        print f('abc', 'a', 'b')		# Calls tr('abc', 'a', 'b')
        vim.command('''
            function DictFun() dict
                return self
            endfunction
        ''')
        f = vim.bindeval('function("DictFun")')
        print f(self={})			# Like call('DictFun', [], {})
        print isinstance(f, vim.Function)	# True

        p = vim.Function('DictFun', self={})
        print f()
        p = vim.Function('tr', args=['abc', 'a'])
        print f('b')

==============================================================================
8. pyeval() and py3eval() Vim functions			*python-pyeval*

To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()|
functions to evaluate Python expressions and pass their values to Vim script.
|pyxeval()| is also available.

The Python value "None" is converted to v:none.

==============================================================================
9. Dynamic loading					*python-dynamic*

On MS-Windows and Unix the Python library can be loaded dynamically.  The
|:version| output then includes |+python/dyn| or |+python3/dyn|.

This means that Vim will search for the Python DLL or shared library file only
when needed.  When you don't use the Python interface you don't need it, thus
you can use Vim without this file.


MS-Windows ~

To use the Python interface the Python DLL must be in your search path.  In a
console window type "path" to see what directories are used.  The 'pythondll'
or 'pythonthreedll' option can be also used to specify the Python DLL.

The name of the DLL should match the Python version Vim was compiled with.
Currently the name for Python 2 is "python27.dll", that is for Python 2.7.
That is the default value for 'pythondll'.  For Python 3 it is python36.dll
(Python 3.6).  To know for sure edit "gvim.exe" and search for
"python\d*.dll\c".


Unix ~

The 'pythondll' or 'pythonthreedll' option can be used to specify the Python
shared library file instead of DYNAMIC_PYTHON_DLL or DYNAMIC_PYTHON3_DLL file
what were specified at compile time.  The version of the shared library must
match the Python 2.x or Python 3 version Vim was compiled with.

==============================================================================
10. Python 3						*python3*

							*:py3* *:python3*
:[range]py3 {stmt}
:[range]py3 << [endmarker]
{script}
{endmarker}

:[range]python3 {stmt}
:[range]python3 << [endmarker]
{script}
{endmarker}
	The `:py3` and `:python3` commands work similar to `:python`.  A
	simple check if the `:py3` command is working: >
		:py3 print("Hello")
<
	To see what version of Python you have: >
		:py3 import sys
		:py3 print(sys.version)
<							*:py3file*
:[range]py3f[ile] {file}
	The `:py3file` command works similar to `:pyfile`.
							*:py3do*
:[range]py3do {body}
	The `:py3do` command works similar to `:pydo`.


Vim can be built in four ways (:version output):
1. No Python support	    (-python, -python3)
2. Python 2 support only    (+python or +python/dyn, -python3)
3. Python 3 support only    (-python, +python3 or +python3/dyn)
4. Python 2 and 3 support   (+python/dyn, +python3/dyn)

Some more details on the special case 4:  *python-2-and-3*

When Python 2 and Python 3 are both supported they must be loaded dynamically.

When doing this on Linux/Unix systems and importing global symbols, this leads
to a crash when the second Python version is used.  So either global symbols
are loaded but only one Python version is activated, or no global symbols are
loaded. The latter makes Python's "import" fail on libraries that expect the
symbols to be provided by Vim.
							*E836* *E837*
Vim's configuration script makes a guess for all libraries based on one
standard Python library (termios).  If importing this library succeeds for
both Python versions, then both will be made available in Vim at the same
time.  If not, only the version first used in a session will be enabled.
When trying to use the other one you will get the E836 or E837 error message.

Here Vim's behavior depends on the system in which it was configured.  In a
system where both versions of Python were configured with --enable-shared,
both versions of Python will be activated at the same time.  There will still
be problems with other third party libraries that were not linked to
libPython.

To work around such problems there are these options:
1. The problematic library is recompiled to link to the according
   libpython.so.
2. Vim is recompiled for only one Python version.
3. You undefine PY_NO_RTLD_GLOBAL in auto/config.h after configuration.  This
   may crash Vim though.

							*E880*
Raising SystemExit exception in python isn't endorsed way to quit vim, use: >
	:py vim.command("qall!")
<

							*has-python*
You can test what Python version is available with: >
	if has('python')
	  echo 'there is Python 2.x'
	endif
  	if has('python3')
	  echo 'there is Python 3.x'
	endif

Note however, that when Python 2 and 3 are both available and loaded
dynamically, these has() calls will try to load them.  If only one can be
loaded at a time, just checking if Python 2 or 3 are available will prevent
the other one from being available.

To avoid loading the dynamic library, only check if Vim was compiled with
python support: >
	if has('python_compiled')
	  echo 'compiled with Python 2.x support'
	  if has('python_dynamic')
	    echo 'Python 2.x dynamically loaded'
	  endif
	endif
  	if has('python3_compiled')
	  echo 'compiled with Python 3.x support'
	  if has('python3_dynamic')
	    echo 'Python 3.x dynamically loaded'
	  endif
	endif

This also tells you whether Python is dynamically loaded, which will fail if
the runtime library cannot be found.

==============================================================================
11. Python X						*python_x* *pythonx*

Because most python code can be written so that it works with python 2.6+ and
python 3 the pyx* functions and commands have been written.  They work exactly
the same as the Python 2 and 3 variants, but select the Python version using
the 'pyxversion' setting.

You should set 'pyxversion' in your |.vimrc| to prefer Python 2 or Python 3
for Python commands. If you change this setting at runtime you may risk that
state of plugins (such as initialization) may be lost.

If you want to use a module, you can put it in the {rtp}/pythonx directory.
See |pythonx-directory|.

							*:pyx* *:pythonx*
The `:pyx` and `:pythonx` commands work similar to `:python`.  A simple check
if the `:pyx` command is working: >
	:pyx print("Hello")

To see what version of Python is being used: >
	:pyx import sys
	:pyx print(sys.version)
<
					*:pyxfile* *python_x-special-comments*
The `:pyxfile` command works similar to `:pyfile`.  However you can add one of
these comments to force Vim using `:pyfile` or `:py3file`: >
  #!/any string/python2		" Shebang. Must be the first line of the file.
  #!/any string/python3		" Shebang. Must be the first line of the file.
  # requires python 2.x		" Maximum lines depend on 'modelines'.
  # requires python 3.x		" Maximum lines depend on 'modelines'.
Unlike normal modelines, the bottom of the file is not checked.
If none of them are found, the 'pyxversion' setting is used.
							*W20* *W21*
If Vim does not support the selected Python version a silent message will be
printed.  Use `:messages` to read them.

							*:pyxdo*
The `:pyxdo` command works similar to `:pydo`.

							*has-pythonx*
You can test if pyx* commands are available with: >
	if has('pythonx')
	  echo 'pyx* commands are available. (Python ' . &pyx . ')'
	endif

When compiled with only one of |+python| or |+python3|, the has() returns 1.
When compiled with both |+python| and |+python3|, the test depends on the
'pyxversion' setting.  If 'pyxversion' is 0, it tests Python 3 first, and if
it is not available then Python 2.  If 'pyxversion' is 2 or 3, it tests only
Python 2 or 3 respectively.

Note that for `has('pythonx')` to work it may try to dynamically load Python 3
or 2.  This may have side effects, especially when Vim can only load one of
the two.

If a user prefers Python 2 and want to fallback to Python 3, he needs to set
'pyxversion' explicitly in his |.vimrc|.  E.g.: >
	if has('python')
	  set pyx=2
	elseif has('python3')
	  set pyx=3
	endif

==============================================================================
12. Building with Python support			*python-building*

A few hints for building with Python 2 or 3 support.

UNIX

See src/Makefile for how to enable including the Python interface.

On Ubuntu you will want to install these packages for Python 2:
	python
	python-dev
For Python 3:
	python3
	python3-dev
For Python 3.6:
	python3.6
	python3.6-dev

If you have more than one version of Python 3, you need to link python3 to the
one you prefer, before running configure.

==============================================================================
 vim:tw=78:ts=8:noet:ft=help:norl:
