Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cffi/ffiplatform.py: 18%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

97 statements  

1import sys, os 

2from .error import VerificationError 

3 

4 

5LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs', 

6 'extra_objects', 'depends'] 

7 

8def get_extension(srcfilename, modname, sources=(), **kwds): 

9 _hack_at_distutils() 

10 from distutils.core import Extension 

11 allsources = [srcfilename] 

12 for src in sources: 

13 allsources.append(os.path.normpath(src)) 

14 return Extension(name=modname, sources=allsources, **kwds) 

15 

16def compile(tmpdir, ext, compiler_verbose=0, debug=None): 

17 """Compile a C extension module using distutils.""" 

18 

19 _hack_at_distutils() 

20 saved_environ = os.environ.copy() 

21 try: 

22 outputfilename = _build(tmpdir, ext, compiler_verbose, debug) 

23 outputfilename = os.path.abspath(outputfilename) 

24 finally: 

25 # workaround for a distutils bugs where some env vars can 

26 # become longer and longer every time it is used 

27 for key, value in saved_environ.items(): 

28 if os.environ.get(key) != value: 

29 os.environ[key] = value 

30 return outputfilename 

31 

32def _build(tmpdir, ext, compiler_verbose=0, debug=None): 

33 # XXX compact but horrible :-( 

34 from distutils.core import Distribution 

35 import distutils.errors, distutils.log 

36 # 

37 dist = Distribution({'ext_modules': [ext]}) 

38 dist.parse_config_files() 

39 options = dist.get_option_dict('build_ext') 

40 if debug is None: 

41 debug = sys.flags.debug 

42 options['debug'] = ('ffiplatform', debug) 

43 options['force'] = ('ffiplatform', True) 

44 options['build_lib'] = ('ffiplatform', tmpdir) 

45 options['build_temp'] = ('ffiplatform', tmpdir) 

46 # 

47 try: 

48 old_level = distutils.log.set_threshold(0) or 0 

49 try: 

50 distutils.log.set_verbosity(compiler_verbose) 

51 dist.run_command('build_ext') 

52 cmd_obj = dist.get_command_obj('build_ext') 

53 [soname] = cmd_obj.get_outputs() 

54 finally: 

55 distutils.log.set_threshold(old_level) 

56 except (distutils.errors.CompileError, 

57 distutils.errors.LinkError) as e: 

58 raise VerificationError('%s: %s' % (e.__class__.__name__, e)) 

59 # 

60 return soname 

61 

62try: 

63 from os.path import samefile 

64except ImportError: 

65 def samefile(f1, f2): 

66 return os.path.abspath(f1) == os.path.abspath(f2) 

67 

68def maybe_relative_path(path): 

69 if not os.path.isabs(path): 

70 return path # already relative 

71 dir = path 

72 names = [] 

73 while True: 

74 prevdir = dir 

75 dir, name = os.path.split(prevdir) 

76 if dir == prevdir or not dir: 

77 return path # failed to make it relative 

78 names.append(name) 

79 try: 

80 if samefile(dir, os.curdir): 

81 names.reverse() 

82 return os.path.join(*names) 

83 except OSError: 

84 pass 

85 

86# ____________________________________________________________ 

87 

88try: 

89 int_or_long = (int, long) 

90 import cStringIO 

91except NameError: 

92 int_or_long = int # Python 3 

93 import io as cStringIO 

94 

95def _flatten(x, f): 

96 if isinstance(x, str): 

97 f.write('%ds%s' % (len(x), x)) 

98 elif isinstance(x, dict): 

99 keys = sorted(x.keys()) 

100 f.write('%dd' % len(keys)) 

101 for key in keys: 

102 _flatten(key, f) 

103 _flatten(x[key], f) 

104 elif isinstance(x, (list, tuple)): 

105 f.write('%dl' % len(x)) 

106 for value in x: 

107 _flatten(value, f) 

108 elif isinstance(x, int_or_long): 

109 f.write('%di' % (x,)) 

110 else: 

111 raise TypeError( 

112 "the keywords to verify() contains unsupported object %r" % (x,)) 

113 

114def flatten(x): 

115 f = cStringIO.StringIO() 

116 _flatten(x, f) 

117 return f.getvalue() 

118 

119def _hack_at_distutils(): 

120 # Windows-only workaround for some configurations: see 

121 # https://bugs.python.org/issue23246 (Python 2.7 with  

122 # a specific MS compiler suite download) 

123 if sys.platform == "win32": 

124 try: 

125 import setuptools # for side-effects, patches distutils 

126 except ImportError: 

127 pass