Wing IDE Reference Manual
   
Wing IDE Reference Manual

Version 1.1.10


next up previous contents
Next: C. Software License Up: Reference Manual Wing IDE Previous: A. Command Reference


Subsections

B. Wing Tips

This appendix provides tips for usage and pointers to useful online resources for developers using Wing IDE.

B.1 Online Resources for Wing IDE

Archaeopteryx Software provides a number of support resources free of charge. All of these are available on the web at http://wingide.com/support.

B.2 Python Language Reference

The Python Language Reference, maintained by the developers of Python, is available online at www.python.org or from the Help menu in Wing IDE.

This reference manual contains the following parts:

B.3 Useful Tools

This section describes some useful tools that are available to Python programmers but that have not yet been integrated into the Wing's graphical user interface.

B.3.1 Performance Profiling

Performance profiling is supported by the Python profile and pstats modules.

To create a profile file named profile.tmp for invocation of a function main() you would include the following code in your application:

import profile
profile.run('import mymodule; mymodule.main()', 'profile.tmp')
       

This will accumulate profile data while running the function main() in module mymodule. Note that importing and fully specifying the module scope is important if you plan to run the profiler under the Wing debugger. The profiler makes assumptions about scope that are violated by the debugger so just specifying profile.run('main()', 'profile.tmp') will not work.

Subsequently, the pstats module is used to inspect the contents of the profiler's output file. For example, the following command would sort the file by cumulative time spent in each function, and then print out the top 10 compute-intensive calls:

import pstats
p = pstats.Stats('profile.tmp')
p.sort_stats('cumulative').print_stats(10)
       

Detailed documentation for profiling is available in the Python Library Reference under The Python Profiler.

B.3.2 Busting Object Reference Cycles (Python 1.5.2)

Because Python versions 2.0 and later contain code to detect and break object reference cycles, you may not need to worry about cyclical references unless you are using Python 1.5.2.

A common problem in reference counted garbage-collected languages like Python is memory leakage due to cyclical object references. This occurs in cases where an object A has a reference to another object B that has a reference back to object A. The interpreter fails to discard memory held by these objects even if they become unused by the program because a non-zero reference count exists as a result of the cycle.

Cycles may be much longer than just two objects, for example A -> B -> C -> D -> A would result in failure to discard objects A through D.

In these cases, a long-running program will eventually run out of memory as more and more objects are left intact because of their participation in object reference cycles.


B.3.2.1 Cyclops

A Python module called Cyclops is available for monitoring your program as it runs, to determine when cyclical memory references are preventing the Python interpreter from discarding unused objects.

This module can be used to print information on existing cycles at any time, including at time of program exit.

The following function might be used to invoke a function called main and then output cycle information for modules and functions upon exit:

#------------------------------------
def RunWithCyclops():
  """Run the main program under Cyclops.  Require Cyclops.py found at
  http://www.python.org/ftp/python/contrib/System/Cyclops.py."""

from cyclops import Cyclops import types

def mod_refs(x): return x.__dict__.values()

def mod_tag(x, i): return "." + x.__dict__.keys()[i]

def func_refs(x): return x.func_globals, x.func_defaults

def func_tag(x, i): return (".func_globals", ".func_defaults")[i]

def instance_filter(cycle): for obj, index in cycle: if type(obj) is types.InstanceType: return 1 return 0

z = Cyclops.CycleFinder() z.chase_type(types.ModuleType, mod_refs, mod_tag) z.chase_type(types.FunctionType, func_refs, func_tag)

z.run(main) z.find_cycles() z.show_stats() z.show_cycles()

