Fix #4783: Sphinx crashed when drives of srcdir and outdir are different

This commit is contained in:
Takeshi KOMIYA 2018-04-01 17:46:44 +09:00
parent eb1e8f937c
commit cff8dc519b
9 changed files with 25 additions and 16 deletions

View File

@ -20,6 +20,8 @@ Bugs fixed
* #4790: autosummary: too wide two column tables in PDF builds
* #4795: Latex customization via ``_templates/longtable.tex_t`` is broken
* #4789: imgconverter: confused by convert.exe of Windows
* #4783: On windows, Sphinx crashed when drives of srcdir and outdir are
different
Testing
--------

View File

@ -40,7 +40,7 @@ from sphinx.util import pycompat # noqa: F401
from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import is_html5_writer_available, directive_helper
from sphinx.util.i18n import find_catalog_source_files
from sphinx.util.osutil import ENOENT, ensuredir
from sphinx.util.osutil import ENOENT, ensuredir, relpath
from sphinx.util.tags import Tags
if False:
@ -342,7 +342,7 @@ class Sphinx(object):
if self.statuscode == 0 and self.builder.epilog:
logger.info('')
logger.info(self.builder.epilog % {
'outdir': path.relpath(self.outdir),
'outdir': relpath(self.outdir),
'project': self.config.project
})
except Exception as err:

View File

@ -19,7 +19,7 @@ from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.util import i18n, logging, status_iterator
from sphinx.util.console import bold # type: ignore
from sphinx.util.i18n import find_catalog
from sphinx.util.osutil import SEP, ensuredir, relative_uri
from sphinx.util.osutil import SEP, ensuredir, relative_uri, relpath
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
parallel_available
@ -237,7 +237,7 @@ class Builder(object):
def cat2relpath(cat):
# type: (CatalogInfo) -> unicode
return path.relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
return relpath(cat.mo_path, self.env.srcdir).replace(path.sep, SEP)
logger.info(bold('building [mo]: ') + message)
for catalog in status_iterator(catalogs, 'writing output... ', "darkgreen",

View File

@ -26,7 +26,7 @@ from sphinx.util import split_index_msg, logging, status_iterator
from sphinx.util.console import bold # type: ignore
from sphinx.util.i18n import find_catalog
from sphinx.util.nodes import extract_messages, traverse_translatable_index
from sphinx.util.osutil import safe_relpath, ensuredir, canon_path
from sphinx.util.osutil import relpath, ensuredir, canon_path
from sphinx.util.tags import Tags
if False:
@ -284,8 +284,7 @@ class MessageCatalogBuilder(I18nBuilder):
if self.config.gettext_location:
# generate "#: file1:line1\n#: file2:line2 ..."
output.write("#: %s\n" % "\n#: ".join( # type: ignore
"%s:%s" % (canon_path(
safe_relpath(source, self.outdir)), line)
"%s:%s" % (canon_path(relpath(source, self.outdir)), line)
for source, line, _ in positions))
if self.config.gettext_uuid:
# generate "# uuid1\n# uuid2\n ..."

View File

@ -38,7 +38,7 @@ from sphinx.util.docutils import sphinx_domains, WarningStream
from sphinx.util.i18n import find_catalog_files
from sphinx.util.matching import compile_matchers
from sphinx.util.nodes import is_translatable
from sphinx.util.osutil import SEP, ensuredir
from sphinx.util.osutil import SEP, ensuredir, relpath
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable
@ -346,7 +346,7 @@ class BuildEnvironment(object):
*filename* should be absolute or relative to the source directory.
"""
if filename.startswith(self.srcdir):
filename = os.path.relpath(filename, self.srcdir)
filename = relpath(filename, self.srcdir)
for suffix in self.config.source_suffix:
if filename.endswith(suffix):
return filename[:-len(suffix)]

View File

@ -30,7 +30,7 @@ from sphinx.locale import _
from sphinx.util import force_decode, logging
from sphinx.util.console import bold # type: ignore
from sphinx.util.nodes import set_source_info
from sphinx.util.osutil import fs_encoding
from sphinx.util.osutil import fs_encoding, relpath
if False:
# For type annotation
@ -372,7 +372,7 @@ Doctest summary
"""Try to get the file which actually contains the doctest, not the
filename of the document it's included in."""
try:
filename = path.relpath(node.source, self.env.srcdir)\
filename = relpath(node.source, self.env.srcdir)\
.rsplit(':docstring of ', maxsplit=1)[0]
except Exception:
filename = self.env.doc2path(docname, base=None)

View File

@ -23,6 +23,7 @@ from sphinx.builders.latex import LaTeXBuilder
from sphinx.ext.autodoc import AutoDirective
from sphinx.pycode import ModuleAnalyzer
from sphinx.testing.path import path
from sphinx.util.osutil import relpath
if False:
from typing import List # NOQA
@ -184,7 +185,7 @@ def find_files(root, suffix=None):
dirpath = path(dirpath)
for f in [f for f in files if not suffix or f.endswith(suffix)]:
fpath = dirpath / f
yield os.path.relpath(fpath, root)
yield relpath(fpath, root)
def strip_escseq(text):

View File

@ -22,7 +22,7 @@ from babel.messages.pofile import read_po
from sphinx.errors import SphinxError
from sphinx.util import logging
from sphinx.util.osutil import SEP, walk
from sphinx.util.osutil import SEP, relpath, walk
logger = logging.getLogger(__name__)
@ -96,7 +96,7 @@ def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction):
domain = find_catalog(docname, compaction)
files = [gettext.find(domain, path.join(srcdir, dir_), [lang]) # type: ignore
for dir_ in locale_dirs]
files = [path.relpath(f, srcdir) for f in files if f] # type: ignore
files = [relpath(f, srcdir) for f in files if f] # type: ignore
return files # type: ignore
@ -137,7 +137,7 @@ def find_catalog_source_files(locale_dirs, locale, domains=None, gettext_compact
filenames = [f for f in filenames if f.endswith('.po')]
for filename in filenames:
base = path.splitext(filename)[0]
domain = path.relpath(path.join(dirpath, base), base_dir)
domain = relpath(path.join(dirpath, base), base_dir)
if gettext_compact and path.sep in domain:
domain = path.split(domain)[0]
domain = domain.replace(path.sep, SEP)

View File

@ -205,14 +205,21 @@ def ustrftime(format, *args):
return r.encode().decode('unicode-escape')
def safe_relpath(path, start=None):
def relpath(path, start=os.curdir):
# type: (unicode, unicode) -> unicode
"""Return a relative filepath to *path* either from the current directory or
from an optional *start* directory.
This is an alternative of ``os.path.relpath()``. This returns original path
if *path* and *start* are on different drives (for Windows platform).
"""
try:
return os.path.relpath(path, start)
except ValueError:
return path
safe_relpath = relpath # for compatibility
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() # type: unicode