DebugWriter.py 1.9 KB
Newer Older
Stefan Behnel's avatar
Stefan Behnel committed
1
from __future__ import absolute_import
2

Mark Florisson's avatar
Mark Florisson committed
3
import os
4
import sys
Mark Florisson's avatar
Mark Florisson committed
5 6 7
import errno

try:
8 9
    from lxml import etree
    have_lxml = True
Mark Florisson's avatar
Mark Florisson committed
10 11 12 13 14 15 16 17
except ImportError:
    have_lxml = False
    try:
        from xml.etree import cElementTree as etree
    except ImportError:
        try:
            from xml.etree import ElementTree as etree
        except ImportError:
Stefan Behnel's avatar
Stefan Behnel committed
18 19 20
            etree = None

from ..Compiler import Errors
Mark Florisson's avatar
Mark Florisson committed
21 22 23 24 25


class CythonDebugWriter(object):
    """
    Class to output debugging information for cygdb
26

Mark Florisson's avatar
Mark Florisson committed
27 28 29
    It writes debug information to cython_debug/cython_debug_info_<modulename>
    in the build directory.
    """
30

Mark Florisson's avatar
Mark Florisson committed
31 32 33
    def __init__(self, output_dir):
        if etree is None:
            raise Errors.NoElementTreeInstalledException()
34

35
        self.output_dir = os.path.join(output_dir or os.curdir, 'cython_debug')
Mark Florisson's avatar
Mark Florisson committed
36 37 38 39
        self.tb = etree.TreeBuilder()
        # set by Cython.Compiler.ParseTreeTransforms.DebugTransform
        self.module_name = None
        self.start('cython_debug', attrs=dict(version='1.0'))
40

Mark Florisson's avatar
Mark Florisson committed
41 42
    def start(self, name, attrs=None):
        self.tb.start(name, attrs or {})
43

Mark Florisson's avatar
Mark Florisson committed
44 45 46
    def end(self, name):
        self.tb.end(name)

47 48 49 50
    def add_entry(self, name, **attrs):
        self.tb.start(name, attrs)
        self.tb.end(name)

Mark Florisson's avatar
Mark Florisson committed
51 52 53 54 55 56 57
    def serialize(self):
        self.tb.end('Module')
        self.tb.end('cython_debug')
        xml_root_element = self.tb.close()

        try:
            os.makedirs(self.output_dir)
58
        except OSError as e:
Mark Florisson's avatar
Mark Florisson committed
59 60 61 62 63 64 65
            if e.errno != errno.EEXIST:
                raise

        et = etree.ElementTree(xml_root_element)
        kw = {}
        if have_lxml:
            kw['pretty_print'] = True
66

Mark Florisson's avatar
Mark Florisson committed
67
        fn = "cython_debug_info_" + self.module_name
68
        et.write(os.path.join(self.output_dir, fn), encoding="UTF-8", **kw)
69

70 71 72
        interpreter_path = os.path.join(self.output_dir, 'interpreter')
        with open(interpreter_path, 'w') as f:
            f.write(sys.executable)