File: _pypy_testcapi.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (123 lines) | stat: -rw-r--r-- 4,344 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os, sys

import tempfile, binascii
import importlib.machinery
from importlib.util import spec_from_file_location, module_from_spec


def _get_hashed_filename(cfile):
    with open(cfile,'r') as fid:
        content = fid.read()
    # from cffi's Verifier()
    key = '\x00'.join([sys.version[:3], content])
    # change the key to force recompilation
    key += '2017-11-21'
    if sys.version_info >= (3,):
        key = key.encode('utf-8')
    k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
    k1 = k1.lstrip('0x').rstrip('L')
    k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff)
    k2 = k2.lstrip('0').rstrip('L')
    try:
        username = os.environ['USER']           #linux, et al
    except KeyError:
        try:
            username = os.environ['USERNAME']   #windows
        except KeyError:
            username = os.getuid()
    return tempfile.gettempdir() + os.path.sep + 'testcapi_%s_%s%s' % (
        username, k1, k2)

def get_hashed_dir(cfile):
    hashed_fn = _get_hashed_filename(cfile)
    try:
        with open(hashed_fn) as f:
            dirname = f.read(1024)
    except IOError:
        dirname = ''
    tmpdir = tempfile.gettempdir()
    if (not dirname or '/' in dirname or '\\' in dirname or '\x00' in dirname
            or not os.path.isdir(os.path.join(tmpdir, dirname))):
        dirname = binascii.hexlify(os.urandom(8))
        if not isinstance(dirname, str):    # Python 3
            dirname = dirname.decode('ascii')
        dirname = 'testcapi_' + dirname
    output_dir = os.path.join(tmpdir, dirname)
    try:
        os.mkdir(output_dir)
    except OSError:
        pass
    return output_dir


def _get_c_extension_suffix():
    suffixes = importlib.machinery.EXTENSION_SUFFIXES
    return suffixes[0] if suffixes else None


def compile_shared(csource, modulename, output_dir):
    """Compile '_testcapi.c' or '_ctypes_test.c' into an extension module,
    and import it.
    """
    thisdir = os.path.dirname(__file__)
    assert output_dir is not None

    from distutils.ccompiler import new_compiler
    from distutils import log, sysconfig
    log.set_verbosity(3)

    compiler = new_compiler()
    compiler.output_dir = output_dir
    # Compile .c file
    include_dir = sysconfig.get_config_var('INCLUDEPY')
    if sys.platform == 'win32':
        ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
    else:
        ccflags = ['-fPIC', '-Wimplicit-function-declaration', '-O0', '-g3']
    sysconfig.customize_compiler(compiler)
    res = compiler.compile([os.path.join(thisdir, csource)],
                           include_dirs=[include_dir],
                           extra_preargs=ccflags,
                          )
    object_filename = res[0]

    # set link options
    output_filename = modulename + _get_c_extension_suffix()
    if sys.platform == 'win32':
        libname = 'python{0[0]}{0[1]}'.format(sys.version_info)
        library = os.path.join(thisdir, '..', 'libs', libname)
        if not os.path.exists(library + '.lib'):
            # For a local translation or nightly build
            library = os.path.join(thisdir, '..', 'pypy', 'goal', libname)
        assert os.path.exists(library + '.lib'), 'Could not find import library "%s"' % library
        libraries = [library, 'oleaut32']
        extra_ldargs = ['/MANIFEST',  # needed for VC10
                        '/EXPORT:PyInit_' + modulename]
    else:
        libraries = []
        extra_ldargs = []

    # link the dynamic library
    compiler.link_shared_object(
        [object_filename],
        output_filename,
        libraries=libraries,
        extra_preargs=extra_ldargs)

    # Now import the newly created library, it will replace the original
    # module in sys.modules
    spec = spec_from_file_location(modulename,
                                   os.path.join(output_dir, output_filename))
    mod = module_from_spec(spec)

    # If everything went fine up to now, write the name of this new
    # directory to 'hashed_fn', for future processes (and to avoid a
    # growing number of temporary directories that are not completely
    # obvious to clean up on Windows)
    hashed_fn = _get_hashed_filename(os.path.join(thisdir, csource))
    try:
        with open(hashed_fn, 'w') as f:
            f.write(os.path.basename(output_dir))
    except IOError:
        pass
    return mod