Once cycles are found, the most effective method for fixing the resulting memory leaks is to introduce a destroy function that manually clears references that are causing a cycle (for example, by setting them to None or by calling the clear() method on Python dictionaries or sequences.

If a cycle is broken at a single point in this way, all objects in the cycle will subsequently be freed. For this reason, busting cycles tends to be relatively easy.

For more information on using Cyclops, please refer to documentation within the copy located in WINGHOME/cyclops.

B.3.3 Debugging C/C++ Modules (on Linux/Unix)

Gdb can be used as a tool to aid in debugging C/C++ extension modules written for Python, although doing so can be a bit tricky and prone to problems. The following text contains hints to make this easier.

Note that this section assumes you are already familiar with gdb; for more information on gdb commands, please refer to the gdb documentation.

The first step in debugging C/C++ modules with gdb is to make sure that you are using a version of Python that was compiled with debug symbols. To do this, you need a source distribution of Python and you need to configure the distribution as described in the accompanying README file.

In most cases, this can be done as follows: (1) Type ./configure, (2) type make OPT=-g or edit the Makefile so OPT=-g, (3) type make, and (4) once the build is complete, install it with make install (but see the README first if you don't want to install into /usr/local/lib/python).

If you are building an extension module that you are compiling into the Python interpreter, you can now just run Python within gdb, set a breakpoint at the desired location in your extension module, and execute your Python test program.

In most cases, however, the extension module is not compiled into Python but is instead loaded dynamically at runtime. In order to get your extension module to load, it must be on the PYTHONPATH or within the same directory where the module is import-ed into Python source.

Gdb additionally requires setting LD_LIBRARY_PATH to include the directory where the dynamically loaded module is located. A common problem in doing this is that gdb will reread .cshrc each time that it runs, so setting LD_LIBRARY_PATH before invoking gdb has no effect if you also set LD_LIBRARY_PATH in .cshrc. To work around this, set LD_LIBRARY_PATH in .profile instead. This file is read only once at login time.

Then start Python as follows:

myhost> gdb
(gdb) file python
(gdb) run yourprogram.py yourargs
       

Note that breakpoints in a shared library cannot be set until after the shared library is loaded. If running your program triggers loading of your extension module library, you can use ^C^C to interrupt the debug program, set breakpoints, and then continue.

Otherwise, you must continue running your program until the extension module is loaded. When in doubt, add a print statement at point of import, or you can set a breakpoint at PyImport_AddModule (this can be set after file python and before running since this call is not in a shared library).

Unfortunately, even if you take all of the above steps, gdb will often get confused if you load and unload shared libraries repeatedly during a single debug session. You can usually re-run Python 5-10 times but subsequently may see crashing, failure to stop at breakpoints, or other odd behaviors. When this occurs, there is no alternative but to exit and restart gdb.

Finally a hint for viewing Python data from the C/C++ side when using gdb. The following gdb command will print out the contents of a PyObject * called obj as if you had issued the command print obj from within the Python language:

(gdb) p PyObject_Print (obj, stderr, 0)
       

B.4 Wing IDE Source Code

The source code for Wing IDE is available to all users that have a permanent (non-evaluation) license to Wing IDE Standard or higher product level. This section contains information that may be useful to those wanting to delve into the source code to make changes or add custom features.

B.4.1 Setting up the Source

Before getting started, you should download and install the source distributions, as described in section 1.9.

Once the source is installed, see the document build-files/README.txt for build instructions.

If you have problems getting set up for source development, please send email to support@wingide.com.

B.4.2 Top-level Organization

The source code, relative to the top level of the Wing IDE installation, is organized into three major groups of functionality, according to its origin and the distribution licenses that apply to the code:

B.4.3 IDE Sub-systems

Distributed among the above directories are the following major sub-systems of the IDE:

B.4.4 Documentation

Throughout the source, Python documentation strings and comments are used to describe the code. As a result, most documentation is located within the code itself.

Each IDE module also has a README file containing at least some text identifying the module. This may also contain high level documentation for the module's source, so it's a good place to start when inspecting the code.

The top-level docstring (at start of each Python file) contains a CVS logging area, which lists all recent revision comments for that file.

B.4.5 Naming Convention

Three techniques are used to build names for language constructs in the Wing IDE source code: (1) leading underscores indicate the public, semi-private, and private nature of the construct, (2) prefix letters are used to indicate the type of some constructs, and (3) capitalization is used to indicate the type of some constructs. This naming style is used with all Python language constructs, including classes, functions, methods, variables, attributes, and in some cases module names.

B.4.5.1 Underscoring

The presence and number of underscores before construct names is used to indicate the scope of access intended for that construct.

B.4.5.2 Prefixing

A prefix-based naming convention is also applied to some language constructs, as follows:

B.4.5.3 Capitalization

Capitalization of letters within construct names is also standardized:

Underscoring, prefixing, and capitalization are combined as appropriate for all constructs, to build names like _CMyClass (a semi-private class), kAValue (a public constant), and __fCount (a private instance attribute).


next up previous contents
Next: C. Software License Up: Reference Manual Wing IDE Previous: A. Command Reference   Contents



2003-08-28