<s> from __future__ import absolute_import , print_function <EOL> import cython <EOL> from . . import __version__ <EOL> import re , os , sys , time <EOL> from glob import iglob <EOL> try : <EOL> import gzip <EOL> gzip_open = gzip . open <EOL> gzip_ext = '<STR_LIT>' <EOL> except ImportError : <EOL> gzip_open = open <EOL> gzip_ext = '<STR_LIT>' <EOL> import shutil <EOL> import subprocess <EOL> try : <EOL> import hashlib <EOL> except ImportError : <EOL> import md5 as hashlib <EOL> try : <EOL> from io import open as io_open <EOL> except ImportError : <EOL> from codecs import open as io_open <EOL> try : <EOL> from os . path import relpath as _relpath <EOL> except ImportError : <EOL> def _relpath ( path , start = os . path . curdir ) : <EOL> if not path : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> start_list = os . path . abspath ( start ) . split ( os . path . sep ) <EOL> path_list = os . path . abspath ( path ) . split ( os . path . sep ) <EOL> i = len ( os . path . commonprefix ( [ start_list , path_list ] ) ) <EOL> rel_list = [ os . path . pardir ] * ( len ( start_list ) - i ) + path_list [ i : ] <EOL> if not rel_list : <EOL> return os . path . curdir <EOL> return os . path . join ( * rel_list ) <EOL> from distutils . extension import Extension <EOL> from . . import Utils <EOL> from . . Utils import ( cached_function , cached_method , path_exists , <EOL> safe_makedirs , copy_file_to_dir_if_newer , is_package_dir ) <EOL> from . . Compiler . Main import Context , CompilationOptions , default_options <EOL> join_path = cached_function ( os . path . join ) <EOL> copy_once_if_newer = cached_function ( copy_file_to_dir_if_newer ) <EOL> safe_makedirs_once = cached_function ( safe_makedirs ) <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> _fs_encoding = sys . getfilesystemencoding ( ) <EOL> if _fs_encoding is None : <EOL> _fs_encoding = sys . getdefaultencoding ( ) <EOL> def encode_filename_in_py2 ( filename ) : <EOL> if not isinstance ( filename , bytes ) : <EOL> return filename . encode ( _fs_encoding ) <EOL> return filename <EOL> else : <EOL> def encode_filename_in_py2 ( filename ) : <EOL> return filename <EOL> basestring = str <EOL> def extended_iglob ( pattern ) : <EOL> if '<STR_LIT:{>' in pattern : <EOL> m = re . match ( '<STR_LIT>' , pattern ) <EOL> if m : <EOL> before , switch , after = m . groups ( ) <EOL> for case in switch . split ( '<STR_LIT:U+002C>' ) : <EOL> for path in extended_iglob ( before + case + after ) : <EOL> yield path <EOL> return <EOL> if '<STR_LIT>' in pattern : <EOL> seen = set ( ) <EOL> first , rest = pattern . split ( '<STR_LIT>' , <NUM_LIT:1> ) <EOL> if first : <EOL> first = iglob ( first + '<STR_LIT:/>' ) <EOL> else : <EOL> first = [ '<STR_LIT>' ] <EOL> for root in first : <EOL> for path in extended_iglob ( join_path ( root , rest ) ) : <EOL> if path not in seen : <EOL> seen . add ( path ) <EOL> yield path <EOL> for path in extended_iglob ( join_path ( root , '<STR_LIT:*>' , '<STR_LIT>' + rest ) ) : <EOL> if path not in seen : <EOL> seen . add ( path ) <EOL> yield path <EOL> else : <EOL> for path in iglob ( pattern ) : <EOL> yield path <EOL> def nonempty ( it , error_msg = "<STR_LIT>" ) : <EOL> empty = True <EOL> for value in it : <EOL> empty = False <EOL> yield value <EOL> if empty : <EOL> raise ValueError ( error_msg ) <EOL> @ cached_function <EOL> def file_hash ( filename ) : <EOL> path = os . path . normpath ( filename . encode ( "<STR_LIT>" ) ) <EOL> m = hashlib . md5 ( str ( len ( path ) ) + "<STR_LIT::>" ) <EOL> m . update ( path ) <EOL> f = open ( filename , '<STR_LIT:rb>' ) <EOL> try : <EOL> data = f . read ( <NUM_LIT> ) <EOL> while data : <EOL> m . update ( data ) <EOL> data = f . read ( <NUM_LIT> ) <EOL> finally : <EOL> f . close ( ) <EOL> return m . hexdigest ( ) <EOL> def parse_list ( s ) : <EOL> """<STR_LIT>""" <EOL> if len ( s ) >= <NUM_LIT:2> and s [ <NUM_LIT:0> ] == '<STR_LIT:[>' and s [ - <NUM_LIT:1> ] == '<STR_LIT:]>' : <EOL> s = s [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> delimiter = '<STR_LIT:U+002C>' <EOL> else : <EOL> delimiter = '<STR_LIT:U+0020>' <EOL> s , literals = strip_string_literals ( s ) <EOL> def unquote ( literal ) : <EOL> literal = literal . strip ( ) <EOL> if literal [ <NUM_LIT:0> ] in "<STR_LIT>" : <EOL> return literals [ literal [ <NUM_LIT:1> : - <NUM_LIT:1> ] ] <EOL> else : <EOL> return literal <EOL> return [ unquote ( item ) for item in s . split ( delimiter ) if item . strip ( ) ] <EOL> transitive_str = object ( ) <EOL> transitive_list = object ( ) <EOL> distutils_settings = { <EOL> '<STR_LIT:name>' : str , <EOL> '<STR_LIT>' : list , <EOL> '<STR_LIT>' : list , <EOL> '<STR_LIT>' : list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : list , <EOL> '<STR_LIT>' : transitive_list , <EOL> '<STR_LIT>' : transitive_str , <EOL> } <EOL> @ cython . locals ( start = cython . Py_ssize_t , end = cython . Py_ssize_t ) <EOL> def line_iter ( source ) : <EOL> if isinstance ( source , basestring ) : <EOL> start = <NUM_LIT:0> <EOL> while True : <EOL> end = source . find ( '<STR_LIT:\n>' , start ) <EOL> if end == - <NUM_LIT:1> : <EOL> yield source [ start : ] <EOL> return <EOL> yield source [ start : end ] <EOL> start = end + <NUM_LIT:1> <EOL> else : <EOL> for line in source : <EOL> yield line <EOL> class DistutilsInfo ( object ) : <EOL> def __init__ ( self , source = None , exn = None ) : <EOL> self . values = { } <EOL> if source is not None : <EOL> for line in line_iter ( source ) : <EOL> line = line . strip ( ) <EOL> if line != '<STR_LIT>' and line [ <NUM_LIT:0> ] != '<STR_LIT:#>' : <EOL> break <EOL> line = line [ <NUM_LIT:1> : ] . strip ( ) <EOL> if line [ : <NUM_LIT:10> ] == '<STR_LIT>' : <EOL> line = line [ <NUM_LIT:10> : ] <EOL> ix = line . index ( '<STR_LIT:=>' ) <EOL> key = str ( line [ : ix ] . strip ( ) ) <EOL> value = line [ ix + <NUM_LIT:1> : ] . strip ( ) <EOL> type = distutils_settings [ key ] <EOL> if type in ( list , transitive_list ) : <EOL> value = parse_list ( value ) <EOL> if key == '<STR_LIT>' : <EOL> value = [ tuple ( macro . split ( '<STR_LIT:=>' ) ) for macro in value ] <EOL> self . values [ key ] = value <EOL> elif exn is not None : <EOL> for key in distutils_settings : <EOL> if key in ( '<STR_LIT:name>' , '<STR_LIT>' ) : <EOL> continue <EOL> value = getattr ( exn , key , None ) <EOL> if value : <EOL> self . values [ key ] = value <EOL> def merge ( self , other ) : <EOL> if other is None : <EOL> return self <EOL> for key , value in other . values . items ( ) : <EOL> type = distutils_settings [ key ] <EOL> if type is transitive_str and key not in self . values : <EOL> self . values [ key ] = value <EOL> elif type is transitive_list : <EOL> if key in self . values : <EOL> all = self . values [ key ] [ : ] <EOL> for v in value : <EOL> if v not in all : <EOL> all . append ( v ) <EOL> value = all <EOL> self . values [ key ] = value <EOL> return self <EOL> def subs ( self , aliases ) : <EOL> if aliases is None : <EOL> return self <EOL> resolved = DistutilsInfo ( ) <EOL> for key , value in self . values . items ( ) : <EOL> type = distutils_settings [ key ] <EOL> if type in [ list , transitive_list ] : <EOL> new_value_list = [ ] <EOL> for v in value : <EOL> if v in aliases : <EOL> v = aliases [ v ] <EOL> if isinstance ( v , list ) : <EOL> new_value_list += v <EOL> else : <EOL> new_value_list . append ( v ) <EOL> value = new_value_list <EOL> else : <EOL> if value in aliases : <EOL> value = aliases [ value ] <EOL> resolved . values [ key ] = value <EOL> return resolved <EOL> def apply ( self , extension ) : <EOL> for key , value in self . values . items ( ) : <EOL> type = distutils_settings [ key ] <EOL> if type in [ list , transitive_list ] : <EOL> value = getattr ( extension , key ) + list ( value ) <EOL> setattr ( extension , key , value ) <EOL> @ cython . locals ( start = cython . Py_ssize_t , q = cython . Py_ssize_t , <EOL> single_q = cython . Py_ssize_t , double_q = cython . Py_ssize_t , <EOL> hash_mark = cython . Py_ssize_t , end = cython . Py_ssize_t , <EOL> k = cython . Py_ssize_t , counter = cython . Py_ssize_t , quote_len = cython . Py_ssize_t ) <EOL> def strip_string_literals ( code , prefix = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> new_code = [ ] <EOL> literals = { } <EOL> counter = <NUM_LIT:0> <EOL> start = q = <NUM_LIT:0> <EOL> in_quote = False <EOL> hash_mark = single_q = double_q = - <NUM_LIT:1> <EOL> code_len = len ( code ) <EOL> quote_type = quote_len = None <EOL> while True : <EOL> if hash_mark < q : <EOL> hash_mark = code . find ( '<STR_LIT:#>' , q ) <EOL> if single_q < q : <EOL> single_q = code . find ( "<STR_LIT:'>" , q ) <EOL> if double_q < q : <EOL> double_q = code . find ( '<STR_LIT:">' , q ) <EOL> q = min ( single_q , double_q ) <EOL> if q == - <NUM_LIT:1> : <EOL> q = max ( single_q , double_q ) <EOL> if q == - <NUM_LIT:1> and hash_mark == - <NUM_LIT:1> : <EOL> new_code . append ( code [ start : ] ) <EOL> break <EOL> elif in_quote : <EOL> if code [ q - <NUM_LIT:1> ] == u'<STR_LIT:\\>' : <EOL> k = <NUM_LIT:2> <EOL> while q >= k and code [ q - k ] == u'<STR_LIT:\\>' : <EOL> k += <NUM_LIT:1> <EOL> if k % <NUM_LIT:2> == <NUM_LIT:0> : <EOL> q += <NUM_LIT:1> <EOL> continue <EOL> if code [ q ] == quote_type and ( <EOL> quote_len == <NUM_LIT:1> or ( code_len > q + <NUM_LIT:2> and quote_type == code [ q + <NUM_LIT:1> ] == code [ q + <NUM_LIT:2> ] ) ) : <EOL> counter += <NUM_LIT:1> <EOL> label = "<STR_LIT>" % ( prefix , counter ) <EOL> literals [ label ] = code [ start + quote_len : q ] <EOL> full_quote = code [ q : q + quote_len ] <EOL> new_code . append ( full_quote ) <EOL> new_code . append ( label ) <EOL> new_code . append ( full_quote ) <EOL> q += quote_len <EOL> in_quote = False <EOL> start = q <EOL> else : <EOL> q += <NUM_LIT:1> <EOL> elif - <NUM_LIT:1> != hash_mark and ( hash_mark < q or q == - <NUM_LIT:1> ) : <EOL> new_code . append ( code [ start : hash_mark + <NUM_LIT:1> ] ) <EOL> end = code . find ( '<STR_LIT:\n>' , hash_mark ) <EOL> counter += <NUM_LIT:1> <EOL> label = "<STR_LIT>" % ( prefix , counter ) <EOL> if end == - <NUM_LIT:1> : <EOL> end_or_none = None <EOL> else : <EOL> end_or_none = end <EOL> literals [ label ] = code [ hash_mark + <NUM_LIT:1> : end_or_none ] <EOL> new_code . append ( label ) <EOL> if end == - <NUM_LIT:1> : <EOL> break <EOL> start = q = end <EOL> else : <EOL> if code_len >= q + <NUM_LIT:3> and ( code [ q ] == code [ q + <NUM_LIT:1> ] == code [ q + <NUM_LIT:2> ] ) : <EOL> quote_len = <NUM_LIT:3> <EOL> else : <EOL> quote_len = <NUM_LIT:1> <EOL> in_quote = True <EOL> quote_type = code [ q ] <EOL> new_code . append ( code [ start : q ] ) <EOL> start = q <EOL> q += quote_len <EOL> return "<STR_LIT>" . join ( new_code ) , literals <EOL> dependency_regex = re . compile ( r"<STR_LIT>" <EOL> r"<STR_LIT>" <EOL> r"<STR_LIT>" <EOL> r"<STR_LIT>" , re . M ) <EOL> def normalize_existing ( base_path , rel_paths ) : <EOL> return normalize_existing0 ( os . path . dirname ( base_path ) , tuple ( set ( rel_paths ) ) ) <EOL> @ cached_function <EOL> def normalize_existing0 ( base_dir , rel_paths ) : <EOL> normalized = [ ] <EOL> for rel in rel_paths : <EOL> path = join_path ( base_dir , rel ) <EOL> if path_exists ( path ) : <EOL> normalized . append ( os . path . normpath ( path ) ) <EOL> else : <EOL> normalized . append ( rel ) <EOL> return normalized <EOL> def resolve_depends ( depends , include_dirs ) : <EOL> include_dirs = tuple ( include_dirs ) <EOL> resolved = [ ] <EOL> for depend in depends : <EOL> path = resolve_depend ( depend , include_dirs ) <EOL> if path is not None : <EOL> resolved . append ( path ) <EOL> return resolved <EOL> @ cached_function <EOL> def resolve_depend ( depend , include_dirs ) : <EOL> if depend [ <NUM_LIT:0> ] == '<STR_LIT:<>' and depend [ - <NUM_LIT:1> ] == '<STR_LIT:>>' : <EOL> return None <EOL> for dir in include_dirs : <EOL> path = join_path ( dir , depend ) <EOL> if path_exists ( path ) : <EOL> return os . path . normpath ( path ) <EOL> return None <EOL> @ cached_function <EOL> def package ( filename ) : <EOL> dir = os . path . dirname ( os . path . abspath ( str ( filename ) ) ) <EOL> if dir != filename and is_package_dir ( dir ) : <EOL> return package ( dir ) + ( os . path . basename ( dir ) , ) <EOL> else : <EOL> return ( ) <EOL> @ cached_function <EOL> def fully_qualified_name ( filename ) : <EOL> module = os . path . splitext ( os . path . basename ( filename ) ) [ <NUM_LIT:0> ] <EOL> return '<STR_LIT:.>' . join ( package ( filename ) + ( module , ) ) <EOL> @ cached_function <EOL> def parse_dependencies ( source_filename ) : <EOL> fh = Utils . open_source_file ( source_filename , error_handling = '<STR_LIT:ignore>' ) <EOL> try : <EOL> source = fh . read ( ) <EOL> finally : <EOL> fh . close ( ) <EOL> distutils_info = DistutilsInfo ( source ) <EOL> source , literals = strip_string_literals ( source ) <EOL> source = source . replace ( '<STR_LIT>' , '<STR_LIT:U+0020>' ) . replace ( '<STR_LIT:\t>' , '<STR_LIT:U+0020>' ) <EOL> cimports = [ ] <EOL> includes = [ ] <EOL> externs = [ ] <EOL> for m in dependency_regex . finditer ( source ) : <EOL> cimport_from , cimport_list , extern , include = m . groups ( ) <EOL> if cimport_from : <EOL> cimports . append ( cimport_from ) <EOL> elif cimport_list : <EOL> cimports . extend ( x . strip ( ) for x in cimport_list . split ( "<STR_LIT:U+002C>" ) ) <EOL> elif extern : <EOL> externs . append ( literals [ extern ] ) <EOL> else : <EOL> includes . append ( literals [ include ] ) <EOL> return cimports , includes , externs , distutils_info <EOL> class DependencyTree ( object ) : <EOL> def __init__ ( self , context , quiet = False ) : <EOL> self . context = context <EOL> self . quiet = quiet <EOL> self . _transitive_cache = { } <EOL> def parse_dependencies ( self , source_filename ) : <EOL> if path_exists ( source_filename ) : <EOL> source_filename = os . path . normpath ( source_filename ) <EOL> return parse_dependencies ( source_filename ) <EOL> @ cached_method <EOL> def included_files ( self , filename ) : <EOL> all = set ( ) <EOL> for include in self . parse_dependencies ( filename ) [ <NUM_LIT:1> ] : <EOL> include_path = join_path ( os . path . dirname ( filename ) , include ) <EOL> if not path_exists ( include_path ) : <EOL> include_path = self . context . find_include_file ( include , None ) <EOL> if include_path : <EOL> if '<STR_LIT:.>' + os . path . sep in include_path : <EOL> include_path = os . path . normpath ( include_path ) <EOL> all . add ( include_path ) <EOL> all . update ( self . included_files ( include_path ) ) <EOL> elif not self . quiet : <EOL> print ( "<STR_LIT>" % ( filename , include ) ) <EOL> return all <EOL> @ cached_method <EOL> def cimports_and_externs ( self , filename ) : <EOL> cimports , includes , externs = self . parse_dependencies ( filename ) [ : <NUM_LIT:3> ] <EOL> cimports = set ( cimports ) <EOL> externs = set ( externs ) <EOL> for include in self . included_files ( filename ) : <EOL> included_cimports , included_externs = self . cimports_and_externs ( include ) <EOL> cimports . update ( included_cimports ) <EOL> externs . update ( included_externs ) <EOL> return tuple ( cimports ) , normalize_existing ( filename , externs ) <EOL> def cimports ( self , filename ) : <EOL> return self . cimports_and_externs ( filename ) [ <NUM_LIT:0> ] <EOL> def package ( self , filename ) : <EOL> return package ( filename ) <EOL> def fully_qualified_name ( self , filename ) : <EOL> return fully_qualified_name ( filename ) <EOL> @ cached_method <EOL> def find_pxd ( self , module , filename = None ) : <EOL> is_relative = module [ <NUM_LIT:0> ] == '<STR_LIT:.>' <EOL> if is_relative and not filename : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> if filename is not None : <EOL> module_path = module . split ( '<STR_LIT:.>' ) <EOL> if is_relative : <EOL> module_path . pop ( <NUM_LIT:0> ) <EOL> package_path = list ( self . package ( filename ) ) <EOL> while module_path and not module_path [ <NUM_LIT:0> ] : <EOL> try : <EOL> package_path . pop ( ) <EOL> except IndexError : <EOL> return None <EOL> module_path . pop ( <NUM_LIT:0> ) <EOL> relative = '<STR_LIT:.>' . join ( package_path + module_path ) <EOL> pxd = self . context . find_pxd_file ( relative , None ) <EOL> if pxd : <EOL> return pxd <EOL> if is_relative : <EOL> return None <EOL> return self . context . find_pxd_file ( module , None ) <EOL> @ cached_method <EOL> def cimported_files ( self , filename ) : <EOL> if filename [ - <NUM_LIT:4> : ] == '<STR_LIT>' and path_exists ( filename [ : - <NUM_LIT:4> ] + '<STR_LIT>' ) : <EOL> pxd_list = [ filename [ : - <NUM_LIT:4> ] + '<STR_LIT>' ] <EOL> else : <EOL> pxd_list = [ ] <EOL> for module in self . cimports ( filename ) : <EOL> if module [ : <NUM_LIT:7> ] == '<STR_LIT>' or module == '<STR_LIT>' : <EOL> continue <EOL> pxd_file = self . find_pxd ( module , filename ) <EOL> if pxd_file is not None : <EOL> pxd_list . append ( pxd_file ) <EOL> elif not self . quiet : <EOL> print ( "<STR_LIT>" % ( module , filename ) ) <EOL> return tuple ( pxd_list ) <EOL> @ cached_method <EOL> def immediate_dependencies ( self , filename ) : <EOL> all = set ( [ filename ] ) <EOL> all . update ( self . cimported_files ( filename ) ) <EOL> all . update ( self . included_files ( filename ) ) <EOL> return all <EOL> def all_dependencies ( self , filename ) : <EOL> return self . transitive_merge ( filename , self . immediate_dependencies , set . union ) <EOL> @ cached_method <EOL> def timestamp ( self , filename ) : <EOL> return os . path . getmtime ( filename ) <EOL> def extract_timestamp ( self , filename ) : <EOL> return self . timestamp ( filename ) , filename <EOL> def newest_dependency ( self , filename ) : <EOL> return max ( [ self . extract_timestamp ( f ) for f in self . all_dependencies ( filename ) ] ) <EOL> def transitive_fingerprint ( self , filename , extra = None ) : <EOL> try : <EOL> m = hashlib . md5 ( __version__ ) <EOL> m . update ( file_hash ( filename ) ) <EOL> for x in sorted ( self . all_dependencies ( filename ) ) : <EOL> if os . path . splitext ( x ) [ <NUM_LIT:1> ] not in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> m . update ( file_hash ( x ) ) <EOL> if extra is not None : <EOL> m . update ( str ( extra ) ) <EOL> return m . hexdigest ( ) <EOL> except IOError : <EOL> return None <EOL> def distutils_info0 ( self , filename ) : <EOL> info = self . parse_dependencies ( filename ) [ <NUM_LIT:3> ] <EOL> externs = self . cimports_and_externs ( filename ) [ <NUM_LIT:1> ] <EOL> if externs : <EOL> if '<STR_LIT>' in info . values : <EOL> info . values [ '<STR_LIT>' ] = list ( set ( info . values [ '<STR_LIT>' ] ) . union ( externs ) ) <EOL> else : <EOL> info . values [ '<STR_LIT>' ] = list ( externs ) <EOL> return info <EOL> def distutils_info ( self , filename , aliases = None , base = None ) : <EOL> return ( self . transitive_merge ( filename , self . distutils_info0 , DistutilsInfo . merge ) <EOL> . subs ( aliases ) <EOL> . merge ( base ) ) <EOL> def transitive_merge ( self , node , extract , merge ) : <EOL> try : <EOL> seen = self . _transitive_cache [ extract , merge ] <EOL> except KeyError : <EOL> seen = self . _transitive_cache [ extract , merge ] = { } <EOL> return self . transitive_merge_helper ( <EOL> node , extract , merge , seen , { } , self . cimported_files ) [ <NUM_LIT:0> ] <EOL> def transitive_merge_helper ( self , node , extract , merge , seen , stack , outgoing ) : <EOL> if node in seen : <EOL> return seen [ node ] , None <EOL> deps = extract ( node ) <EOL> if node in stack : <EOL> return deps , node <EOL> try : <EOL> stack [ node ] = len ( stack ) <EOL> loop = None <EOL> for next in outgoing ( node ) : <EOL> sub_deps , sub_loop = self . transitive_merge_helper ( next , extract , merge , seen , stack , outgoing ) <EOL> if sub_loop is not None : <EOL> if loop is not None and stack [ loop ] < stack [ sub_loop ] : <EOL> pass <EOL> else : <EOL> loop = sub_loop <EOL> deps = merge ( deps , sub_deps ) <EOL> if loop == node : <EOL> loop = None <EOL> if loop is None : <EOL> seen [ node ] = deps <EOL> return deps , loop <EOL> finally : <EOL> del stack [ node ] <EOL> _dep_tree = None <EOL> def create_dependency_tree ( ctx = None , quiet = False ) : <EOL> global _dep_tree <EOL> if _dep_tree is None : <EOL> if ctx is None : <EOL> ctx = Context ( [ "<STR_LIT:.>" ] , CompilationOptions ( default_options ) ) <EOL> _dep_tree = DependencyTree ( ctx , quiet = quiet ) <EOL> return _dep_tree <EOL> def create_extension_list ( patterns , exclude = None , ctx = None , aliases = None , quiet = False , language = None , <EOL> exclude_failures = False ) : <EOL> if language is not None : <EOL> print ( '<STR_LIT>' % language ) <EOL> if exclude is None : <EOL> exclude = [ ] <EOL> if not isinstance ( patterns , ( list , tuple ) ) : <EOL> patterns = [ patterns ] <EOL> explicit_modules = set ( [ m . name for m in patterns if isinstance ( m , Extension ) ] ) <EOL> seen = set ( ) <EOL> deps = create_dependency_tree ( ctx , quiet = quiet ) <EOL> to_exclude = set ( ) <EOL> if not isinstance ( exclude , list ) : <EOL> exclude = [ exclude ] <EOL> for pattern in exclude : <EOL> to_exclude . update ( map ( os . path . abspath , extended_iglob ( pattern ) ) ) <EOL> module_list = [ ] <EOL> module_metadata = { } <EOL> if '<STR_LIT>' in sys . modules : <EOL> Extension_distutils = sys . modules [ '<STR_LIT>' ] . _Extension <EOL> Extension_setuptools = sys . modules [ '<STR_LIT>' ] . Extension <EOL> else : <EOL> Extension_distutils = Extension <EOL> class Extension_setuptools ( Extension ) : pass <EOL> for pattern in patterns : <EOL> if isinstance ( pattern , str ) : <EOL> filepattern = pattern <EOL> template = None <EOL> name = '<STR_LIT:*>' <EOL> base = None <EOL> exn_type = Extension <EOL> ext_language = language <EOL> elif isinstance ( pattern , ( Extension_distutils , Extension_setuptools ) ) : <EOL> for filepattern in pattern . sources : <EOL> if os . path . splitext ( filepattern ) [ <NUM_LIT:1> ] in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> break <EOL> else : <EOL> module_list . append ( pattern ) <EOL> continue <EOL> template = pattern <EOL> name = template . name <EOL> base = DistutilsInfo ( exn = template ) <EOL> exn_type = template . __class__ <EOL> ext_language = None <EOL> else : <EOL> msg = str ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( repr ( Extension ) , <EOL> type ( pattern ) , <EOL> pattern . __class__ ) ) <EOL> raise TypeError ( msg ) <EOL> for file in nonempty ( sorted ( extended_iglob ( filepattern ) ) , "<STR_LIT>" % filepattern ) : <EOL> if os . path . abspath ( file ) in to_exclude : <EOL> continue <EOL> pkg = deps . package ( file ) <EOL> if '<STR_LIT:*>' in name : <EOL> module_name = deps . fully_qualified_name ( file ) <EOL> if module_name in explicit_modules : <EOL> continue <EOL> else : <EOL> module_name = name <EOL> if module_name not in seen : <EOL> try : <EOL> kwds = deps . distutils_info ( file , aliases , base ) . values <EOL> except Exception : <EOL> if exclude_failures : <EOL> continue <EOL> raise <EOL> if base is not None : <EOL> for key , value in base . values . items ( ) : <EOL> if key not in kwds : <EOL> kwds [ key ] = value <EOL> sources = [ file ] <EOL> if template is not None : <EOL> sources += [ m for m in template . sources if m != filepattern ] <EOL> if '<STR_LIT>' in kwds : <EOL> for source in kwds [ '<STR_LIT>' ] : <EOL> source = encode_filename_in_py2 ( source ) <EOL> if source not in sources : <EOL> sources . append ( source ) <EOL> extra_sources = kwds [ '<STR_LIT>' ] <EOL> del kwds [ '<STR_LIT>' ] <EOL> else : <EOL> extra_sources = None <EOL> if '<STR_LIT>' in kwds : <EOL> depends = resolve_depends ( kwds [ '<STR_LIT>' ] , ( kwds . get ( '<STR_LIT>' ) or [ ] ) + [ "<STR_LIT:.>" ] ) <EOL> if template is not None : <EOL> depends = set ( template . depends ) . union ( depends ) <EOL> kwds [ '<STR_LIT>' ] = sorted ( depends ) <EOL> if ext_language and '<STR_LIT>' not in kwds : <EOL> kwds [ '<STR_LIT>' ] = ext_language <EOL> module_list . append ( exn_type ( <EOL> name = module_name , <EOL> sources = sources , <EOL> ** kwds ) ) <EOL> if extra_sources : <EOL> kwds [ '<STR_LIT>' ] = extra_sources <EOL> module_metadata [ module_name ] = { '<STR_LIT>' : kwds , '<STR_LIT>' : module_name } <EOL> m = module_list [ - <NUM_LIT:1> ] <EOL> seen . add ( name ) <EOL> return module_list , module_metadata <EOL> def cythonize ( module_list , exclude = None , nthreads = <NUM_LIT:0> , aliases = None , quiet = False , force = False , language = None , <EOL> exclude_failures = False , ** options ) : <EOL> """<STR_LIT>""" <EOL> if exclude is None : <EOL> exclude = [ ] <EOL> if '<STR_LIT>' not in options : <EOL> options [ '<STR_LIT>' ] = [ '<STR_LIT:.>' ] <EOL> if '<STR_LIT>' in options : <EOL> if options . get ( '<STR_LIT>' ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> safe_makedirs ( options [ '<STR_LIT>' ] ) <EOL> c_options = CompilationOptions ( ** options ) <EOL> cpp_options = CompilationOptions ( ** options ) ; cpp_options . cplus = True <EOL> ctx = c_options . create_context ( ) <EOL> options = c_options <EOL> module_list , module_metadata = create_extension_list ( <EOL> module_list , <EOL> exclude = exclude , <EOL> ctx = ctx , <EOL> quiet = quiet , <EOL> exclude_failures = exclude_failures , <EOL> language = language , <EOL> aliases = aliases ) <EOL> deps = create_dependency_tree ( ctx , quiet = quiet ) <EOL> build_dir = getattr ( options , '<STR_LIT>' , None ) <EOL> modules_by_cfile = { } <EOL> to_compile = [ ] <EOL> for m in module_list : <EOL> if build_dir : <EOL> root = os . getcwd ( ) <EOL> def copy_to_build_dir ( filepath , root = root ) : <EOL> filepath_abs = os . path . abspath ( filepath ) <EOL> if os . path . isabs ( filepath ) : <EOL> filepath = filepath_abs <EOL> if filepath_abs . startswith ( root ) : <EOL> mod_dir = join_path ( build_dir , <EOL> os . path . dirname ( _relpath ( filepath , root ) ) ) <EOL> copy_once_if_newer ( filepath_abs , mod_dir ) <EOL> for dep in m . depends : <EOL> copy_to_build_dir ( dep ) <EOL> new_sources = [ ] <EOL> for source in m . sources : <EOL> base , ext = os . path . splitext ( source ) <EOL> if ext in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if m . language == '<STR_LIT>' : <EOL> c_file = base + '<STR_LIT>' <EOL> options = cpp_options <EOL> else : <EOL> c_file = base + '<STR_LIT>' <EOL> options = c_options <EOL> if build_dir : <EOL> c_file = os . path . join ( build_dir , c_file ) <EOL> dir = os . path . dirname ( c_file ) <EOL> safe_makedirs_once ( dir ) <EOL> if os . path . exists ( c_file ) : <EOL> c_timestamp = os . path . getmtime ( c_file ) <EOL> else : <EOL> c_timestamp = - <NUM_LIT:1> <EOL> if c_timestamp < deps . timestamp ( source ) : <EOL> dep_timestamp , dep = deps . timestamp ( source ) , source <EOL> priority = <NUM_LIT:0> <EOL> else : <EOL> dep_timestamp , dep = deps . newest_dependency ( source ) <EOL> priority = <NUM_LIT:2> - ( dep in deps . immediate_dependencies ( source ) ) <EOL> if force or c_timestamp < dep_timestamp : <EOL> if not quiet : <EOL> if source == dep : <EOL> print ( "<STR_LIT>" % source ) <EOL> else : <EOL> print ( "<STR_LIT>" % ( source , dep ) ) <EOL> if not force and hasattr ( options , '<STR_LIT>' ) : <EOL> extra = m . language <EOL> fingerprint = deps . transitive_fingerprint ( source , extra ) <EOL> else : <EOL> fingerprint = None <EOL> to_compile . append ( ( priority , source , c_file , fingerprint , quiet , <EOL> options , not exclude_failures , module_metadata . get ( m . name ) ) ) <EOL> new_sources . append ( c_file ) <EOL> if c_file not in modules_by_cfile : <EOL> modules_by_cfile [ c_file ] = [ m ] <EOL> else : <EOL> modules_by_cfile [ c_file ] . append ( m ) <EOL> else : <EOL> new_sources . append ( source ) <EOL> if build_dir : <EOL> copy_to_build_dir ( source ) <EOL> m . sources = new_sources <EOL> if hasattr ( options , '<STR_LIT>' ) : <EOL> if not os . path . exists ( options . cache ) : <EOL> os . makedirs ( options . cache ) <EOL> to_compile . sort ( ) <EOL> N = len ( to_compile ) <EOL> progress_fmt = "<STR_LIT>" % len ( str ( N ) ) <EOL> for i in range ( N ) : <EOL> progress = progress_fmt . format ( i + <NUM_LIT:1> , N ) <EOL> to_compile [ i ] = to_compile [ i ] [ <NUM_LIT:1> : ] + ( progress , ) <EOL> if N <= <NUM_LIT:1> : <EOL> nthreads = <NUM_LIT:0> <EOL> if nthreads : <EOL> try : <EOL> import multiprocessing <EOL> pool = multiprocessing . Pool ( <EOL> nthreads , initializer = _init_multiprocessing_helper ) <EOL> except ( ImportError , OSError ) : <EOL> print ( "<STR_LIT>" ) <EOL> nthreads = <NUM_LIT:0> <EOL> else : <EOL> try : <EOL> result = pool . map_async ( cythonize_one_helper , to_compile , chunksize = <NUM_LIT:1> ) <EOL> pool . close ( ) <EOL> while not result . ready ( ) : <EOL> try : <EOL> result . get ( <NUM_LIT> ) <EOL> except multiprocessing . TimeoutError : <EOL> pass <EOL> except KeyboardInterrupt : <EOL> pool . terminate ( ) <EOL> raise <EOL> pool . join ( ) <EOL> if not nthreads : <EOL> for args in to_compile : <EOL> cythonize_one ( * args ) <EOL> if exclude_failures : <EOL> failed_modules = set ( ) <EOL> for c_file , modules in modules_by_cfile . items ( ) : <EOL> if not os . path . exists ( c_file ) : <EOL> failed_modules . update ( modules ) <EOL> elif os . path . getsize ( c_file ) < <NUM_LIT:200> : <EOL> f = io_open ( c_file , '<STR_LIT:r>' , encoding = '<STR_LIT>' ) <EOL> try : <EOL> if f . read ( len ( '<STR_LIT>' ) ) == '<STR_LIT>' : <EOL> failed_modules . update ( modules ) <EOL> finally : <EOL> f . close ( ) <EOL> if failed_modules : <EOL> for module in failed_modules : <EOL> module_list . remove ( module ) <EOL> print ( "<STR_LIT>" % '<STR_LIT:U+002CU+0020>' . join ( sorted ( [ <EOL> module . name for module in failed_modules ] ) ) ) <EOL> if hasattr ( options , '<STR_LIT>' ) : <EOL> cleanup_cache ( options . cache , getattr ( options , '<STR_LIT>' , <NUM_LIT> * <NUM_LIT> * <NUM_LIT:100> ) ) <EOL> sys . stdout . flush ( ) <EOL> return module_list <EOL> if os . environ . get ( '<STR_LIT>' ) : <EOL> compile_result_dir = os . environ [ '<STR_LIT>' ] <EOL> def record_results ( func ) : <EOL> def with_record ( * args ) : <EOL> t = time . time ( ) <EOL> success = True <EOL> try : <EOL> try : <EOL> func ( * args ) <EOL> except : <EOL> success = False <EOL> finally : <EOL> t = time . time ( ) - t <EOL> module = fully_qualified_name ( args [ <NUM_LIT:0> ] ) <EOL> name = "<STR_LIT>" + module <EOL> failures = <NUM_LIT:1> - success <EOL> if success : <EOL> failure_item = "<STR_LIT>" <EOL> else : <EOL> failure_item = "<STR_LIT>" <EOL> output = open ( os . path . join ( compile_result_dir , name + "<STR_LIT>" ) , "<STR_LIT:w>" ) <EOL> output . write ( """<STR_LIT>""" . strip ( ) % locals ( ) ) <EOL> output . close ( ) <EOL> return with_record <EOL> else : <EOL> def record_results ( func ) : <EOL> return func <EOL> @ record_results <EOL> def cythonize_one ( pyx_file , c_file , fingerprint , quiet , options = None , raise_on_failure = True , embedded_metadata = None , progress = "<STR_LIT>" ) : <EOL> from . . Compiler . Main import compile , default_options <EOL> from . . Compiler . Errors import CompileError , PyrexError <EOL> if fingerprint : <EOL> if not os . path . exists ( options . cache ) : <EOL> try : <EOL> os . mkdir ( options . cache ) <EOL> except : <EOL> if not os . path . exists ( options . cache ) : <EOL> raise <EOL> fingerprint_file = join_path ( <EOL> options . cache , "<STR_LIT>" % ( os . path . basename ( c_file ) , fingerprint , gzip_ext ) ) <EOL> if os . path . exists ( fingerprint_file ) : <EOL> if not quiet : <EOL> print ( "<STR_LIT>" % ( progress , pyx_file ) ) <EOL> os . utime ( fingerprint_file , None ) <EOL> g = gzip_open ( fingerprint_file , '<STR_LIT:rb>' ) <EOL> try : <EOL> f = open ( c_file , '<STR_LIT:wb>' ) <EOL> try : <EOL> shutil . copyfileobj ( g , f ) <EOL> finally : <EOL> f . close ( ) <EOL> finally : <EOL> g . close ( ) <EOL> return <EOL> if not quiet : <EOL> print ( "<STR_LIT>" % ( progress , pyx_file ) ) <EOL> if options is None : <EOL> options = CompilationOptions ( default_options ) <EOL> options . output_file = c_file <EOL> options . embedded_metadata = embedded_metadata <EOL> any_failures = <NUM_LIT:0> <EOL> try : <EOL> result = compile ( [ pyx_file ] , options ) <EOL> if result . num_errors > <NUM_LIT:0> : <EOL> any_failures = <NUM_LIT:1> <EOL> except ( EnvironmentError , PyrexError ) as e : <EOL> sys . stderr . write ( '<STR_LIT>' % e ) <EOL> any_failures = <NUM_LIT:1> <EOL> import traceback <EOL> traceback . print_exc ( ) <EOL> except Exception : <EOL> if raise_on_failure : <EOL> raise <EOL> import traceback <EOL> traceback . print_exc ( ) <EOL> any_failures = <NUM_LIT:1> <EOL> if any_failures : <EOL> if raise_on_failure : <EOL> raise CompileError ( None , pyx_file ) <EOL> elif os . path . exists ( c_file ) : <EOL> os . remove ( c_file ) <EOL> elif fingerprint : <EOL> f = open ( c_file , '<STR_LIT:rb>' ) <EOL> try : <EOL> g = gzip_open ( fingerprint_file , '<STR_LIT:wb>' ) <EOL> try : <EOL> shutil . copyfileobj ( f , g ) <EOL> finally : <EOL> g . close ( ) <EOL> finally : <EOL> f . close ( ) <EOL> def cythonize_one_helper ( m ) : <EOL> import traceback <EOL> try : <EOL> return cythonize_one ( * m ) <EOL> except Exception : <EOL> traceback . print_exc ( ) <EOL> raise <EOL> def _init_multiprocessing_helper ( ) : <EOL> import signal <EOL> signal . signal ( signal . SIGINT , signal . SIG_IGN ) <EOL> def cleanup_cache ( cache , target_size , ratio = <NUM_LIT> ) : <EOL> try : <EOL> p = subprocess . Popen ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , os . path . abspath ( cache ) ] , stdout = subprocess . PIPE ) <EOL> res = p . wait ( ) <EOL> if res == <NUM_LIT:0> : <EOL> total_size = <NUM_LIT> * int ( p . stdout . read ( ) . strip ( ) . split ( ) [ <NUM_LIT:0> ] ) <EOL> if total_size < target_size : <EOL> return <EOL> except ( OSError , ValueError ) : <EOL> pass <EOL> total_size = <NUM_LIT:0> <EOL> all = [ ] <EOL> for file in os . listdir ( cache ) : <EOL> path = join_path ( cache , file ) <EOL> s = os . stat ( path ) <EOL> total_size += s . st_size <EOL> all . append ( ( s . st_atime , s . st_size , path ) ) <EOL> if total_size > target_size : <EOL> for time , size , file in reversed ( sorted ( all ) ) : <EOL> os . unlink ( file ) <EOL> total_size -= size <EOL> if total_size < target_size * ratio : <EOL> break </s>
