sampledoc

Please contact info@pyxll.com with any enquiries.

Current version: 1.3.2

Table Of Contents

Previous topic

Object cache

Next topic

Forum

Developer Tools

Debugging with Eclipse and PyDev

This example shows how to attach the PyDev interactive debugger to Python code running in PyXLL.

This module must be loaded by PyXLL by adding it to the modules list in the pyxll config.

"""
PyXLL Examples: eclipse_debug.py

PyDev can be used to interactively debug Python code running
in Excel via PyXLL.

Before using this script you must have Eclipse and PyDev
installed:

http://www.eclipse.org/
http://pydev.org/

To be able to attach the PyDev debugger to Excel and you
Python code open the PyDev Debug perspective in Eclipse
and start the PyDev server by clicking the toolbar
button with a bug and a small P on it (hover over for the
tooltip).

Any python process can now attach to the PyDev debug
server by importing the 'pydevd' module included as part
of PyDev and calling pydevd.settrace()

This module adds an Excel menu item to attach to the
PyDev debugger, and also an Excel macro so that this
script can be run outside of Excel and call PyXLL to
attach to the PyDev debugger.

See http://pydev.org/manual_adv_remote_debugger.html
for more details about remote debugging using PyDev.

"""
import sys
import os
import logging

_log = logging.getLogger(__name__)

## UPDATE THIS TO MATCH YOUR VERSION OF PYDEV
_pydev_src = r"plugins\org.python.pydev.debug_2.3.0.2011121518\pysrc"

## UPDATE THIS TO WHERE YOU HAVE ECLIPSE INSTALLED
_eclipse_root = r"C:\Program Files\Eclipse"

# add the pysrc to the path for importing pydev
sys.path.append(os.path.join(_eclipse_root, _pydev_src))

def main():
    import win32com.client

    # get Excel and call the macro declared below
    xl_app = win32com.client.GetActiveObject("Excel.Application")
    xl_app.Run("attach_to_pydev")

#
# PyXLL function for attaching to the debug server
#
try:
    from pyxll import xl_menu, xl_macro

    # if this doesn't import check the paths above
    try:
        import pydevd
    except ImportError:
        _log.warn("pydevd failed to import")
        _log.warn("Check the eclipse path in %s" % __file__)
        raise

    # this creates a menu item and a macro from the same function
    @xl_menu("Attach to PyDev")
    @xl_macro()
    def attach_to_pydev():
        pydevd.settrace()

except ImportError:
    pass

if __name__ == "__main__":
    sys.exit(main())

Reloading and importing modules

This example shows how to use the pyxll_reload and pyxll_rebind commands from outside Excel to reload and import modules in PyXLL. This can be useful when combined with calling this or a similar script from an editor.

This module must be loaded by PyXLL by adding it to the modules list in the pyxll config.

"""
PyXLL Examples: reload.py

This script can be called from outside of Excel to load and
reload modules using PyXLL.

It uses win32com (part of pywin32) to call into Excel to two built-in
PyXLL Excel macros ('pyxll_reload' and 'pyxll_rebind') and another
macro 'pyxll_import_file' defined in this file.

The PyXLL reload and rebind commands are only available in developer mode,
so ensure that developer_mode in the pyxll.cfg configuration is set to 1.

Excel must already be running for this script to work.

Example Usage:

# reload all modules
python reload.py

# reload a specific module
python reload.py <filename>
"""

# pywin32 must be installed to run this script
import win32com.client
import sys
import os
import cPickle

def main():
    # any arguments are assumed to be filenames
    # of modules to reload
    filenames = None
    if len(sys.argv) > 1:
        filenames = sys.argv[1:]

    # this will fail if Excel isn't running
    xl_app = win32com.client.GetActiveObject("Excel.Application")

    # load the modules listed on the command line by
    # calling the macro defined in this file.
    if filenames:
        for filename in filenames:
            filename = os.path.abspath(filename)
            print "re/importing %s" % filename
            response = xl_app.Run("pyxll_import_file", filename)
            response = cPickle.loads(str(response))
            if isinstance(response, Exception):
                raise response

        # once all the files have been imported or reloaded
        # call the built-in pyxll_rebind macro to update the
        # Excel functions without reloading anything else
        xl_app.Run("pyxll_rebind")
        print "Rebound PyXLL functions"

    else:
        # call the built-in pyxll__reload macro
        xl_app.Run("pyxll_reload")
        print "Reloaded all PyXLL modules"

#
# in order to be able to reload particular files we add
# an Excel macro that has to be loaded by PyXLL
#
try:
    from pyxll import xl_macro

    @xl_macro("string filename: string")
    def pyxll_import_file(filename):
        """
        imports or reloads a python file.

        Returns an Exception on failure or True on success
        as a pickled string.
        """
        # keep a copy of the path to restore later
        sys_path = list(sys.path)
        try:
            # insert the path to the pythonpath
            path = os.path.dirname(filename)
            sys.path.insert(0, path)

            try:
                # try to load/reload the module
                basename = os.path.basename(filename)
                modulename, ext = os.path.splitext(basename)
                if modulename in sys.modules:
                    module = sys.modules[modulename]
                    reload(module)
                else:
                    __import__(modulename)

            except Exception, e:
                # return the pickled exception
                return cPickle.dumps(e)

        finally:
            # restore the original path
            sys.path = sys_path

        return cPickle.dumps(True)

except ImportError:
    pass

if __name__ == "__main__":
    sys.exit(main())