Path: blob/main/test/lib/python3.9/site-packages/setuptools/command/setopt.py
4799 views
from distutils.util import convert_path1from distutils import log2from distutils.errors import DistutilsOptionError3import distutils4import os5import configparser67from setuptools import Command89__all__ = ['config_file', 'edit_config', 'option_base', 'setopt']101112def config_file(kind="local"):13"""Get the filename of the distutils, local, global, or per-user config1415`kind` must be one of "local", "global", or "user"16"""17if kind == 'local':18return 'setup.cfg'19if kind == 'global':20return os.path.join(21os.path.dirname(distutils.__file__), 'distutils.cfg'22)23if kind == 'user':24dot = os.name == 'posix' and '.' or ''25return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot))26raise ValueError(27"config_file() type must be 'local', 'global', or 'user'", kind28)293031def edit_config(filename, settings, dry_run=False):32"""Edit a configuration file to include `settings`3334`settings` is a dictionary of dictionaries or ``None`` values, keyed by35command/section name. A ``None`` value means to delete the entire section,36while a dictionary lists settings to be changed or deleted in that section.37A setting of ``None`` means to delete that setting.38"""39log.debug("Reading configuration from %s", filename)40opts = configparser.RawConfigParser()41opts.optionxform = lambda x: x42opts.read([filename])43for section, options in settings.items():44if options is None:45log.info("Deleting section [%s] from %s", section, filename)46opts.remove_section(section)47else:48if not opts.has_section(section):49log.debug("Adding new section [%s] to %s", section, filename)50opts.add_section(section)51for option, value in options.items():52if value is None:53log.debug(54"Deleting %s.%s from %s",55section, option, filename56)57opts.remove_option(section, option)58if not opts.options(section):59log.info("Deleting empty [%s] section from %s",60section, filename)61opts.remove_section(section)62else:63log.debug(64"Setting %s.%s to %r in %s",65section, option, value, filename66)67opts.set(section, option, value)6869log.info("Writing %s", filename)70if not dry_run:71with open(filename, 'w') as f:72opts.write(f)737475class option_base(Command):76"""Abstract base class for commands that mess with config files"""7778user_options = [79('global-config', 'g',80"save options to the site-wide distutils.cfg file"),81('user-config', 'u',82"save options to the current user's pydistutils.cfg file"),83('filename=', 'f',84"configuration file to use (default=setup.cfg)"),85]8687boolean_options = [88'global-config', 'user-config',89]9091def initialize_options(self):92self.global_config = None93self.user_config = None94self.filename = None9596def finalize_options(self):97filenames = []98if self.global_config:99filenames.append(config_file('global'))100if self.user_config:101filenames.append(config_file('user'))102if self.filename is not None:103filenames.append(self.filename)104if not filenames:105filenames.append(config_file('local'))106if len(filenames) > 1:107raise DistutilsOptionError(108"Must specify only one configuration file option",109filenames110)111self.filename, = filenames112113114class setopt(option_base):115"""Save command-line options to a file"""116117description = "set an option in setup.cfg or another config file"118119user_options = [120('command=', 'c', 'command to set an option for'),121('option=', 'o', 'option to set'),122('set-value=', 's', 'value of the option'),123('remove', 'r', 'remove (unset) the value'),124] + option_base.user_options125126boolean_options = option_base.boolean_options + ['remove']127128def initialize_options(self):129option_base.initialize_options(self)130self.command = None131self.option = None132self.set_value = None133self.remove = None134135def finalize_options(self):136option_base.finalize_options(self)137if self.command is None or self.option is None:138raise DistutilsOptionError("Must specify --command *and* --option")139if self.set_value is None and not self.remove:140raise DistutilsOptionError("Must specify --set-value or --remove")141142def run(self):143edit_config(144self.filename, {145self.command: {self.option.replace('-', '_'): self.set_value}146},147self.dry_run148)149150151