<type>documentation</type>
<domain>edit</domain>
<id>analysis-helping-pyi-files</id>
<title>Defining Interface Files</title>
<date>$Date: 2007-02-09 12:04:39 -0500 (Fri, 09 Feb 2007) $</date>
<version>$Revision: 14785 $</version>
<product>all</product>

Creating a ``*.pyi`` Python Interface file is another way to describe the contents of a
module that Wing has trouble analyzing. This file is simply a Python skeleton with the
appropriate structure, call signature, and return values to match the functions,
attributes, classes, and methods defined in a module.

Wing reads the ``*.pyi`` and merges its contents with any information it obtained through
direct inspection of the module. ``.pyi`` files can use `PEP 484
<https://www.python.org/dev/peps/pep-0484/>`__ (Python 3.5+) and `PEP 526
<https://www.python.org/dev/peps/pep-0526/>`__ (Python 3.6+) type annotations, regardless
of whether Python 2 or Python 3 is being used.

Wing also supports reading interface files named ``*.pi`` but these cannot use PEP 484 or
PEP 526 type annotations. The ``.pi`` extension was used in previous versions of Wing that
predated the PEPs. It is still supported but should not be used for newly created
interface files.

In somes cases, as for Python bindings for GUI and other toolkits, ``*.pyi`` or ``*.pyi``
files can be auto-generated from interface description files. The code that Wing uses to
automatically generate ``*.pi`` files from extension modules is in
``src/wingutils/generate_pi.py`` in your Wing installation, and another example that is
used to generate interface information for PyGTK is in ``src/wingutils/pygtk_to_pi.py``.

**Naming and Placing \*.pyi Files**

Wing expects the ``*.pyi`` file name to match the name of the module. For example, if the
name referenced by ``import`` is ``mymodule`` then Wing looks for ``mymodule.pyi``.

The most common place to put the ``*.pyi`` file is in the same directory as the ``*.pyd``,
``*.so``, or ``*.py`` module it is describing. ``*.pyi`` files that describe entire
packages (directories containing ``__init__.py``) should be placed in the package
directory's parent directory.

If Wing cannot find the ``*.pyi`` file in the same directory as the module, it proceeds to
search as follows, choosing the first matching ``*.pyi`` file:

1) In the path set with the `Source Analysis > Advanced > Interface File Path
   <script:show_preferences_gui#prefname="pysource.interfaces-path">`__ preference.
   
2) In the ``resources/builtin-pi-files`` in the Wing installation.  This
   is used to ship type overrides for Python's builtin types and standard library.

3) In ``resources/package-pi-files``, which is used to ship some ``*.pyi`` files 
   for commonly used third party packages.

For all of these, Wing inspects the path directory for a matching ``*.pyi`` file and
treats any sub-directories as packages.

In cases where Wing cannot find a ``*.pyi`` at all for a C/C++ extension module, it will
still attempt to load the extension module by name, in a separate process space, so that
it can introspect its contents. The results of this operation are stored in ``pi-cache``
within the ``Cache Directory`` shown in Wing's `About <script:about-application>`__ box.
This file is regenerated only if the ``*.pyd`` or ``*.so`` for the loaded extension module
changes.

**Merging \*.pyi Name Spaces**

When Wing finds a ``*.pyi`` file, it merges the contents of the ``*.pyi`` file with any
information found by analyzing or introspecting the module itself. The contents of the
``*.pyi`` file take precedence when symbols are defined in both places.

**Creating \*.pyi Variants by Python Version**

In rare cases, you may need to create variants of your ``*.pyi`` files according to Python
version. An example of this is in ``resources/builtin-pi-files``, the directory used to
ship type overrides for Python's builtin types and standard library.

Wing always looks first at the top level of an interface path directory for a matching
``*.pyi`` file. If this fails then Wing tries looking in a sub-directory ``#.#`` named
according to the major and minor version of Python being used with your source base, and
subsequently in each lower major/minor version back to ``2.0``.

For example, if ``c:\share\pi\pi-files`` is on the interfaces path and Python 2.7 is being
used, Wing will check first in ``c:\share\pi\pi-files``, then in
``c:\share\pi\pi-files\2.7``. then in ``c:\share\pi\pi-files\2.6``, and so forth.

