There are a number of ways of assistant Wing's static source analyzer in determining the type of values in Python code.
Using Live Runtime State
When a debug process is active, or when working in the Python Shell, Wing extracts relevant type information from the live runtime state associated with your Python code. Since this yields complete and correct type information even for code that Wing's static analysis engine cannot understand, it is often useful to run to a breakpoint before designing new code that is intended to work in that context. In the editor, the cog icon in the auto-completer indicates that type information was found in the live runtime state. In Wing IDE Professional, the Debug Probe can be used to immediately try out new code in the runtime environment for which it is being designed.
Using isinstance() to Assist Analysis
One way to inform the code analysis facility of the type of a variable is to add an isinstance call in your code. For example isinstance(obj, CMyClass) or assert isinstance(obj, CMyClass) when runtime type checking is desired. The code analyzer will pick up on these and present more complete information for the asserted values.
In cases where doing this introduces a circular import, you can use a conditional to allow Wing's static analyser to process the code without causing problems when it is executed:
if 0: import othermodule assert isinstance(myvariable, othermodule.COtherClass)
In most code, a few isinstance calls go a long way to making code faster and easier to edit and navigate.
Using *.pi files to Assist Analysis
Wing's source analyser can only read Python code and does not contain support for understanding C/C++ extension module code other than by attempting to import the extension module and introspecting its contents (which yields only a limited amount of information and cannot determine argument number, name, or types). Also, since Python is a dynamic language, it is possible to craft code that Wing's static analysis engine cannot understand.
For both of these cases, it is possible to create a *.pi (Python interface) file that describes the contents of a module. This file is simply a Python skeleton with the appropriate structure and call signature to match the functions, attributes, classes, and methods defined in a module. Wing IDE will read this file and merge its contents with any information it can obtain through static analysis or by loading an extension module. In somes cases, as for Python bindings for GUI and other toolkits, these *.pi files can be auto-generated from interface description files.
For a module imported as mymodule, the interface file is called mymodule.pi. Wing will search for *.pi files first in the same directory as it finds the Python module (or the extension module source code if it has not yet been compiled and the source code's directory is on your configured Python Path). If not found, Wing will look in the directory path set with the Interfaces Path preference. Next, Wing will look in the resources/builtin-pi-files directory within your Wing IDE installation. Finally, Wing will look in resources/packages-pi-files, which is used to ship some *.pi files for commonly used third party packages.
When searching on the interfaces path or in the resources directories, the top level of the directory is checked first for a matching *.pi file. 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.
Example *.pi files used by Wing internally to produce autocompletion information for builtins can be seen in the directory resources/builtin-pi-files inside your Wing IDE installation. This also illustrates the above-described version number fallback mechanism.
In cases where Wing cannot find a *.pi at all, it will attempt to load the 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 User Settings Directory and used subsequently. This file is regenerated only if the *.pyd or *.so for the loaded module changes.
|« 15.1. Static Analysis Limitations||Table of Contents||15.3. Analysis Disk Cache »|