def _read_setup_cfg(self, parser, cfg_filename): cfg_directory = os.path.dirname(os.path.abspath(cfg_filename)) content = {} for section in parser.sections(): content[section] = dict(parser.items(section)) # global setup hooks are called first if "global" in content: if "setup_hooks" in content["global"]: setup_hooks = split_multiline(content["global"]["setup_hooks"]) # add project directory to sys.path, to allow hooks to be # distributed with the project sys.path.insert(0, cfg_directory) try: for line in setup_hooks: try: hook = resolve_name(line) except ImportError, e: logger.warning("cannot find setup hook: %s", e.args[0]) else: self.setup_hooks.append(hook) self.run_hooks(content) finally: sys.path.pop(0)
def _load_commands(self, commands): commands = split_multiline(commands) if isinstance(commands, str): commands = [commands] for command in commands: set_command(command.strip())
def _load_compilers(self, compilers): compilers = split_multiline(compilers) if isinstance(compilers, str): compilers = [compilers] for compiler in compilers: set_compiler(compiler.strip())
def parse_config_files(self, filenames=None): if filenames is None: filenames = self.find_config_files() logger.debug("Distribution.parse_config_files():") parser = RawConfigParser() for filename in filenames: logger.debug(" reading %s", filename) with open(filename, 'r', encoding='utf-8') as f: parser.readfp(f) if os.path.split(filename)[-1] == 'setup.cfg': self._read_setup_cfg(parser, filename) for section in parser.sections(): if section == 'global': if parser.has_option('global', 'compilers'): self._load_compilers(parser.get('global', 'compilers')) if parser.has_option('global', 'commands'): self._load_commands(parser.get('global', 'commands')) options = parser.options(section) opt_dict = self.dist.get_option_dict(section) for opt in options: if opt == '__name__': continue val = parser.get(section, opt) opt = opt.replace('-', '_') if opt == 'sub_commands': val = split_multiline(val) if isinstance(val, str): val = [val] # Hooks use a suffix system to prevent being overriden # by a config file processed later (i.e. a hook set in # the user config file cannot be replaced by a hook # set in a project config file, unless they have the # same suffix). if (opt.startswith("pre_hook.") or opt.startswith("post_hook.")): hook_type, alias = opt.split(".") hook_dict = opt_dict.setdefault( hook_type, (filename, {}))[1] hook_dict[alias] = val else: opt_dict[opt] = filename, val # Make the RawConfigParser forget everything (so we retain # the original filenames that options come from) parser.__init__() # If there was a "global" section in the config file, use it # to set Distribution options. if 'global' in self.dist.command_options: for opt, (src, val) in self.dist.command_options['global'].items(): alias = self.dist.negative_opt.get(opt) try: if alias: setattr(self.dist, alias, not strtobool(val)) elif opt == 'dry_run': # FIXME ugh! setattr(self.dist, opt, strtobool(val)) else: setattr(self.dist, opt, val) except ValueError as msg: raise PackagingOptionError(msg)
def _read_setup_cfg(self, parser, cfg_filename): cfg_directory = os.path.dirname(os.path.abspath(cfg_filename)) content = {} for section in parser.sections(): content[section] = dict(parser.items(section)) # global setup hooks are called first if 'global' in content: if 'setup_hooks' in content['global']: setup_hooks = split_multiline(content['global']['setup_hooks']) # add project directory to sys.path, to allow hooks to be # distributed with the project sys.path.insert(0, cfg_directory) try: for line in setup_hooks: try: hook = resolve_name(line) except ImportError as e: logger.warning('cannot find setup hook: %s', e.args[0]) else: self.setup_hooks.append(hook) self.run_hooks(content) finally: sys.path.pop(0) metadata = self.dist.metadata # setting the metadata values if 'metadata' in content: for key, value in content['metadata'].items(): key = key.replace('_', '-') if metadata.is_multi_field(key): value = split_multiline(value) if key == 'project-url': value = [(label.strip(), url.strip()) for label, url in [v.split(',') for v in value]] if key == 'description-file': if 'description' in content['metadata']: msg = ("description and description-file' are " "mutually exclusive") raise PackagingOptionError(msg) filenames = value.split() # concatenate all files value = [] for filename in filenames: # will raise if file not found with open(filename) as description_file: value.append(description_file.read().strip()) # add filename as a required file if filename not in metadata.requires_files: metadata.requires_files.append(filename) value = '\n'.join(value).strip() key = 'description' if metadata.is_metadata_field(key): metadata[key] = self._convert_metadata(key, value) if 'files' in content: files = content['files'] self.dist.package_dir = files.pop('packages_root', None) files = dict((key, split_multiline(value)) for key, value in files.items()) self.dist.packages = [] packages = files.get('packages', []) if isinstance(packages, str): packages = [packages] for package in packages: if ':' in package: dir_, package = package.split(':') self.dist.package_dir[package] = dir_ self.dist.packages.append(package) self.dist.py_modules = files.get('modules', []) if isinstance(self.dist.py_modules, str): self.dist.py_modules = [self.dist.py_modules] self.dist.scripts = files.get('scripts', []) if isinstance(self.dist.scripts, str): self.dist.scripts = [self.dist.scripts] self.dist.package_data = {} # bookkeeping for the loop below firstline = True prev = None for line in files.get('package_data', []): if '=' in line: # package name -- file globs or specs key, value = line.split('=') prev = self.dist.package_data[key.strip()] = value.split() elif firstline: # invalid continuation on the first line raise PackagingOptionError( 'malformed package_data first line: %r (misses "=")' % line) else: # continuation, add to last seen package name prev.extend(line.split()) firstline = False self.dist.data_files = [] for data in files.get('data_files', []): data = data.split('=') if len(data) != 2: continue key, value = data values = [v.strip() for v in value.split(',')] self.dist.data_files.append((key, values)) # manifest template self.dist.extra_files = files.get('extra_files', []) resources = [] for rule in files.get('resources', []): glob, destination = rule.split('=', 1) rich_glob = glob.strip().split(' ', 1) if len(rich_glob) == 2: prefix, suffix = rich_glob else: assert len(rich_glob) == 1 prefix = '' suffix = glob if destination == '<exclude>': destination = None resources.append( (prefix.strip(), suffix.strip(), destination.strip())) self.dist.data_files = get_resources_dests( cfg_directory, resources) ext_modules = self.dist.ext_modules for section_key in content: # no str.partition in 2.4 :( labels = section_key.split(':') if len(labels) == 2 and labels[0] == 'extension': values_dct = content[section_key] if 'name' in values_dct: raise PackagingOptionError( 'extension name should be given as [extension: name], ' 'not as key') name = labels[1].strip() _check_name(name, self.dist.packages) ext_modules.append(Extension( name, _pop_values(values_dct, 'sources'), _pop_values(values_dct, 'include_dirs'), _pop_values(values_dct, 'define_macros'), _pop_values(values_dct, 'undef_macros'), _pop_values(values_dct, 'library_dirs'), _pop_values(values_dct, 'libraries'), _pop_values(values_dct, 'runtime_library_dirs'), _pop_values(values_dct, 'extra_objects'), _pop_values(values_dct, 'extra_compile_args'), _pop_values(values_dct, 'extra_link_args'), _pop_values(values_dct, 'export_symbols'), _pop_values(values_dct, 'swig_opts'), _pop_values(values_dct, 'depends'), values_dct.pop('language', None), values_dct.pop('optional', None), **values_dct))
def _load_commands(self, commands): commands = split_multiline(commands) if isinstance(commands, basestring): commands = [commands] for command in commands: set_command(command.strip())
def _load_compilers(self, compilers): compilers = split_multiline(compilers) if isinstance(compilers, basestring): compilers = [compilers] for compiler in compilers: set_compiler(compiler.strip())
def parse_config_files(self, filenames=None): if filenames is None: filenames = self.find_config_files() logger.debug("Distribution.parse_config_files():") parser = RawConfigParser() for filename in filenames: logger.debug(" reading %s", filename) f = codecs.open(filename, "r", encoding="utf-8") try: parser.readfp(f) finally: f.close() if os.path.split(filename)[-1] == "setup.cfg": self._read_setup_cfg(parser, filename) for section in parser.sections(): if section == "global": if parser.has_option("global", "compilers"): self._load_compilers(parser.get("global", "compilers")) if parser.has_option("global", "commands"): self._load_commands(parser.get("global", "commands")) options = parser.options(section) opt_dict = self.dist.get_option_dict(section) for opt in options: if opt == "__name__": continue val = parser.get(section, opt) opt = opt.replace("-", "_") if opt == "sub_commands": val = split_multiline(val) if isinstance(val, basestring): val = [val] # Hooks use a suffix system to prevent being overriden # by a config file processed later (i.e. a hook set in # the user config file cannot be replaced by a hook # set in a project config file, unless they have the # same suffix). if opt.startswith("pre_hook.") or opt.startswith("post_hook."): hook_type, alias = opt.split(".") hook_dict = opt_dict.setdefault(hook_type, (filename, {}))[1] hook_dict[alias] = val else: opt_dict[opt] = filename, val # Make the RawConfigParser forget everything (so we retain # the original filenames that options come from) parser.__init__() # If there was a "global" section in the config file, use it # to set Distribution options. if "global" in self.dist.command_options: for opt, (src, val) in self.dist.command_options["global"].items(): alias = self.dist.negative_opt.get(opt) try: if alias: setattr(self.dist, alias, not strtobool(val)) elif opt == "dry_run": # FIXME ugh! setattr(self.dist, opt, strtobool(val)) else: setattr(self.dist, opt, val) except ValueError, msg: raise PackagingOptionError(msg)
except ImportError, e: logger.warning("cannot find setup hook: %s", e.args[0]) else: self.setup_hooks.append(hook) self.run_hooks(content) finally: sys.path.pop(0) metadata = self.dist.metadata # setting the metadata values if "metadata" in content: for key, value in content["metadata"].items(): key = key.replace("_", "-") if metadata.is_multi_field(key): value = split_multiline(value) if key == "project-url": value = [(label.strip(), url.strip()) for label, url in [v.split(",") for v in value]] if key == "description-file": if "description" in content["metadata"]: msg = "description and description-file' are " "mutually exclusive" raise PackagingOptionError(msg) filenames = value.split() # concatenate all files value = [] for filename in filenames: # will raise if file not found