1515
1616from __future__ import print_function
1717
18- from distutils .sysconfig import get_config_var
19- from subprocess import Popen , CalledProcessError , PIPE
20- from pycparser import c_parser , c_ast
2118import logging
22- import sys
2319import os
20+ import sys
21+ import sysconfig
22+ import subprocess
23+
24+ from pycparser import c_ast , c_parser
2425
2526_log = logging .getLogger ()
2627logging .basicConfig (level = logging .DEBUG )
2728
29+ PY_MAJOR = sys .version_info [0 ]
30+ PY_MINOR = sys .version_info [1 ]
2831
2932# rename some members from their C name when generating the C#
3033_typeoffset_member_renames = {
3336}
3437
3538
39+ def _check_output (* args , ** kwargs ):
40+ """Check output wrapper for py2/py3 compatibility"""
41+ output = subprocess .check_output (* args , ** kwargs )
42+ if PY_MAJOR == 2 :
43+ return output
44+ return output .decode ("ascii" )
45+
46+
3647class AstParser (object ):
3748 """Walk an AST and determine the members of all structs"""
3849
@@ -147,23 +158,6 @@ def __get_struct_name(self, node):
147158 return node .name or "_struct_%d" % id (node )
148159
149160
150- def check_output (* popenargs , ** kwargs ):
151- """subprocess.check_output from python 2.7.
152- Added here to support building for earlier versions of Python.
153- """
154- process = Popen (stdout = PIPE , * popenargs , ** kwargs )
155- output , unused_err = process .communicate ()
156- retcode = process .poll ()
157- if retcode :
158- cmd = kwargs .get ("args" )
159- if cmd is None :
160- cmd = popenargs [0 ]
161- raise CalledProcessError (retcode , cmd )
162- if sys .version_info [0 ] > 2 :
163- return output .decode ("ascii" )
164- return output
165-
166-
167161def preprocess_python_headers ():
168162 """Return Python.h pre-processed, ready for parsing.
169163 Requires clang.
@@ -172,7 +166,7 @@ def preprocess_python_headers():
172166 "fake_libc_include" )
173167 include_dirs = [fake_libc_include ]
174168
175- include_py = get_config_var ("INCLUDEPY" )
169+ include_py = sysconfig . get_config_var ("INCLUDEPY" )
176170 include_dirs .append (include_py )
177171
178172 defines = [
@@ -195,7 +189,7 @@ def preprocess_python_headers():
195189
196190 # normalize as the parser doesn't like windows line endings.
197191 lines = []
198- for line in check_output (cmd ).splitlines ():
192+ for line in _check_output (cmd ).splitlines ():
199193 if line .startswith ("#" ):
200194 line = line .replace ("\\ " , "/" )
201195 lines .append (line )
@@ -206,7 +200,7 @@ def gen_interop_code(members):
206200 """Generate the TypeOffset C# class"""
207201
208202 defines = [
209- "PYTHON%d%d" % ( sys . version_info [: 2 ] )
203+ "PYTHON{0}{1}" . format ( PY_MAJOR , PY_MINOR )
210204 ]
211205
212206 if hasattr (sys , "abiflags" ):
@@ -217,6 +211,8 @@ def gen_interop_code(members):
217211 if "u" in sys .abiflags :
218212 defines .append ("PYTHON_WITH_WIDE_UNICODE" )
219213
214+ filename = os .path .basename (__file__ )
215+ defines_str = " && " .join (defines )
220216 class_definition = """
221217// Auto-generated by %s.
222218// DO NOT MODIFIY BY HAND.
@@ -252,7 +248,7 @@ def gen_interop_code(members):
252248 }
253249
254250 // Auto-generated from PyHeapTypeObject in Python.h
255- """ % (os . path . basename ( __file__ ), " && " . join ( defines ) )
251+ """ % (filename , defines_str )
256252
257253 # All the members are sizeof(void*) so we don't need to do any
258254 # extra work to determine the size based on the type.
0 commit comments