mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Deprecate and drop internal use of force_decode()
In the Python 3 only code base, this function is no longer necessary. The type of values is well understood and deliberate. Code should avoid arbitrary mixing of bytes & str. By removing force_decode() calls from docstring values, can deprecate the now unused 'encoding' arguments to various autodoc methods.
This commit is contained in:
parent
6b0e0fa3eb
commit
555960d668
5
CHANGES
5
CHANGES
@ -19,12 +19,17 @@ Incompatible changes
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
* The ``encoding`` argument of ``autodoc.Documenter.get_doc()``,
|
||||
``autodoc.DocstringSignatureMixin.get_doc()``,
|
||||
``autodoc.DocstringSignatureMixin._find_signature()``, and
|
||||
``autodoc.ClassDocumenter.get_doc()`` are deprecated.
|
||||
* The ``suffix`` argument of ``env.doc2path()`` is deprecated.
|
||||
* The string style ``base`` argument of ``env.doc2path()`` is deprecated.
|
||||
* ``sphinx.application.Sphinx._setting_up_extension``
|
||||
* ``sphinx.ext.config.check_unicode()``
|
||||
* ``sphinx.ext.doctest.doctest_encode()``
|
||||
* ``sphinx.testing.util.remove_unicode_literal()``
|
||||
* ``sphinx.util.force_decode()``
|
||||
* ``sphinx.util.get_matching_docs()`` is deprecated
|
||||
* ``sphinx.util.osutil.walk()``
|
||||
* ``sphinx.util.pycompat.u``
|
||||
|
@ -123,6 +123,14 @@ The following is a list of deprecated interfaces.
|
||||
- (will be) Removed
|
||||
- Alternatives
|
||||
|
||||
* - ``encoding`` argument of ``autodoc.Documenter.get_doc()``,
|
||||
``autodoc.DocstringSignatureMixin.get_doc()``,
|
||||
``autodoc.DocstringSignatureMixin._find_signature()``, and
|
||||
``autodoc.ClassDocumenter.get_doc()``
|
||||
- 2.0
|
||||
- 4.0
|
||||
- N/A
|
||||
|
||||
* - ``suffix`` argument of ``BuildEnvironment.doc2path()``
|
||||
- 2.0
|
||||
- 4.0
|
||||
@ -148,6 +156,11 @@ The following is a list of deprecated interfaces.
|
||||
- 4.0
|
||||
- N/A
|
||||
|
||||
* - ``sphinx.util.force_decode()``
|
||||
- 2.0
|
||||
- 4.0
|
||||
- N/A
|
||||
|
||||
* - ``sphinx.util.get_matching_docs()``
|
||||
- 2.0
|
||||
- 4.0
|
||||
|
@ -15,7 +15,6 @@ import re
|
||||
from os import path
|
||||
|
||||
from docutils import nodes
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import package_dir
|
||||
@ -23,7 +22,7 @@ from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.config import string_classes
|
||||
from sphinx.environment.adapters.indexentries import IndexEntries
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import force_decode, logging
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
from sphinx.util.template import SphinxRenderer
|
||||
@ -113,15 +112,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
item = section_template % {'title': indexcls.localname,
|
||||
'ref': '%s.html' % indexname}
|
||||
sections.append(' ' * 4 * 4 + item)
|
||||
# sections may be unicode strings or byte strings, we have to make sure
|
||||
# they are all unicode strings before joining them
|
||||
new_sections = []
|
||||
for section in sections:
|
||||
if not isinstance(section, text_type):
|
||||
new_sections.append(force_decode(section, None))
|
||||
else:
|
||||
new_sections.append(section)
|
||||
sections = u'\n'.join(new_sections) # type: ignore
|
||||
sections = '\n'.join(sections) # type: ignore
|
||||
|
||||
# keywords
|
||||
keywords = []
|
||||
@ -182,7 +173,6 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
def write_toc(self, node, indentlevel=4):
|
||||
# type: (nodes.Node, int) -> List[unicode]
|
||||
# XXX this should return a Unicode string, not a bytestring
|
||||
parts = [] # type: List[unicode]
|
||||
if self.isdocnode(node):
|
||||
refnode = node.children[0][0]
|
||||
@ -202,7 +192,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
title = htmlescape(node.astext()).replace('"', '"')
|
||||
item = section_template % {'title': title, 'ref': link}
|
||||
item = u' ' * 4 * indentlevel + item
|
||||
parts.append(item.encode('ascii', 'xmlcharrefreplace'))
|
||||
parts.append(item.encode('ascii', 'xmlcharrefreplace').decode())
|
||||
elif isinstance(node, nodes.bullet_list):
|
||||
for subnode in node:
|
||||
parts.extend(self.write_toc(subnode, indentlevel))
|
||||
|
@ -21,13 +21,13 @@ from docutils.statemachine import ViewList
|
||||
from six import text_type, string_types
|
||||
|
||||
import sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||
from sphinx.ext.autodoc.importer import mock, import_object, get_object_members
|
||||
from sphinx.ext.autodoc.importer import _MockImporter # to keep compatibility # NOQA
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.pycode import ModuleAnalyzer, PycodeError
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import rpartition, force_decode
|
||||
from sphinx.util import rpartition
|
||||
from sphinx.util.docstrings import prepare_docstring
|
||||
from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \
|
||||
safe_getattr, object_description, is_builtin_class_method, \
|
||||
@ -438,16 +438,14 @@ class Documenter:
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (unicode, int) -> List[List[unicode]]
|
||||
"""Decode and return lines of the docstring(s) for the object."""
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
% self.__class__.__name__,
|
||||
RemovedInSphinx40Warning)
|
||||
docstring = getdoc(self.object, self.get_attr,
|
||||
self.env.config.autodoc_inherit_docstrings)
|
||||
# make sure we have Unicode docstrings, then sanitize and split
|
||||
# into lines
|
||||
if isinstance(docstring, text_type):
|
||||
if docstring:
|
||||
return [prepare_docstring(docstring, ignore)]
|
||||
elif isinstance(docstring, str): # this will not trigger on Py3
|
||||
return [prepare_docstring(force_decode(docstring, encoding),
|
||||
ignore)]
|
||||
# ... else it is something strange, let's ignore it
|
||||
return []
|
||||
|
||||
def process_doc(self, docstrings):
|
||||
@ -491,8 +489,7 @@ class Documenter:
|
||||
|
||||
# add content from docstrings
|
||||
if not no_docstring:
|
||||
encoding = self.analyzer and self.analyzer.encoding
|
||||
docstrings = self.get_doc(encoding)
|
||||
docstrings = self.get_doc()
|
||||
if not docstrings:
|
||||
# append at least a dummy docstring, so that the event
|
||||
# autodoc-process-docstring is fired and can add some
|
||||
@ -926,7 +923,11 @@ class DocstringSignatureMixin:
|
||||
|
||||
def _find_signature(self, encoding=None):
|
||||
# type: (unicode) -> Tuple[str, str]
|
||||
docstrings = self.get_doc(encoding)
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s._find_signature() is "
|
||||
"deprecated." % self.__class__.__name__,
|
||||
RemovedInSphinx40Warning)
|
||||
docstrings = self.get_doc()
|
||||
self._new_docstrings = docstrings[:]
|
||||
result = None
|
||||
for i, doclines in enumerate(docstrings):
|
||||
@ -955,10 +956,14 @@ class DocstringSignatureMixin:
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (unicode, int) -> List[List[unicode]]
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
% self.__class__.__name__,
|
||||
RemovedInSphinx40Warning)
|
||||
lines = getattr(self, '_new_docstrings', None)
|
||||
if lines is not None:
|
||||
return lines
|
||||
return Documenter.get_doc(self, encoding, ignore) # type: ignore
|
||||
return Documenter.get_doc(self, None, ignore) # type: ignore
|
||||
|
||||
def format_signature(self):
|
||||
# type: () -> unicode
|
||||
@ -1119,6 +1124,10 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (unicode, int) -> List[List[unicode]]
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
% self.__class__.__name__,
|
||||
RemovedInSphinx40Warning)
|
||||
lines = getattr(self, '_new_docstrings', None)
|
||||
if lines is not None:
|
||||
return lines
|
||||
@ -1154,14 +1163,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
docstrings = [initdocstring]
|
||||
else:
|
||||
docstrings.append(initdocstring)
|
||||
doc = []
|
||||
for docstring in docstrings:
|
||||
if isinstance(docstring, text_type):
|
||||
doc.append(prepare_docstring(docstring, ignore))
|
||||
elif isinstance(docstring, str): # this will not trigger on Py3
|
||||
doc.append(prepare_docstring(force_decode(docstring, encoding),
|
||||
ignore))
|
||||
return doc
|
||||
return [prepare_docstring(docstring, ignore) for docstring in docstrings]
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
# type: (Any, bool) -> None
|
||||
|
@ -44,13 +44,10 @@ from hashlib import md5
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
from six import text_type
|
||||
|
||||
import sphinx
|
||||
from sphinx.ext.graphviz import render_dot_html, render_dot_latex, \
|
||||
render_dot_texinfo, figure_wrapper
|
||||
from sphinx.pycode import ModuleAnalyzer
|
||||
from sphinx.util import force_decode
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
|
||||
if False:
|
||||
@ -187,10 +184,7 @@ class InheritanceGraph:
|
||||
tooltip = None
|
||||
try:
|
||||
if cls.__doc__:
|
||||
enc = ModuleAnalyzer.for_module(cls.__module__).encoding
|
||||
doc = cls.__doc__.strip().split("\n")[0]
|
||||
if not isinstance(doc, text_type):
|
||||
doc = force_decode(doc, enc)
|
||||
if doc:
|
||||
tooltip = '"%s"' % doc.replace('"', '\\"')
|
||||
except Exception: # might raise AttributeError for strange classes
|
||||
|
@ -258,7 +258,7 @@ def save_traceback(app):
|
||||
last_msgs = ''
|
||||
if app is not None:
|
||||
last_msgs = '\n'.join(
|
||||
'# %s' % strip_colors(force_decode(s, 'utf-8')).strip() # type: ignore
|
||||
'# %s' % strip_colors(s).strip()
|
||||
for s in app.messagelog)
|
||||
os.write(fd, (_DEBUG_HEADER %
|
||||
(sphinx.__display_version__,
|
||||
@ -458,6 +458,8 @@ def parselinenos(spec, total):
|
||||
def force_decode(string, encoding):
|
||||
# type: (unicode, unicode) -> unicode
|
||||
"""Forcibly get a unicode string out of a bytestring."""
|
||||
warnings.warn('force_decode() is deprecated.',
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
if isinstance(string, bytes):
|
||||
try:
|
||||
if encoding:
|
||||
|
@ -286,13 +286,13 @@ def test_format_signature():
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_get_doc():
|
||||
def getdocl(objtype, obj, encoding=None):
|
||||
def getdocl(objtype, obj):
|
||||
inst = app.registry.documenters[objtype](directive, 'tmp')
|
||||
inst.object = obj
|
||||
inst.objpath = [obj.__name__]
|
||||
inst.doc_as_attr = False
|
||||
inst.format_signature() # handle docstring signatures!
|
||||
ds = inst.get_doc(encoding)
|
||||
ds = inst.get_doc()
|
||||
# for testing purposes, concat them and strip the empty line at the end
|
||||
res = sum(ds, [])[:-1]
|
||||
print(res)
|
||||
|
Loading…
Reference in New Issue
Block a user