mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #6535 from tk0miya/refactor_type_annotation_cmd
Migrate to py3 style type annotation: sphinx.cmd
This commit is contained in:
commit
05949f8347
@ -14,6 +14,7 @@ import multiprocessing
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
from typing import Any, IO, List
|
||||||
|
|
||||||
from docutils.utils import SystemMessage
|
from docutils.utils import SystemMessage
|
||||||
|
|
||||||
@ -26,13 +27,8 @@ from sphinx.util import Tee, format_exception_cut_frames, save_traceback
|
|||||||
from sphinx.util.console import red, nocolor, color_terminal, terminal_safe # type: ignore
|
from sphinx.util.console import red, nocolor, color_terminal, terminal_safe # type: ignore
|
||||||
from sphinx.util.docutils import docutils_namespace, patch_docutils
|
from sphinx.util.docutils import docutils_namespace, patch_docutils
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, IO, List, Union # NOQA
|
|
||||||
|
|
||||||
|
def handle_exception(app: Sphinx, args: Any, exception: BaseException, stderr: IO = sys.stderr) -> None: # NOQA
|
||||||
def handle_exception(app, args, exception, stderr=sys.stderr):
|
|
||||||
# type: (Sphinx, Any, Union[Exception, KeyboardInterrupt], IO) -> None
|
|
||||||
if args.pdb:
|
if args.pdb:
|
||||||
import pdb
|
import pdb
|
||||||
print(red(__('Exception occurred while building, starting debugger:')),
|
print(red(__('Exception occurred while building, starting debugger:')),
|
||||||
@ -82,8 +78,7 @@ def handle_exception(app, args, exception, stderr=sys.stderr):
|
|||||||
file=stderr)
|
file=stderr)
|
||||||
|
|
||||||
|
|
||||||
def jobs_argument(value):
|
def jobs_argument(value: str) -> int:
|
||||||
# type: (str) -> int
|
|
||||||
"""
|
"""
|
||||||
Special type to handle 'auto' flags passed to 'sphinx-build' via -j flag. Can
|
Special type to handle 'auto' flags passed to 'sphinx-build' via -j flag. Can
|
||||||
be expanded to handle other special scaling requests, such as setting job count
|
be expanded to handle other special scaling requests, such as setting job count
|
||||||
@ -99,8 +94,7 @@ def jobs_argument(value):
|
|||||||
return jobs
|
return jobs
|
||||||
|
|
||||||
|
|
||||||
def get_parser():
|
def get_parser() -> argparse.ArgumentParser:
|
||||||
# type: () -> argparse.ArgumentParser
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
usage='%(prog)s [OPTIONS] SOURCEDIR OUTPUTDIR [FILENAMES...]',
|
usage='%(prog)s [OPTIONS] SOURCEDIR OUTPUTDIR [FILENAMES...]',
|
||||||
epilog=__('For more information, visit <http://sphinx-doc.org/>.'),
|
epilog=__('For more information, visit <http://sphinx-doc.org/>.'),
|
||||||
@ -195,15 +189,13 @@ files can be built by specifying individual filenames.
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def make_main(argv=sys.argv[1:]):
|
def make_main(argv: List[str] = sys.argv[1:]) -> int:
|
||||||
# type: (List[str]) -> int
|
|
||||||
"""Sphinx build "make mode" entry."""
|
"""Sphinx build "make mode" entry."""
|
||||||
from sphinx.cmd import make_mode
|
from sphinx.cmd import make_mode
|
||||||
return make_mode.run_make_mode(argv[1:])
|
return make_mode.run_make_mode(argv[1:])
|
||||||
|
|
||||||
|
|
||||||
def build_main(argv=sys.argv[1:]):
|
def build_main(argv: List[str] = sys.argv[1:]) -> int:
|
||||||
# type: (List[str]) -> int
|
|
||||||
"""Sphinx build "main" command-line entry."""
|
"""Sphinx build "main" command-line entry."""
|
||||||
|
|
||||||
parser = get_parser()
|
parser = get_parser()
|
||||||
@ -288,8 +280,7 @@ def build_main(argv=sys.argv[1:]):
|
|||||||
return 2
|
return 2
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv[1:]):
|
def main(argv: List[str] = sys.argv[1:]) -> int:
|
||||||
# type: (List[str]) -> int
|
|
||||||
sphinx.locale.setlocale(locale.LC_ALL, '')
|
sphinx.locale.setlocale(locale.LC_ALL, '')
|
||||||
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
||||||
|
|
||||||
|
@ -18,16 +18,13 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import List
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.cmd.build import build_main
|
from sphinx.cmd.build import build_main
|
||||||
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
|
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
|
||||||
from sphinx.util.osutil import cd, rmtree
|
from sphinx.util.osutil import cd, rmtree
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import List # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
BUILDERS = [
|
BUILDERS = [
|
||||||
("", "html", "to make standalone HTML files"),
|
("", "html", "to make standalone HTML files"),
|
||||||
@ -58,20 +55,16 @@ BUILDERS = [
|
|||||||
|
|
||||||
|
|
||||||
class Make:
|
class Make:
|
||||||
|
def __init__(self, srcdir: str, builddir: str, opts: List[str]) -> None:
|
||||||
def __init__(self, srcdir, builddir, opts):
|
|
||||||
# type: (str, str, List[str]) -> None
|
|
||||||
self.srcdir = srcdir
|
self.srcdir = srcdir
|
||||||
self.builddir = builddir
|
self.builddir = builddir
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
|
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
|
||||||
|
|
||||||
def builddir_join(self, *comps):
|
def builddir_join(self, *comps: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return path.join(self.builddir, *comps)
|
return path.join(self.builddir, *comps)
|
||||||
|
|
||||||
def build_clean(self):
|
def build_clean(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
srcdir = path.abspath(self.srcdir)
|
srcdir = path.abspath(self.srcdir)
|
||||||
builddir = path.abspath(self.builddir)
|
builddir = path.abspath(self.builddir)
|
||||||
if not path.exists(self.builddir):
|
if not path.exists(self.builddir):
|
||||||
@ -90,8 +83,7 @@ class Make:
|
|||||||
rmtree(self.builddir_join(item))
|
rmtree(self.builddir_join(item))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def build_help(self):
|
def build_help(self) -> None:
|
||||||
# type: () -> None
|
|
||||||
if not color_terminal():
|
if not color_terminal():
|
||||||
nocolor()
|
nocolor()
|
||||||
|
|
||||||
@ -101,8 +93,7 @@ class Make:
|
|||||||
if not osname or os.name == osname:
|
if not osname or os.name == osname:
|
||||||
print(' %s %s' % (blue(bname.ljust(10)), description))
|
print(' %s %s' % (blue(bname.ljust(10)), description))
|
||||||
|
|
||||||
def build_latexpdf(self):
|
def build_latexpdf(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
if self.run_generic_build('latex') > 0:
|
if self.run_generic_build('latex') > 0:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@ -117,8 +108,7 @@ class Make:
|
|||||||
print('Error: Failed to run: %s' % makecmd)
|
print('Error: Failed to run: %s' % makecmd)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def build_latexpdfja(self):
|
def build_latexpdfja(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
if self.run_generic_build('latex') > 0:
|
if self.run_generic_build('latex') > 0:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@ -133,8 +123,7 @@ class Make:
|
|||||||
print('Error: Failed to run: %s' % makecmd)
|
print('Error: Failed to run: %s' % makecmd)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def build_info(self):
|
def build_info(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
if self.run_generic_build('texinfo') > 0:
|
if self.run_generic_build('texinfo') > 0:
|
||||||
return 1
|
return 1
|
||||||
try:
|
try:
|
||||||
@ -144,15 +133,13 @@ class Make:
|
|||||||
print('Error: Failed to run: %s' % self.makecmd)
|
print('Error: Failed to run: %s' % self.makecmd)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def build_gettext(self):
|
def build_gettext(self) -> int:
|
||||||
# type: () -> int
|
|
||||||
dtdir = self.builddir_join('gettext', '.doctrees')
|
dtdir = self.builddir_join('gettext', '.doctrees')
|
||||||
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
|
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def run_generic_build(self, builder, doctreedir=None):
|
def run_generic_build(self, builder: str, doctreedir: str = None) -> int:
|
||||||
# type: (str, str) -> int
|
|
||||||
# compatibility with old Makefile
|
# compatibility with old Makefile
|
||||||
papersize = os.getenv('PAPER', '')
|
papersize = os.getenv('PAPER', '')
|
||||||
opts = self.opts
|
opts = self.opts
|
||||||
@ -168,8 +155,7 @@ class Make:
|
|||||||
return build_main(args + opts)
|
return build_main(args + opts)
|
||||||
|
|
||||||
|
|
||||||
def run_make_mode(args):
|
def run_make_mode(args: List[str]) -> int:
|
||||||
# type: (List[str]) -> int
|
|
||||||
if len(args) < 3:
|
if len(args) < 3:
|
||||||
print('Error: at least 3 arguments (builder, source '
|
print('Error: at least 3 arguments (builder, source '
|
||||||
'dir, build dir) are required.', file=sys.stderr)
|
'dir, build dir) are required.', file=sys.stderr)
|
||||||
|
@ -17,6 +17,7 @@ import time
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from os import path
|
from os import path
|
||||||
|
from typing import Any, Callable, Dict, List, Pattern, Union
|
||||||
|
|
||||||
# try to import readline, unix specific enhancement
|
# try to import readline, unix specific enhancement
|
||||||
try:
|
try:
|
||||||
@ -42,10 +43,6 @@ from sphinx.util.console import ( # type: ignore
|
|||||||
from sphinx.util.osutil import ensuredir
|
from sphinx.util.osutil import ensuredir
|
||||||
from sphinx.util.template import SphinxRenderer
|
from sphinx.util.template import SphinxRenderer
|
||||||
|
|
||||||
if False:
|
|
||||||
# For type annotation
|
|
||||||
from typing import Any, Callable, Dict, List, Pattern, Union # NOQA
|
|
||||||
|
|
||||||
TERM_ENCODING = getattr(sys.stdin, 'encoding', None) # RemovedInSphinx40Warning
|
TERM_ENCODING = getattr(sys.stdin, 'encoding', None) # RemovedInSphinx40Warning
|
||||||
|
|
||||||
EXTENSIONS = OrderedDict([
|
EXTENSIONS = OrderedDict([
|
||||||
@ -84,8 +81,7 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
# function to get input from terminal -- overridden by the test suite
|
# function to get input from terminal -- overridden by the test suite
|
||||||
def term_input(prompt):
|
def term_input(prompt: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
# Important: On windows, readline is not enabled by default. In these
|
# Important: On windows, readline is not enabled by default. In these
|
||||||
# environment, escape sequences have been broken. To avoid the
|
# environment, escape sequences have been broken. To avoid the
|
||||||
@ -100,58 +96,49 @@ class ValidationError(Exception):
|
|||||||
"""Raised for validation errors."""
|
"""Raised for validation errors."""
|
||||||
|
|
||||||
|
|
||||||
def is_path(x):
|
def is_path(x: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
x = path.expanduser(x)
|
x = path.expanduser(x)
|
||||||
if not path.isdir(x):
|
if not path.isdir(x):
|
||||||
raise ValidationError(__("Please enter a valid path name."))
|
raise ValidationError(__("Please enter a valid path name."))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def allow_empty(x):
|
def allow_empty(x: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def nonempty(x):
|
def nonempty(x: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if not x:
|
if not x:
|
||||||
raise ValidationError(__("Please enter some text."))
|
raise ValidationError(__("Please enter some text."))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def choice(*l):
|
def choice(*l: str) -> Callable[[str], str]:
|
||||||
# type: (str) -> Callable[[str], str]
|
def val(x: str) -> str:
|
||||||
def val(x):
|
|
||||||
# type: (str) -> str
|
|
||||||
if x not in l:
|
if x not in l:
|
||||||
raise ValidationError(__('Please enter one of %s.') % ', '.join(l))
|
raise ValidationError(__('Please enter one of %s.') % ', '.join(l))
|
||||||
return x
|
return x
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def boolean(x):
|
def boolean(x: str) -> bool:
|
||||||
# type: (str) -> bool
|
|
||||||
if x.upper() not in ('Y', 'YES', 'N', 'NO'):
|
if x.upper() not in ('Y', 'YES', 'N', 'NO'):
|
||||||
raise ValidationError(__("Please enter either 'y' or 'n'."))
|
raise ValidationError(__("Please enter either 'y' or 'n'."))
|
||||||
return x.upper() in ('Y', 'YES')
|
return x.upper() in ('Y', 'YES')
|
||||||
|
|
||||||
|
|
||||||
def suffix(x):
|
def suffix(x: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
if not (x[0:1] == '.' and len(x) > 1):
|
if not (x[0:1] == '.' and len(x) > 1):
|
||||||
raise ValidationError(__("Please enter a file suffix, "
|
raise ValidationError(__("Please enter a file suffix, "
|
||||||
"e.g. '.rst' or '.txt'."))
|
"e.g. '.rst' or '.txt'."))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def ok(x):
|
def ok(x: str) -> str:
|
||||||
# type: (str) -> str
|
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def term_decode(text):
|
def term_decode(text: Union[bytes, str]) -> str:
|
||||||
# type: (Union[bytes,str]) -> str
|
|
||||||
warnings.warn('term_decode() is deprecated.',
|
warnings.warn('term_decode() is deprecated.',
|
||||||
RemovedInSphinx40Warning, stacklevel=2)
|
RemovedInSphinx40Warning, stacklevel=2)
|
||||||
|
|
||||||
@ -175,8 +162,7 @@ def term_decode(text):
|
|||||||
return text.decode('latin1')
|
return text.decode('latin1')
|
||||||
|
|
||||||
|
|
||||||
def do_prompt(text, default=None, validator=nonempty):
|
def do_prompt(text: str, default: str = None, validator: Callable[[str], Any] = nonempty) -> Union[str, bool]: # NOQA
|
||||||
# type: (str, str, Callable[[str], Any]) -> Union[str, bool]
|
|
||||||
while True:
|
while True:
|
||||||
if default is not None:
|
if default is not None:
|
||||||
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
|
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
|
||||||
@ -201,8 +187,7 @@ def do_prompt(text, default=None, validator=nonempty):
|
|||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
|
def convert_python_source(source: str, rex: Pattern = re.compile(r"[uU]('.*?')")) -> str:
|
||||||
# type: (str, Pattern) -> str
|
|
||||||
# remove Unicode literal prefixes
|
# remove Unicode literal prefixes
|
||||||
warnings.warn('convert_python_source() is deprecated.',
|
warnings.warn('convert_python_source() is deprecated.',
|
||||||
RemovedInSphinx40Warning)
|
RemovedInSphinx40Warning)
|
||||||
@ -210,13 +195,11 @@ def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
|
|||||||
|
|
||||||
|
|
||||||
class QuickstartRenderer(SphinxRenderer):
|
class QuickstartRenderer(SphinxRenderer):
|
||||||
def __init__(self, templatedir):
|
def __init__(self, templatedir: str) -> None:
|
||||||
# type: (str) -> None
|
|
||||||
self.templatedir = templatedir or ''
|
self.templatedir = templatedir or ''
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def render(self, template_name, context):
|
def render(self, template_name: str, context: Dict) -> str:
|
||||||
# type: (str, Dict) -> str
|
|
||||||
user_template = path.join(self.templatedir, path.basename(template_name))
|
user_template = path.join(self.templatedir, path.basename(template_name))
|
||||||
if self.templatedir and path.exists(user_template):
|
if self.templatedir and path.exists(user_template):
|
||||||
return self.render_from_file(user_template, context)
|
return self.render_from_file(user_template, context)
|
||||||
@ -224,8 +207,7 @@ class QuickstartRenderer(SphinxRenderer):
|
|||||||
return super().render(template_name, context)
|
return super().render(template_name, context)
|
||||||
|
|
||||||
|
|
||||||
def ask_user(d):
|
def ask_user(d: Dict) -> None:
|
||||||
# type: (Dict) -> None
|
|
||||||
"""Ask the user for quickstart values missing from *d*.
|
"""Ask the user for quickstart values missing from *d*.
|
||||||
|
|
||||||
Values are:
|
Values are:
|
||||||
@ -367,8 +349,8 @@ directly.'''))
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
def generate(d, overwrite=True, silent=False, templatedir=None):
|
def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir: str = None
|
||||||
# type: (Dict, bool, bool, str) -> None
|
) -> None:
|
||||||
"""Generate project based on values in *d*."""
|
"""Generate project based on values in *d*."""
|
||||||
template = QuickstartRenderer(templatedir=templatedir)
|
template = QuickstartRenderer(templatedir=templatedir)
|
||||||
|
|
||||||
@ -401,8 +383,7 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
|
|||||||
ensuredir(path.join(srcdir, d['dot'] + 'templates'))
|
ensuredir(path.join(srcdir, d['dot'] + 'templates'))
|
||||||
ensuredir(path.join(srcdir, d['dot'] + 'static'))
|
ensuredir(path.join(srcdir, d['dot'] + 'static'))
|
||||||
|
|
||||||
def write_file(fpath, content, newline=None):
|
def write_file(fpath: str, content: str, newline: str = None) -> None:
|
||||||
# type: (str, str, str) -> None
|
|
||||||
if overwrite or not path.isfile(fpath):
|
if overwrite or not path.isfile(fpath):
|
||||||
if 'quiet' not in d:
|
if 'quiet' not in d:
|
||||||
print(__('Creating file %s.') % fpath)
|
print(__('Creating file %s.') % fpath)
|
||||||
@ -460,8 +441,7 @@ where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
|
|||||||
'''))
|
'''))
|
||||||
|
|
||||||
|
|
||||||
def valid_dir(d):
|
def valid_dir(d: Dict) -> bool:
|
||||||
# type: (Dict) -> bool
|
|
||||||
dir = d['path']
|
dir = d['path']
|
||||||
if not path.exists(dir):
|
if not path.exists(dir):
|
||||||
return True
|
return True
|
||||||
@ -490,8 +470,7 @@ def valid_dir(d):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_parser():
|
def get_parser() -> argparse.ArgumentParser:
|
||||||
# type: () -> argparse.ArgumentParser
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
usage='%(prog)s [OPTIONS] <PROJECT_DIR>',
|
usage='%(prog)s [OPTIONS] <PROJECT_DIR>',
|
||||||
epilog=__("For more information, visit <http://sphinx-doc.org/>."),
|
epilog=__("For more information, visit <http://sphinx-doc.org/>."),
|
||||||
@ -572,8 +551,7 @@ Makefile to be used with sphinx-build.
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv[1:]):
|
def main(argv: List[str] = sys.argv[1:]) -> int:
|
||||||
# type: (List[str]) -> int
|
|
||||||
sphinx.locale.setlocale(locale.LC_ALL, '')
|
sphinx.locale.setlocale(locale.LC_ALL, '')
|
||||||
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user