1from __future__ import with_statement
2
3import os
4import sys
5import errno
6
7try:
8  from lxml import etree
9  have_lxml = True
10except ImportError:
11    have_lxml = False
12    try:
13        # Python 2.5
14        from xml.etree import cElementTree as etree
15    except ImportError:
16        try:
17            # Python 2.5
18            from xml.etree import ElementTree as etree
19        except ImportError:
20            try:
21                # normal cElementTree install
22                import cElementTree as etree
23            except ImportError:
24                try:
25                    # normal ElementTree install
26                    import elementtree.ElementTree as etree
27                except ImportError:
28                    etree = None
29
30from Cython.Compiler import Errors
31
32
33class CythonDebugWriter(object):
34    """
35    Class to output debugging information for cygdb
36
37    It writes debug information to cython_debug/cython_debug_info_<modulename>
38    in the build directory.
39    """
40
41    def __init__(self, output_dir):
42        if etree is None:
43            raise Errors.NoElementTreeInstalledException()
44
45        self.output_dir = os.path.join(output_dir, 'cython_debug')
46        self.tb = etree.TreeBuilder()
47        # set by Cython.Compiler.ParseTreeTransforms.DebugTransform
48        self.module_name = None
49        self.start('cython_debug', attrs=dict(version='1.0'))
50
51    def start(self, name, attrs=None):
52        self.tb.start(name, attrs or {})
53
54    def end(self, name):
55        self.tb.end(name)
56
57    def serialize(self):
58        self.tb.end('Module')
59        self.tb.end('cython_debug')
60        xml_root_element = self.tb.close()
61
62        try:
63            os.makedirs(self.output_dir)
64        except OSError, e:
65            if e.errno != errno.EEXIST:
66                raise
67
68        et = etree.ElementTree(xml_root_element)
69        kw = {}
70        if have_lxml:
71            kw['pretty_print'] = True
72
73        fn = "cython_debug_info_" + self.module_name
74        et.write(os.path.join(self.output_dir, fn), encoding="UTF-8", **kw)
75
76        interpreter_path = os.path.join(self.output_dir, 'interpreter')
77        with open(interpreter_path, 'w') as f:
78            f.write(sys.executable)
79