Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
core.py291 linesDownload Raw Back to _distutils
1"""distutils.core2 3The only module that needs to be imported to use the Distutils; provides4the 'setup' function (which is to be called from the setup script).  Also5indirectly provides the Distribution and Command classes, although they are6really defined in distutils.dist and distutils.cmd.7"""8 9import os10import sys11import tokenize12 13from .cmd import Command14from .config import PyPIRCCommand15from .debug import DEBUG16 17# Mainly import these so setup scripts can "from distutils.core import" them.18from .dist import Distribution19from .errors import (20    CCompilerError,21    DistutilsArgError,22    DistutilsError,23    DistutilsSetupError,24)25from .extension import Extension26 27__all__ = ['Distribution', 'Command', 'PyPIRCCommand', 'Extension', 'setup']28 29# This is a barebones help message generated displayed when the user30# runs the setup script with no arguments at all.  More useful help31# is generated with various --help options: global help, list commands,32# and per-command help.33USAGE = """\34usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]35   or: %(script)s --help [cmd1 cmd2 ...]36   or: %(script)s --help-commands37   or: %(script)s cmd --help38"""39 40 41def gen_usage(script_name):42    script = os.path.basename(script_name)43    return USAGE % locals()44 45 46# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'.47_setup_stop_after = None48_setup_distribution = None49 50# Legal keyword arguments for the setup() function51setup_keywords = (52    'distclass',53    'script_name',54    'script_args',55    'options',56    'name',57    'version',58    'author',59    'author_email',60    'maintainer',61    'maintainer_email',62    'url',63    'license',64    'description',65    'long_description',66    'keywords',67    'platforms',68    'classifiers',69    'download_url',70    'requires',71    'provides',72    'obsoletes',73)74 75# Legal keyword arguments for the Extension constructor76extension_keywords = (77    'name',78    'sources',79    'include_dirs',80    'define_macros',81    'undef_macros',82    'library_dirs',83    'libraries',84    'runtime_library_dirs',85    'extra_objects',86    'extra_compile_args',87    'extra_link_args',88    'swig_opts',89    'export_symbols',90    'depends',91    'language',92)93 94 95def setup(**attrs):  # noqa: C90196    """The gateway to the Distutils: do everything your setup script needs97    to do, in a highly flexible and user-driven way.  Briefly: create a98    Distribution instance; find and parse config files; parse the command99    line; run each Distutils command found there, customized by the options100    supplied to 'setup()' (as keyword arguments), in config files, and on101    the command line.102 103    The Distribution instance might be an instance of a class supplied via104    the 'distclass' keyword argument to 'setup'; if no such class is105    supplied, then the Distribution class (in dist.py) is instantiated.106    All other arguments to 'setup' (except for 'cmdclass') are used to set107    attributes of the Distribution instance.108 109    The 'cmdclass' argument, if supplied, is a dictionary mapping command110    names to command classes.  Each command encountered on the command line111    will be turned into a command class, which is in turn instantiated; any112    class found in 'cmdclass' is used in place of the default, which is113    (for command 'foo_bar') class 'foo_bar' in module114    'distutils.command.foo_bar'.  The command class must provide a115    'user_options' attribute which is a list of option specifiers for116    'distutils.fancy_getopt'.  Any command-line options between the current117    and the next command are used to set attributes of the current command118    object.119 120    When the entire command-line has been successfully parsed, calls the121    'run()' method on each command object in turn.  This method will be122    driven entirely by the Distribution object (which each command object123    has a reference to, thanks to its constructor), and the124    command-specific options that became attributes of each command125    object.126    """127 128    global _setup_stop_after, _setup_distribution129 130    # Determine the distribution class -- either caller-supplied or131    # our Distribution (see below).132    klass = attrs.get('distclass')133    if klass:134        attrs.pop('distclass')135    else:136        klass = Distribution137 138    if 'script_name' not in attrs:139        attrs['script_name'] = os.path.basename(sys.argv[0])140    if 'script_args' not in attrs:141        attrs['script_args'] = sys.argv[1:]142 143    # Create the Distribution instance, using the remaining arguments144    # (ie. everything except distclass) to initialize it145    try:146        _setup_distribution = dist = klass(attrs)147    except DistutilsSetupError as msg:148        if 'name' not in attrs:149            raise SystemExit("error in setup command: %s" % msg)150        else:151            raise SystemExit("error in {} setup command: {}".format(attrs['name'], msg))152 153    if _setup_stop_after == "init":154        return dist155 156    # Find and parse the config file(s): they will override options from157    # the setup script, but be overridden by the command line.158    dist.parse_config_files()159 160    if DEBUG:161        print("options (after parsing config files):")162        dist.dump_option_dicts()163 164    if _setup_stop_after == "config":165        return dist166 167    # Parse the command line and override config files; any168    # command-line errors are the end user's fault, so turn them into169    # SystemExit to suppress tracebacks.170    try:171        ok = dist.parse_command_line()172    except DistutilsArgError as msg:173        raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg)174 175    if DEBUG:176        print("options (after parsing command line):")177        dist.dump_option_dicts()178 179    if _setup_stop_after == "commandline":180        return dist181 182    # And finally, run all the commands found on the command line.183    if ok:184        return run_commands(dist)185 186    return dist187 188 189# setup ()190 191 192def run_commands(dist):193    """Given a Distribution object run all the commands,194    raising ``SystemExit`` errors in the case of failure.195 196    This function assumes that either ``sys.argv`` or ``dist.script_args``197    is already set accordingly.198    """199    try:200        dist.run_commands()201    except KeyboardInterrupt:202        raise SystemExit("interrupted")203    except OSError as exc:204        if DEBUG:205            sys.stderr.write(f"error: {exc}\n")206            raise207        else:208            raise SystemExit(f"error: {exc}")209 210    except (DistutilsError, CCompilerError) as msg:211        if DEBUG:212            raise213        else:214            raise SystemExit("error: " + str(msg))215 216    return dist217 218 219def run_setup(script_name, script_args=None, stop_after="run"):220    """Run a setup script in a somewhat controlled environment, and221    return the Distribution instance that drives things.  This is useful222    if you need to find out the distribution meta-data (passed as223    keyword args from 'script' to 'setup()', or the contents of the224    config files or command-line.225 226    'script_name' is a file that will be read and run with 'exec()';227    'sys.argv[0]' will be replaced with 'script' for the duration of the228    call.  'script_args' is a list of strings; if supplied,229    'sys.argv[1:]' will be replaced by 'script_args' for the duration of230    the call.231 232    'stop_after' tells 'setup()' when to stop processing; possible233    values:234      init235        stop after the Distribution instance has been created and236        populated with the keyword arguments to 'setup()'237      config238        stop after config files have been parsed (and their data239        stored in the Distribution instance)240      commandline241        stop after the command-line ('sys.argv[1:]' or 'script_args')242        have been parsed (and the data stored in the Distribution)243      run [default]244        stop after all commands have been run (the same as if 'setup()'245        had been called in the usual way246 247    Returns the Distribution instance, which provides all information248    used to drive the Distutils.249    """250    if stop_after not in ('init', 'config', 'commandline', 'run'):251        raise ValueError(f"invalid value for 'stop_after': {stop_after!r}")252 253    global _setup_stop_after, _setup_distribution254    _setup_stop_after = stop_after255 256    save_argv = sys.argv.copy()257    g = {'__file__': script_name, '__name__': '__main__'}258    try:259        try:260            sys.argv[0] = script_name261            if script_args is not None:262                sys.argv[1:] = script_args263            # tokenize.open supports automatic encoding detection264            with tokenize.open(script_name) as f:265                code = f.read().replace(r'\r\n', r'\n')266                exec(code, g)267        finally:268            sys.argv = save_argv269            _setup_stop_after = None270    except SystemExit:271        # Hmm, should we do something if exiting with a non-zero code272        # (ie. error)?273        pass274 275    if _setup_distribution is None:276        raise RuntimeError(277            (278                "'distutils.core.setup()' was never called -- "279                "perhaps '%s' is not a Distutils setup script?"280            )281            % script_name282        )283 284    # I wonder if the setup script's namespace -- g and l -- would be of285    # any interest to callers?286    # print "_setup_distribution:", _setup_distribution287    return _setup_distribution288 289 290# run_setup ()291 
codekingpro/portable-devtools · Team Ai