@@ -54,6 +54,12 @@ class SetupError(BaseError):
54
54
pass
55
55
56
56
57
+ class ConfigurationError (BaseError ):
58
+ """
59
+ Raised for errors in configuration files.
60
+ """
61
+
62
+
57
63
def listify_value (arg , split = None ):
58
64
"""
59
65
Make a list out of an argument.
@@ -1041,39 +1047,40 @@ def _parse_config_object(config: dict, *, filename="(unknown)"):
1041
1047
1042
1048
extractors_read = config .get ("extractors" , {})
1043
1049
if not isinstance (extractors_read , dict ):
1044
- raise ValueError (f"{ filename } : extractors: Expected a dictionary, got { type (extractors_read )!r} " )
1050
+ raise ConfigurationError (f"{ filename } : extractors: Expected a dictionary, got { type (extractors_read )!r} " )
1045
1051
for method , callable_spec in extractors_read .items ():
1046
1052
if not isinstance (method , str ):
1047
- raise ValueError (f"{ filename } : extractors: Extraction method must be a string, got { method !r} " )
1053
+ # Impossible via TOML, but could happen with a custom object.
1054
+ raise ConfigurationError (f"{ filename } : extractors: Extraction method must be a string, got { method !r} " )
1048
1055
if not isinstance (callable_spec , str ):
1049
- raise ValueError (f"{ filename } : extractors: Callable specification must be a string, got { callable_spec !r} " )
1056
+ raise ConfigurationError (f"{ filename } : extractors: Callable specification must be a string, got { callable_spec !r} " )
1050
1057
extractors [method ] = callable_spec
1051
1058
1052
1059
if "mapping" in config :
1053
- raise ValueError (f"{ filename } : 'mapping' is not a valid key, did you mean 'mappings'?" )
1060
+ raise ConfigurationError (f"{ filename } : 'mapping' is not a valid key, did you mean 'mappings'?" )
1054
1061
1055
1062
mappings_read = config .get ("mappings" , [])
1056
1063
if not isinstance (mappings_read , list ):
1057
- raise ValueError (f"{ filename } : mappings: Expected a list, got { type (mappings_read )!r} " )
1064
+ raise ConfigurationError (f"{ filename } : mappings: Expected a list, got { type (mappings_read )!r} " )
1058
1065
for idx , entry in enumerate (mappings_read ):
1059
1066
if not isinstance (entry , dict ):
1060
- raise ValueError (f"{ filename } : mappings[{ idx } ]: Expected a dictionary, got { type (entry )!r} " )
1067
+ raise ConfigurationError (f"{ filename } : mappings[{ idx } ]: Expected a dictionary, got { type (entry )!r} " )
1061
1068
entry = entry .copy ()
1062
1069
1063
1070
method = entry .pop ("method" , None )
1064
1071
if not isinstance (method , str ):
1065
- raise ValueError (f"{ filename } : mappings[{ idx } ]: 'method' must be a string, got { method !r} " )
1072
+ raise ConfigurationError (f"{ filename } : mappings[{ idx } ]: 'method' must be a string, got { method !r} " )
1066
1073
method = extractors .get (method , method ) # Map the extractor name to the callable now
1067
1074
1068
1075
pattern = entry .pop ("pattern" , None )
1069
1076
if not isinstance (pattern , (list , str )):
1070
- raise ValueError (f"{ filename } : mappings[{ idx } ]: 'pattern' must be a list or a string, got { pattern !r} " )
1077
+ raise ConfigurationError (f"{ filename } : mappings[{ idx } ]: 'pattern' must be a list or a string, got { pattern !r} " )
1071
1078
if not isinstance (pattern , list ):
1072
1079
pattern = [pattern ]
1073
1080
1074
1081
for pat in pattern :
1075
1082
if not isinstance (pat , str ):
1076
- raise ValueError (f"{ filename } : mappings[{ idx } ]: 'pattern' elements must be strings, got { pat !r} " )
1083
+ raise ConfigurationError (f"{ filename } : mappings[{ idx } ]: 'pattern' elements must be strings, got { pat !r} " )
1077
1084
method_map .append ((pat , method ))
1078
1085
options_map [pat ] = entry
1079
1086
@@ -1100,16 +1107,20 @@ def parse_mapping_toml(
1100
1107
except ImportError as ie :
1101
1108
raise ImportError ("tomli or tomllib is required to parse TOML files" ) from ie
1102
1109
1103
- parsed_data = tomllib .load (fileobj )
1110
+ try :
1111
+ parsed_data = tomllib .load (fileobj )
1112
+ except tomllib .TOMLDecodeError as e :
1113
+ raise ConfigurationError (f"{ filename } : Error parsing TOML file: { e } " ) from e
1114
+
1104
1115
if style == "pyproject.toml" :
1105
1116
try :
1106
1117
babel_data = parsed_data ["tool" ]["babel" ]
1107
1118
except (TypeError , KeyError ) as e :
1108
- raise ValueError (f"{ filename } : No 'tool.babel' section found in file" ) from e
1119
+ raise ConfigurationError (f"{ filename } : No 'tool.babel' section found in file" ) from e
1109
1120
elif style == "standalone" :
1110
1121
babel_data = parsed_data
1111
1122
if "babel" in babel_data :
1112
- raise ValueError (f"{ filename } : 'babel' should not be present in a stand-alone configuration file" )
1123
+ raise ConfigurationError (f"{ filename } : 'babel' should not be present in a stand-alone configuration file" )
1113
1124
else : # pragma: no cover
1114
1125
raise ValueError (f"Unknown TOML style { style !r} " )
1115
1126
0 commit comments