eric7/DebugClients/Python/coverage/config.py

branch
eric7
changeset 8775
0802ae193343
parent 8527
2bd1325d727e
child 8929
fcca2fa618bf
equal deleted inserted replaced
8774:d728227e8ebb 8775:0802ae193343
2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt 2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
3 3
4 """Config file for coverage.py""" 4 """Config file for coverage.py"""
5 5
6 import collections 6 import collections
7 import configparser
7 import copy 8 import copy
8 import os 9 import os
9 import os.path 10 import os.path
10 import re 11 import re
11 12
12 from coverage import env 13 from coverage.exceptions import CoverageException
13 from coverage.backward import configparser, iitems, string_class 14 from coverage.misc import contract, isolate_module, substitute_variables
14 from coverage.misc import contract, CoverageException, isolate_module
15 from coverage.misc import substitute_variables
16 15
17 from coverage.tomlconfig import TomlConfigParser, TomlDecodeError 16 from coverage.tomlconfig import TomlConfigParser, TomlDecodeError
18 17
19 os = isolate_module(os) 18 os = isolate_module(os)
20 19
33 configparser.RawConfigParser.__init__(self) 32 configparser.RawConfigParser.__init__(self)
34 self.section_prefixes = ["coverage:"] 33 self.section_prefixes = ["coverage:"]
35 if our_file: 34 if our_file:
36 self.section_prefixes.append("") 35 self.section_prefixes.append("")
37 36
38 def read(self, filenames, encoding=None): 37 def read(self, filenames, encoding_unused=None):
39 """Read a file name as UTF-8 configuration data.""" 38 """Read a file name as UTF-8 configuration data."""
40 kwargs = {} 39 return configparser.RawConfigParser.read(self, filenames, encoding="utf-8")
41 if env.PYVERSION >= (3, 2):
42 kwargs['encoding'] = encoding or "utf-8"
43 return configparser.RawConfigParser.read(self, filenames, **kwargs)
44 40
45 def has_option(self, section, option): 41 def has_option(self, section, option):
46 for section_prefix in self.section_prefixes: 42 for section_prefix in self.section_prefixes:
47 real_section = section_prefix + section 43 real_section = section_prefix + section
48 has = configparser.RawConfigParser.has_option(self, real_section, option) 44 has = configparser.RawConfigParser.has_option(self, real_section, option)
126 value = value.strip() 122 value = value.strip()
127 try: 123 try:
128 re.compile(value) 124 re.compile(value)
129 except re.error as e: 125 except re.error as e:
130 raise CoverageException( 126 raise CoverageException(
131 "Invalid [%s].%s value %r: %s" % (section, option, value, e) 127 f"Invalid [{section}].{option} value {value!r}: {e}"
132 ) 128 ) from e
133 if value: 129 if value:
134 value_list.append(value) 130 value_list.append(value)
135 return value_list 131 return value_list
136 132
137 133
152 'while (True|1|False|0):', 148 'while (True|1|False|0):',
153 'if (True|1|False|0):', 149 'if (True|1|False|0):',
154 ] 150 ]
155 151
156 152
157 class CoverageConfig(object): 153 class CoverageConfig:
158 """Coverage.py configuration. 154 """Coverage.py configuration.
159 155
160 The attributes of this class are the various settings that control the 156 The attributes of this class are the various settings that control the
161 operation of coverage.py. 157 operation of coverage.py.
162 158
243 "run_omit", "run_include", 239 "run_omit", "run_include",
244 ] 240 ]
245 241
246 def from_args(self, **kwargs): 242 def from_args(self, **kwargs):
247 """Read config values from `kwargs`.""" 243 """Read config values from `kwargs`."""
248 for k, v in iitems(kwargs): 244 for k, v in kwargs.items():
249 if v is not None: 245 if v is not None:
250 if k in self.MUST_BE_LIST and isinstance(v, string_class): 246 if k in self.MUST_BE_LIST and isinstance(v, str):
251 v = [v] 247 v = [v]
252 setattr(self, k, v) 248 setattr(self, k, v)
253 249
254 @contract(filename=str) 250 @contract(filename=str)
255 def from_file(self, filename, our_file): 251 def from_file(self, filename, warn, our_file):
256 """Read configuration from a .rc file. 252 """Read configuration from a .rc file.
257 253
258 `filename` is a file name to read. 254 `filename` is a file name to read.
259 255
260 `our_file` is True if this config file is specifically for coverage, 256 `our_file` is True if this config file is specifically for coverage,
274 self.attempted_config_files.append(filename) 270 self.attempted_config_files.append(filename)
275 271
276 try: 272 try:
277 files_read = cp.read(filename) 273 files_read = cp.read(filename)
278 except (configparser.Error, TomlDecodeError) as err: 274 except (configparser.Error, TomlDecodeError) as err:
279 raise CoverageException("Couldn't read config file %s: %s" % (filename, err)) 275 raise CoverageException(f"Couldn't read config file {filename}: {err}") from err
280 if not files_read: 276 if not files_read:
281 return False 277 return False
282 278
283 self.config_files_read.extend(map(os.path.abspath, files_read)) 279 self.config_files_read.extend(map(os.path.abspath, files_read))
284 280
287 for option_spec in self.CONFIG_FILE_OPTIONS: 283 for option_spec in self.CONFIG_FILE_OPTIONS:
288 was_set = self._set_attr_from_config_option(cp, *option_spec) 284 was_set = self._set_attr_from_config_option(cp, *option_spec)
289 if was_set: 285 if was_set:
290 any_set = True 286 any_set = True
291 except ValueError as err: 287 except ValueError as err:
292 raise CoverageException("Couldn't read config file %s: %s" % (filename, err)) 288 raise CoverageException(f"Couldn't read config file {filename}: {err}") from err
293 289
294 # Check that there are no unrecognized options. 290 # Check that there are no unrecognized options.
295 all_options = collections.defaultdict(set) 291 all_options = collections.defaultdict(set)
296 for option_spec in self.CONFIG_FILE_OPTIONS: 292 for option_spec in self.CONFIG_FILE_OPTIONS:
297 section, option = option_spec[1].split(":") 293 section, option = option_spec[1].split(":")
298 all_options[section].add(option) 294 all_options[section].add(option)
299 295
300 for section, options in iitems(all_options): 296 for section, options in all_options.items():
301 real_section = cp.has_section(section) 297 real_section = cp.has_section(section)
302 if real_section: 298 if real_section:
303 for unknown in set(cp.options(section)) - options: 299 for unknown in set(cp.options(section)) - options:
304 raise CoverageException( 300 warn(
305 "Unrecognized option '[%s] %s=' in config file %s" % ( 301 "Unrecognized option '[{}] {}=' in config file {}".format(
306 real_section, unknown, filename 302 real_section, unknown, filename
307 ) 303 )
308 ) 304 )
309 305
310 # [paths] is special 306 # [paths] is special
445 if key and plugin_name in self.plugins: 441 if key and plugin_name in self.plugins:
446 self.plugin_options.setdefault(plugin_name, {})[key] = value 442 self.plugin_options.setdefault(plugin_name, {})[key] = value
447 return 443 return
448 444
449 # If we get here, we didn't find the option. 445 # If we get here, we didn't find the option.
450 raise CoverageException("No such option: %r" % option_name) 446 raise CoverageException(f"No such option: {option_name!r}")
451 447
452 def get_option(self, option_name): 448 def get_option(self, option_name):
453 """Get an option from the configuration. 449 """Get an option from the configuration.
454 450
455 `option_name` is a colon-separated string indicating the section and 451 `option_name` is a colon-separated string indicating the section and
473 plugin_name, _, key = option_name.partition(":") 469 plugin_name, _, key = option_name.partition(":")
474 if key and plugin_name in self.plugins: 470 if key and plugin_name in self.plugins:
475 return self.plugin_options.get(plugin_name, {}).get(key) 471 return self.plugin_options.get(plugin_name, {}).get(key)
476 472
477 # If we get here, we didn't find the option. 473 # If we get here, we didn't find the option.
478 raise CoverageException("No such option: %r" % option_name) 474 raise CoverageException(f"No such option: {option_name!r}")
479 475
480 def post_process_file(self, path): 476 def post_process_file(self, path):
481 """Make final adjustments to a file path to make it usable.""" 477 """Make final adjustments to a file path to make it usable."""
482 return os.path.expanduser(path) 478 return os.path.expanduser(path)
483 479
519 ("pyproject.toml", False, False), 515 ("pyproject.toml", False, False),
520 ] 516 ]
521 return files_to_try 517 return files_to_try
522 518
523 519
524 def read_coverage_config(config_file, **kwargs): 520 def read_coverage_config(config_file, warn, **kwargs):
525 """Read the coverage.py configuration. 521 """Read the coverage.py configuration.
526 522
527 Arguments: 523 Arguments:
528 config_file: a boolean or string, see the `Coverage` class for the 524 config_file: a boolean or string, see the `Coverage` class for the
529 tricky details. 525 tricky details.
526 warn: a function to issue warnings.
530 all others: keyword arguments from the `Coverage` class, used for 527 all others: keyword arguments from the `Coverage` class, used for
531 setting values in the configuration. 528 setting values in the configuration.
532 529
533 Returns: 530 Returns:
534 config: 531 config:
543 # 2) from a file: 540 # 2) from a file:
544 if config_file: 541 if config_file:
545 files_to_try = config_files_to_try(config_file) 542 files_to_try = config_files_to_try(config_file)
546 543
547 for fname, our_file, specified_file in files_to_try: 544 for fname, our_file, specified_file in files_to_try:
548 config_read = config.from_file(fname, our_file=our_file) 545 config_read = config.from_file(fname, warn, our_file=our_file)
549 if config_read: 546 if config_read:
550 break 547 break
551 if specified_file: 548 if specified_file:
552 raise CoverageException("Couldn't read '%s' as a config file" % fname) 549 raise CoverageException(f"Couldn't read {fname!r} as a config file")
553 550
554 # $set_env.py: COVERAGE_DEBUG - Options for --debug. 551 # $set_env.py: COVERAGE_DEBUG - Options for --debug.
555 # 3) from environment variables: 552 # 3) from environment variables:
556 env_data_file = os.environ.get('COVERAGE_FILE') 553 env_data_file = os.environ.get('COVERAGE_FILE')
557 if env_data_file: 554 if env_data_file:

eric ide

mercurial