Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
__main__.py277 linesDownload Raw Back to sysconfig
1import json2import os3import sys4import types5from sysconfig import (6    _ALWAYS_STR,7    _PYTHON_BUILD,8    _get_sysconfigdata_name,9    get_config_h_filename,10    get_config_var,11    get_config_vars,12    get_default_scheme,13    get_makefile_filename,14    get_paths,15    get_platform,16    get_python_version,17    parse_config_h,18)19 20 21# Regexes needed for parsing Makefile (and similar syntaxes,22# like old-style Setup files).23_variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)"24_findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)"25_findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}"26 27 28def _parse_makefile(filename, vars=None, keep_unresolved=True):29    """Parse a Makefile-style file.30 31    A dictionary containing name/value pairs is returned.  If an32    optional dictionary is passed in as the second argument, it is33    used instead of a new dictionary.34    """35    import re36 37    if vars is None:38        vars = {}39    done = {}40    notdone = {}41 42    with open(filename, encoding=sys.getfilesystemencoding(),43              errors="surrogateescape") as f:44        lines = f.readlines()45 46    for line in lines:47        if line.startswith('#') or line.strip() == '':48            continue49        m = re.match(_variable_rx, line)50        if m:51            n, v = m.group(1, 2)52            v = v.strip()53            # `$$' is a literal `$' in make54            tmpv = v.replace('$$', '')55 56            if "$" in tmpv:57                notdone[n] = v58            else:59                try:60                    if n in _ALWAYS_STR:61                        raise ValueError62 63                    v = int(v)64                except ValueError:65                    # insert literal `$'66                    done[n] = v.replace('$$', '$')67                else:68                    done[n] = v69 70    # do variable interpolation here71    variables = list(notdone.keys())72 73    # Variables with a 'PY_' prefix in the makefile. These need to74    # be made available without that prefix through sysconfig.75    # Special care is needed to ensure that variable expansion works, even76    # if the expansion uses the name without a prefix.77    renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')78 79    while len(variables) > 0:80        for name in tuple(variables):81            value = notdone[name]82            m1 = re.search(_findvar1_rx, value)83            m2 = re.search(_findvar2_rx, value)84            if m1 and m2:85                m = m1 if m1.start() < m2.start() else m286            else:87                m = m1 if m1 else m288            if m is not None:89                n = m.group(1)90                found = True91                if n in done:92                    item = str(done[n])93                elif n in notdone:94                    # get it on a subsequent round95                    found = False96                elif n in os.environ:97                    # do it like make: fall back to environment98                    item = os.environ[n]99 100                elif n in renamed_variables:101                    if (name.startswith('PY_') and102                        name[3:] in renamed_variables):103                        item = ""104 105                    elif 'PY_' + n in notdone:106                        found = False107 108                    else:109                        item = str(done['PY_' + n])110 111                else:112                    done[n] = item = ""113 114                if found:115                    after = value[m.end():]116                    value = value[:m.start()] + item + after117                    if "$" in after:118                        notdone[name] = value119                    else:120                        try:121                            if name in _ALWAYS_STR:122                                raise ValueError123                            value = int(value)124                        except ValueError:125                            done[name] = value.strip()126                        else:127                            done[name] = value128                        variables.remove(name)129 130                        if name.startswith('PY_') \131                        and name[3:] in renamed_variables:132 133                            name = name[3:]134                            if name not in done:135                                done[name] = value136 137            else:138                # Adds unresolved variables to the done dict.139                # This is disabled when called from distutils.sysconfig140                if keep_unresolved:141                    done[name] = value142                # bogus variable reference (e.g. "prefix=$/opt/python");143                # just drop it since we can't deal144                variables.remove(name)145 146    # strip spurious spaces147    for k, v in done.items():148        if isinstance(v, str):149            done[k] = v.strip()150 151    # save the results in the global dictionary152    vars.update(done)153    return vars154 155 156def _print_config_dict(d, stream):157    print ("{", file=stream)158    for k, v in sorted(d.items()):159        print(f"    {k!r}: {v!r},", file=stream)160    print ("}", file=stream)161 162 163def _get_pybuilddir():164    pybuilddir = f'build/lib.{get_platform()}-{get_python_version()}'165    if get_config_var('Py_DEBUG') == '1':166        pybuilddir += '-pydebug'167    return pybuilddir168 169 170def _get_json_data_name():171    name = _get_sysconfigdata_name()172    assert name.startswith('_sysconfigdata')173    return name.replace('_sysconfigdata', '_sysconfig_vars') + '.json'174 175 176def _generate_posix_vars():177    """Generate the Python module containing build-time variables."""178    vars = {}179    # load the installed Makefile:180    makefile = get_makefile_filename()181    try:182        _parse_makefile(makefile, vars)183    except OSError as e:184        msg = f"invalid Python installation: unable to open {makefile}"185        if hasattr(e, "strerror"):186            msg = f"{msg} ({e.strerror})"187        raise OSError(msg)188    # load the installed pyconfig.h:189    config_h = get_config_h_filename()190    try:191        with open(config_h, encoding="utf-8") as f:192            parse_config_h(f, vars)193    except OSError as e:194        msg = f"invalid Python installation: unable to open {config_h}"195        if hasattr(e, "strerror"):196            msg = f"{msg} ({e.strerror})"197        raise OSError(msg)198    # On AIX, there are wrong paths to the linker scripts in the Makefile199    # -- these paths are relative to the Python source, but when installed200    # the scripts are in another directory.201    if _PYTHON_BUILD:202        vars['BLDSHARED'] = vars['LDSHARED']203 204    name = _get_sysconfigdata_name()205 206    # There's a chicken-and-egg situation on OS X with regards to the207    # _sysconfigdata module after the changes introduced by #15298:208    # get_config_vars() is called by get_platform() as part of the209    # `make pybuilddir.txt` target -- which is a precursor to the210    # _sysconfigdata.py module being constructed.  Unfortunately,211    # get_config_vars() eventually calls _init_posix(), which attempts212    # to import _sysconfigdata, which we won't have built yet.  In order213    # for _init_posix() to work, if we're on Darwin, just mock up the214    # _sysconfigdata module manually and populate it with the build vars.215    # This is more than sufficient for ensuring the subsequent call to216    # get_platform() succeeds.217    # GH-127178: Since we started generating a .json file, we also need this to218    #            be able to run sysconfig.get_config_vars().219    module = types.ModuleType(name)220    module.build_time_vars = vars221    sys.modules[name] = module222 223    pybuilddir = _get_pybuilddir()224    os.makedirs(pybuilddir, exist_ok=True)225    destfile = os.path.join(pybuilddir, name + '.py')226 227    with open(destfile, 'w', encoding='utf8') as f:228        f.write('# system configuration generated and used by'229                ' the sysconfig module\n')230        f.write('build_time_vars = ')231        _print_config_dict(vars, stream=f)232 233    print(f'Written {destfile}')234 235    install_vars = get_config_vars()236    # Fix config vars to match the values after install (of the default environment)237    install_vars['projectbase'] = install_vars['BINDIR']238    install_vars['srcdir'] = install_vars['LIBPL']239    # Write a JSON file with the output of sysconfig.get_config_vars240    jsonfile = os.path.join(pybuilddir, _get_json_data_name())241    with open(jsonfile, 'w') as f:242        json.dump(install_vars, f, indent=2)243 244    print(f'Written {jsonfile}')245 246    # Create file used for sys.path fixup -- see Modules/getpath.c247    with open('pybuilddir.txt', 'w', encoding='utf8') as f:248        f.write(pybuilddir)249 250 251def _print_dict(title, data):252    for index, (key, value) in enumerate(sorted(data.items())):253        if index == 0:254            print(f'{title}: ')255        print(f'\t{key} = "{value}"')256 257 258def _main():259    """Display all information sysconfig detains."""260    if '--generate-posix-vars' in sys.argv:261        _generate_posix_vars()262        return263    print(f'Platform: "{get_platform()}"')264    print(f'Python version: "{get_python_version()}"')265    print(f'Current installation scheme: "{get_default_scheme()}"')266    print()267    _print_dict('Paths', get_paths())268    print()269    _print_dict('Variables', get_config_vars())270 271 272if __name__ == '__main__':273    try:274        _main()275    except BrokenPipeError:276        pass277 
codekingpro/portable-devtools · Team Ai