• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import sys, os
2
3if sys.version_info < (3,):
4    __all__ = ['u', 'arraytostring']
5
6    class U(object):
7        def __add__(self, other):
8            return eval('u'+repr(other).replace(r'\\u', r'\u')
9                                       .replace(r'\\U', r'\U'))
10    u = U()
11    long = long     # for further "from testing.support import long"
12    assert u+'a\x00b' == eval(r"u'a\x00b'")
13    assert u+'a\u1234b' == eval(r"u'a\u1234b'")
14    assert u+'a\U00012345b' == eval(r"u'a\U00012345b'")
15    def arraytostring(a):
16        return a.tostring()
17
18else:
19    __all__ = ['u', 'unicode', 'long', 'arraytostring']
20    u = ""
21    unicode = str
22    long = int
23    def arraytostring(a):
24        return a.tobytes()
25
26
27class StdErrCapture(object):
28    """Capture writes to sys.stderr (not to the underlying file descriptor)."""
29    def __enter__(self):
30        try:
31            from StringIO import StringIO
32        except ImportError:
33            from io import StringIO
34        self.old_stderr = sys.stderr
35        sys.stderr = f = StringIO()
36        if hasattr(sys, '__unraisablehook__'):           # work around pytest
37            self.old_unraisablebook = sys.unraisablehook # on recent CPythons
38            sys.unraisablehook = sys.__unraisablehook__
39        return f
40    def __exit__(self, *args):
41        sys.stderr = self.old_stderr
42        if hasattr(self, 'old_unraisablebook'):
43            sys.unraisablehook = self.old_unraisablebook
44
45
46class FdWriteCapture(object):
47    """xxx limited to capture at most 512 bytes of output, according
48    to the Posix manual."""
49
50    def __init__(self, capture_fd=2):    # stderr by default
51        if sys.platform == 'win32':
52            import py
53            py.test.skip("seems not to work, too bad")
54        self.capture_fd = capture_fd
55
56    def __enter__(self):
57        import os
58        self.read_fd, self.write_fd = os.pipe()
59        self.copy_fd = os.dup(self.capture_fd)
60        os.dup2(self.write_fd, self.capture_fd)
61        return self
62
63    def __exit__(self, *args):
64        import os
65        os.dup2(self.copy_fd, self.capture_fd)
66        os.close(self.copy_fd)
67        os.close(self.write_fd)
68        self._value = os.read(self.read_fd, 512)
69        os.close(self.read_fd)
70
71    def getvalue(self):
72        return self._value
73
74def _verify(ffi, module_name, preamble, *args, **kwds):
75    import imp
76    from cffi.recompiler import recompile
77    from .udir import udir
78    assert module_name not in sys.modules, "module name conflict: %r" % (
79        module_name,)
80    kwds.setdefault('tmpdir', str(udir))
81    outputfilename = recompile(ffi, module_name, preamble, *args, **kwds)
82    module = imp.load_dynamic(module_name, outputfilename)
83    #
84    # hack hack hack: copy all *bound methods* from module.ffi back to the
85    # ffi instance.  Then calls like ffi.new() will invoke module.ffi.new().
86    for name in dir(module.ffi):
87        if not name.startswith('_'):
88            attr = getattr(module.ffi, name)
89            if attr is not getattr(ffi, name, object()):
90                setattr(ffi, name, attr)
91    def typeof_disabled(*args, **kwds):
92        raise NotImplementedError
93    ffi._typeof = typeof_disabled
94    for name in dir(ffi):
95        if not name.startswith('_') and not hasattr(module.ffi, name):
96            setattr(ffi, name, NotImplemented)
97    return module.lib
98
99
100# For testing, we call gcc with "-Werror".  This is fragile because newer
101# versions of gcc are always better at producing warnings, particularly for
102# auto-generated code.  We need here to adapt and silence them as needed.
103
104if sys.platform == 'win32':
105    extra_compile_args = []      # no obvious -Werror equivalent on MSVC
106else:
107    if (sys.platform == 'darwin' and
108          [int(x) for x in os.uname()[2].split('.')] >= [11, 0, 0]):
109        # assume a standard clang or gcc
110        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion',
111                              '-Wno-unused-parameter',
112                              '-Wno-unreachable-code']
113        # special things for clang
114        extra_compile_args.append('-Qunused-arguments')
115    else:
116        # assume a standard gcc
117        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion',
118                              '-Wno-unused-parameter',
119                              '-Wno-unreachable-code']
120