Improve control flow in `check_confval_types()`

This commit is contained in:
Adam Turner 2023-12-29 17:20:21 +00:00
parent 20e804ab90
commit c3deb1746a

View File

@ -499,46 +499,54 @@ def check_confval_types(app: Sphinx | None, config: Config) -> None:
if default is None and not valid_types: if default is None and not valid_types:
continue # neither inferable nor explicitly annotated types continue # neither inferable nor explicitly annotated types
if valid_types is Any: if valid_types is Any: # any type of value is accepted
# any type of value is accepted continue
pass
elif isinstance(valid_types, ENUM): if isinstance(valid_types, ENUM):
if not valid_types.match(value): if not valid_types.match(value):
msg = __("The config value `{name}` has to be a one of {candidates}, " msg = __("The config value `{name}` has to be a one of {candidates}, "
"but `{current}` is given.") "but `{current}` is given.")
logger.warning(msg.format(name=name, logger.warning(
current=value, msg.format(name=name, current=value, candidates=valid_types.candidates),
candidates=valid_types.candidates), once=True) once=True,
else: )
if type(value) is type(default): continue
continue
if type(value) in valid_types:
continue
common_bases = (set(type(value).__bases__ + (type(value),)) & type_value = type(value)
set(type(default).__bases__)) type_default = type(default)
common_bases.discard(object)
if common_bases:
continue # at least we share a non-trivial base class
if valid_types: if type_value is type_default: # attempt to infer the type
msg = __("The config value `{name}' has type `{current.__name__}'; " continue
"expected {permitted}.")
wrapped_valid_types = [f"`{c.__name__}'" for c in valid_types] if type_value in valid_types: # check explicitly listed types
if len(wrapped_valid_types) > 2: continue
permitted = (", ".join(wrapped_valid_types[:-1])
+ f", or {wrapped_valid_types[-1]}") common_bases = (set(type_value.__bases__ + (type_value,))
else: & set(type_default.__bases__))
permitted = " or ".join(wrapped_valid_types) common_bases.discard(object)
logger.warning(msg.format(name=name, if common_bases:
current=type(value), continue # at least we share a non-trivial base class
permitted=permitted), once=True)
if valid_types:
msg = __("The config value `{name}' has type `{current.__name__}'; "
"expected {permitted}.")
wrapped_valid_types = [f"`{c.__name__}'" for c in valid_types]
if len(wrapped_valid_types) > 2:
permitted = (", ".join(wrapped_valid_types[:-1])
+ f", or {wrapped_valid_types[-1]}")
else: else:
msg = __("The config value `{name}' has type `{current.__name__}', " permitted = " or ".join(wrapped_valid_types)
"defaults to `{default.__name__}'.") logger.warning(
logger.warning(msg.format(name=name, msg.format(name=name, current=type_value, permitted=permitted),
current=type(value), once=True,
default=type(default)), once=True) )
else:
msg = __("The config value `{name}' has type `{current.__name__}', "
"defaults to `{default.__name__}'.")
logger.warning(
msg.format(name=name, current=type_value, default=type_default),
once=True,
)
def check_primary_domain(app: Sphinx, config: Config) -> None: def check_primary_domain(app: Sphinx, config: Config) -> None: