mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Migrate to py3 style type annotation: sphinx.config
This commit is contained in:
parent
6e88d66543
commit
7f5acbdf1f
@ -14,7 +14,9 @@ import types
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from os import path, getenv
|
from os import path, getenv
|
||||||
from typing import Any, NamedTuple, Union
|
from typing import (
|
||||||
|
Any, Callable, Dict, Generator, Iterator, List, NamedTuple, Set, Tuple, Union
|
||||||
|
)
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||||
from sphinx.errors import ConfigError, ExtensionError
|
from sphinx.errors import ConfigError, ExtensionError
|
||||||
@ -23,14 +25,13 @@ from sphinx.util import logging
|
|||||||
from sphinx.util.i18n import format_date
|
from sphinx.util.i18n import format_date
|
||||||
from sphinx.util.osutil import cd
|
from sphinx.util.osutil import cd
|
||||||
from sphinx.util.pycompat import execfile_
|
from sphinx.util.pycompat import execfile_
|
||||||
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.util.typing import NoneType
|
from sphinx.util.typing import NoneType
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Callable, Dict, Generator, Iterator, List, Set, Tuple # NOQA
|
from sphinx.application import Sphinx
|
||||||
from sphinx.application import Sphinx # NOQA
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.environment import BuildEnvironment # NOQA
|
|
||||||
from sphinx.util.tags import Tags # NOQA
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -43,8 +44,7 @@ ConfigValue = NamedTuple('ConfigValue', [('name', str),
|
|||||||
('rebuild', Union[bool, str])])
|
('rebuild', Union[bool, str])])
|
||||||
|
|
||||||
|
|
||||||
def is_serializable(obj):
|
def is_serializable(obj: Any) -> bool:
|
||||||
# type: (Any) -> bool
|
|
||||||
"""Check if object is serializable or not."""
|
"""Check if object is serializable or not."""
|
||||||
if isinstance(obj, UNSERIALIZABLE_TYPES):
|
if isinstance(obj, UNSERIALIZABLE_TYPES):
|
||||||
return False
|
return False
|
||||||
@ -64,12 +64,10 @@ class ENUM:
|
|||||||
Example:
|
Example:
|
||||||
app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline'))
|
app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline'))
|
||||||
"""
|
"""
|
||||||
def __init__(self, *candidates):
|
def __init__(self, *candidates: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
self.candidates = candidates
|
self.candidates = candidates
|
||||||
|
|
||||||
def match(self, value):
|
def match(self, value: Union[str, List, Tuple]) -> bool:
|
||||||
# type: (Union[str, List, Tuple]) -> bool
|
|
||||||
if isinstance(value, (list, tuple)):
|
if isinstance(value, (list, tuple)):
|
||||||
return all(item in self.candidates for item in value)
|
return all(item in self.candidates for item in value)
|
||||||
else:
|
else:
|
||||||
@ -156,8 +154,7 @@ class Config:
|
|||||||
'env', []),
|
'env', []),
|
||||||
} # type: Dict[str, Tuple]
|
} # type: Dict[str, Tuple]
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args) -> None:
|
||||||
# type: (Any) -> None
|
|
||||||
if len(args) == 4:
|
if len(args) == 4:
|
||||||
# old style arguments: (dirname, filename, overrides, tags)
|
# old style arguments: (dirname, filename, overrides, tags)
|
||||||
warnings.warn('The argument of Config() class has been changed. '
|
warnings.warn('The argument of Config() class has been changed. '
|
||||||
@ -190,27 +187,23 @@ class Config:
|
|||||||
self.extensions = config.get('extensions', []) # type: List[str]
|
self.extensions = config.get('extensions', []) # type: List[str]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def read(cls, confdir, overrides=None, tags=None):
|
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
|
||||||
# type: (str, Dict, Tags) -> Config
|
|
||||||
"""Create a Config object from configuration file."""
|
"""Create a Config object from configuration file."""
|
||||||
filename = path.join(confdir, CONFIG_FILENAME)
|
filename = path.join(confdir, CONFIG_FILENAME)
|
||||||
namespace = eval_config_file(filename, tags)
|
namespace = eval_config_file(filename, tags)
|
||||||
return cls(namespace, overrides or {})
|
return cls(namespace, overrides or {})
|
||||||
|
|
||||||
def check_types(self):
|
def check_types(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
warnings.warn('Config.check_types() is deprecated. Use check_confval_types() instead.',
|
warnings.warn('Config.check_types() is deprecated. Use check_confval_types() instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
check_confval_types(None, self)
|
check_confval_types(None, self)
|
||||||
|
|
||||||
def check_unicode(self):
|
def check_unicode(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
warnings.warn('Config.check_unicode() is deprecated. Use check_unicode() instead.',
|
warnings.warn('Config.check_unicode() is deprecated. Use check_unicode() instead.',
|
||||||
RemovedInSphinx30Warning, stacklevel=2)
|
RemovedInSphinx30Warning, stacklevel=2)
|
||||||
check_unicode(self)
|
check_unicode(self)
|
||||||
|
|
||||||
def convert_overrides(self, name, value):
|
def convert_overrides(self, name: str, value: Any) -> Any:
|
||||||
# type: (str, Any) -> Any
|
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
@ -243,8 +236,7 @@ class Config:
|
|||||||
else:
|
else:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def pre_init_values(self):
|
def pre_init_values(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
"""
|
"""
|
||||||
Initialize some limited config variables before initialize i18n and loading extensions
|
Initialize some limited config variables before initialize i18n and loading extensions
|
||||||
"""
|
"""
|
||||||
@ -258,8 +250,7 @@ class Config:
|
|||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
logger.warning("%s", exc)
|
logger.warning("%s", exc)
|
||||||
|
|
||||||
def init_values(self):
|
def init_values(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
config = self._raw_config
|
config = self._raw_config
|
||||||
for valname, value in self.overrides.items():
|
for valname, value in self.overrides.items():
|
||||||
try:
|
try:
|
||||||
@ -281,8 +272,7 @@ class Config:
|
|||||||
if name in self.values:
|
if name in self.values:
|
||||||
self.__dict__[name] = config[name]
|
self.__dict__[name] = config[name]
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name: str) -> Any:
|
||||||
# type: (str) -> Any
|
|
||||||
if name.startswith('_'):
|
if name.startswith('_'):
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
if name not in self.values:
|
if name not in self.values:
|
||||||
@ -292,42 +282,34 @@ class Config:
|
|||||||
return default(self)
|
return default(self)
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return getattr(self, name)
|
return getattr(self, name)
|
||||||
|
|
||||||
def __setitem__(self, name, value):
|
def __setitem__(self, name: str, value: Any) -> None:
|
||||||
# type: (str, Any) -> None
|
|
||||||
setattr(self, name, value)
|
setattr(self, name, value)
|
||||||
|
|
||||||
def __delitem__(self, name):
|
def __delitem__(self, name: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
delattr(self, name)
|
delattr(self, name)
|
||||||
|
|
||||||
def __contains__(self, name):
|
def __contains__(self, name: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
return name in self.values
|
return name in self.values
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self) -> Generator[ConfigValue, None, None]:
|
||||||
# type: () -> Generator[ConfigValue, None, None]
|
|
||||||
for name, value in self.values.items():
|
for name, value in self.values.items():
|
||||||
yield ConfigValue(name, getattr(self, name), value[1])
|
yield ConfigValue(name, getattr(self, name), value[1])
|
||||||
|
|
||||||
def add(self, name, default, rebuild, types):
|
def add(self, name: str, default: Any, rebuild: Union[bool, str], types: Any) -> None:
|
||||||
# type: (str, Any, Union[bool, str], Any) -> None
|
|
||||||
if name in self.values:
|
if name in self.values:
|
||||||
raise ExtensionError(__('Config value %r already present') % name)
|
raise ExtensionError(__('Config value %r already present') % name)
|
||||||
else:
|
else:
|
||||||
self.values[name] = (default, rebuild, types)
|
self.values[name] = (default, rebuild, types)
|
||||||
|
|
||||||
def filter(self, rebuild):
|
def filter(self, rebuild: Union[str, List[str]]) -> Iterator[ConfigValue]:
|
||||||
# type: (Union[str, List[str]]) -> Iterator[ConfigValue]
|
|
||||||
if isinstance(rebuild, str):
|
if isinstance(rebuild, str):
|
||||||
rebuild = [rebuild]
|
rebuild = [rebuild]
|
||||||
return (value for value in self if value.rebuild in rebuild)
|
return (value for value in self if value.rebuild in rebuild)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self) -> Dict:
|
||||||
# type: () -> Dict
|
|
||||||
"""Obtains serializable data for pickling."""
|
"""Obtains serializable data for pickling."""
|
||||||
# remove potentially pickling-problematic values from config
|
# remove potentially pickling-problematic values from config
|
||||||
__dict__ = {}
|
__dict__ = {}
|
||||||
@ -350,13 +332,11 @@ class Config:
|
|||||||
|
|
||||||
return __dict__
|
return __dict__
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state: Dict) -> None:
|
||||||
# type: (Dict) -> None
|
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
|
|
||||||
|
|
||||||
def eval_config_file(filename, tags):
|
def eval_config_file(filename: str, tags: Tags) -> Dict[str, Any]:
|
||||||
# type: (str, Tags) -> Dict[str, Any]
|
|
||||||
"""Evaluate a config file."""
|
"""Evaluate a config file."""
|
||||||
namespace = {} # type: Dict[str, Any]
|
namespace = {} # type: Dict[str, Any]
|
||||||
namespace['__file__'] = filename
|
namespace['__file__'] = filename
|
||||||
@ -380,8 +360,7 @@ def eval_config_file(filename, tags):
|
|||||||
return namespace
|
return namespace
|
||||||
|
|
||||||
|
|
||||||
def convert_source_suffix(app, config):
|
def convert_source_suffix(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""This converts old styled source_suffix to new styled one.
|
"""This converts old styled source_suffix to new styled one.
|
||||||
|
|
||||||
* old style: str or list
|
* old style: str or list
|
||||||
@ -406,8 +385,7 @@ def convert_source_suffix(app, config):
|
|||||||
"But `%r' is given." % source_suffix))
|
"But `%r' is given." % source_suffix))
|
||||||
|
|
||||||
|
|
||||||
def init_numfig_format(app, config):
|
def init_numfig_format(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""Initialize :confval:`numfig_format`."""
|
"""Initialize :confval:`numfig_format`."""
|
||||||
numfig_format = {'section': _('Section %s'),
|
numfig_format = {'section': _('Section %s'),
|
||||||
'figure': _('Fig. %s'),
|
'figure': _('Fig. %s'),
|
||||||
@ -419,8 +397,7 @@ def init_numfig_format(app, config):
|
|||||||
config.numfig_format = numfig_format # type: ignore
|
config.numfig_format = numfig_format # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def correct_copyright_year(app, config):
|
def correct_copyright_year(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""correct values of copyright year that are not coherent with
|
"""correct values of copyright year that are not coherent with
|
||||||
the SOURCE_DATE_EPOCH environment variable (if set)
|
the SOURCE_DATE_EPOCH environment variable (if set)
|
||||||
|
|
||||||
@ -433,8 +410,7 @@ def correct_copyright_year(app, config):
|
|||||||
config[k] = copyright_year_re.sub(replace, config[k])
|
config[k] = copyright_year_re.sub(replace, config[k])
|
||||||
|
|
||||||
|
|
||||||
def check_confval_types(app, config):
|
def check_confval_types(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
"""check all values for deviation from the default value's type, since
|
"""check all values for deviation from the default value's type, since
|
||||||
that can result in TypeErrors all over the place NB.
|
that can result in TypeErrors all over the place NB.
|
||||||
"""
|
"""
|
||||||
@ -489,8 +465,7 @@ def check_confval_types(app, config):
|
|||||||
default=type(default)))
|
default=type(default)))
|
||||||
|
|
||||||
|
|
||||||
def check_unicode(config):
|
def check_unicode(config: Config) -> None:
|
||||||
# type: (Config) -> None
|
|
||||||
"""check all string values for non-ASCII characters in bytestrings,
|
"""check all string values for non-ASCII characters in bytestrings,
|
||||||
since that can result in UnicodeErrors all over the place
|
since that can result in UnicodeErrors all over the place
|
||||||
"""
|
"""
|
||||||
@ -506,16 +481,15 @@ def check_unicode(config):
|
|||||||
'Please use Unicode strings, e.g. %r.'), name, 'Content')
|
'Please use Unicode strings, e.g. %r.'), name, 'Content')
|
||||||
|
|
||||||
|
|
||||||
def check_primary_domain(app, config):
|
def check_primary_domain(app: "Sphinx", config: Config) -> None:
|
||||||
# type: (Sphinx, Config) -> None
|
|
||||||
primary_domain = config.primary_domain
|
primary_domain = config.primary_domain
|
||||||
if primary_domain and not app.registry.has_domain(primary_domain):
|
if primary_domain and not app.registry.has_domain(primary_domain):
|
||||||
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
|
||||||
config.primary_domain = None # type: ignore
|
config.primary_domain = None # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def check_master_doc(app, env, added, changed, removed):
|
def check_master_doc(app: "Sphinx", env: "BuildEnvironment", added: Set[str],
|
||||||
# type: (Sphinx, BuildEnvironment, Set[str], Set[str], Set[str]) -> Set[str]
|
changed: Set[str], removed: Set[str]) -> Set[str]:
|
||||||
"""Adjust master_doc to 'contents' to support an old project which does not have
|
"""Adjust master_doc to 'contents' to support an old project which does not have
|
||||||
no master_doc setting.
|
no master_doc setting.
|
||||||
"""
|
"""
|
||||||
@ -529,8 +503,7 @@ def check_master_doc(app, env, added, changed, removed):
|
|||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||||
# type: (Sphinx) -> Dict[str, Any]
|
|
||||||
app.connect('config-inited', convert_source_suffix)
|
app.connect('config-inited', convert_source_suffix)
|
||||||
app.connect('config-inited', init_numfig_format)
|
app.connect('config-inited', init_numfig_format)
|
||||||
app.connect('config-inited', correct_copyright_year)
|
app.connect('config-inited', correct_copyright_year)
|
||||||
|
Loading…
Reference in New Issue
Block a user