mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #5398 from tk0miya/drop_py2_2
Drop branches for sys.version_info < (3, 4)
This commit is contained in:
commit
bc61764319
@ -62,9 +62,7 @@ default_settings = {
|
||||
|
||||
# This is increased every time an environment attribute is added
|
||||
# or changed to properly invalidate pickle files.
|
||||
#
|
||||
# NOTE: increase base version by 2 to have distinct numbers for Py2 and 3
|
||||
ENV_VERSION = 54 + (sys.version_info[0] - 2)
|
||||
ENV_VERSION = 56
|
||||
|
||||
# config status
|
||||
CONFIG_OK = 1
|
||||
|
@ -234,12 +234,6 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None):
|
||||
# the members directly defined in the class
|
||||
obj_dict = attrgetter(subject, '__dict__', {})
|
||||
|
||||
# Py34 doesn't have enum members in __dict__.
|
||||
if sys.version_info[:2] == (3, 4) and isenumclass(subject):
|
||||
obj_dict = dict(obj_dict)
|
||||
for name, value in subject.__members__.items():
|
||||
obj_dict[name] = value
|
||||
|
||||
members = {} # type: Dict[str, Attribute]
|
||||
|
||||
# enum members
|
||||
|
@ -9,9 +9,7 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from six import PY2, iteritems
|
||||
from six import iteritems
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
@ -435,34 +433,26 @@ def _skip_member(app, what, name, obj, skip, options):
|
||||
if name != '__weakref__' and has_doc and is_member:
|
||||
cls_is_owner = False
|
||||
if what == 'class' or what == 'exception':
|
||||
if PY2:
|
||||
cls = getattr(obj, 'im_class', getattr(obj, '__objclass__',
|
||||
None))
|
||||
cls_is_owner = (cls and hasattr(cls, name) and
|
||||
name in cls.__dict__)
|
||||
elif sys.version_info >= (3, 3):
|
||||
qualname = getattr(obj, '__qualname__', '')
|
||||
cls_path, _, _ = qualname.rpartition('.')
|
||||
if cls_path:
|
||||
try:
|
||||
if '.' in cls_path:
|
||||
import importlib
|
||||
import functools
|
||||
qualname = getattr(obj, '__qualname__', '')
|
||||
cls_path, _, _ = qualname.rpartition('.')
|
||||
if cls_path:
|
||||
try:
|
||||
if '.' in cls_path:
|
||||
import importlib
|
||||
import functools
|
||||
|
||||
mod = importlib.import_module(obj.__module__)
|
||||
mod_path = cls_path.split('.')
|
||||
cls = functools.reduce(getattr, mod_path, mod)
|
||||
else:
|
||||
cls = obj.__globals__[cls_path]
|
||||
except Exception:
|
||||
cls_is_owner = False
|
||||
mod = importlib.import_module(obj.__module__)
|
||||
mod_path = cls_path.split('.')
|
||||
cls = functools.reduce(getattr, mod_path, mod)
|
||||
else:
|
||||
cls_is_owner = (cls and hasattr(cls, name) and
|
||||
name in cls.__dict__)
|
||||
else:
|
||||
cls = obj.__globals__[cls_path]
|
||||
except Exception:
|
||||
cls_is_owner = False
|
||||
else:
|
||||
cls_is_owner = (cls and hasattr(cls, name) and # type: ignore
|
||||
name in cls.__dict__)
|
||||
else:
|
||||
cls_is_owner = True
|
||||
cls_is_owner = False
|
||||
|
||||
if what == 'module' or cls_is_owner:
|
||||
is_init = (name == '__init__')
|
||||
|
@ -677,8 +677,7 @@ def xmlname_checker():
|
||||
[u'\u2C00', u'\u2FEF'], [u'\u3001', u'\uD7FF'], [u'\uF900', u'\uFDCF'],
|
||||
[u'\uFDF0', u'\uFFFD']]
|
||||
|
||||
if sys.version_info.major == 3:
|
||||
name_start_chars.append([u'\U00010000', u'\U000EFFFF'])
|
||||
name_start_chars.append([u'\U00010000', u'\U000EFFFF'])
|
||||
|
||||
name_chars = [
|
||||
u"\\-", u"\\.", [u'0', u'9'], u'\u00B7', [u'\u0300', u'\u036F'],
|
||||
|
@ -648,108 +648,6 @@ class Signature(object):
|
||||
return qualname
|
||||
|
||||
|
||||
if sys.version_info >= (3, 5):
|
||||
_getdoc = inspect.getdoc
|
||||
else:
|
||||
# code copied from the inspect.py module of the standard library
|
||||
# of Python 3.5
|
||||
|
||||
def _findclass(func):
|
||||
# type: (Any) -> Any
|
||||
cls = sys.modules.get(func.__module__)
|
||||
if cls is None:
|
||||
return None
|
||||
if hasattr(func, 'im_class'):
|
||||
cls = func.im_class
|
||||
else:
|
||||
for name in func.__qualname__.split('.')[:-1]:
|
||||
cls = getattr(cls, name)
|
||||
if not inspect.isclass(cls):
|
||||
return None
|
||||
return cls
|
||||
|
||||
def _finddoc(obj):
|
||||
# type: (Any) -> unicode
|
||||
if inspect.isclass(obj):
|
||||
for base in obj.__mro__:
|
||||
if base is not object:
|
||||
try:
|
||||
doc = base.__doc__
|
||||
except AttributeError:
|
||||
continue
|
||||
if doc is not None:
|
||||
return doc
|
||||
return None
|
||||
|
||||
if inspect.ismethod(obj) and getattr(obj, '__self__', None):
|
||||
name = obj.__func__.__name__
|
||||
self = obj.__self__
|
||||
if (inspect.isclass(self) and
|
||||
getattr(getattr(self, name, None), '__func__')
|
||||
is obj.__func__):
|
||||
# classmethod
|
||||
cls = self
|
||||
else:
|
||||
cls = self.__class__
|
||||
elif inspect.isfunction(obj) or inspect.ismethod(obj):
|
||||
name = obj.__name__
|
||||
cls = _findclass(obj)
|
||||
if cls is None or getattr(cls, name) != obj:
|
||||
return None
|
||||
elif inspect.isbuiltin(obj):
|
||||
name = obj.__name__
|
||||
self = obj.__self__
|
||||
if (inspect.isclass(self) and
|
||||
self.__qualname__ + '.' + name == obj.__qualname__):
|
||||
# classmethod
|
||||
cls = self
|
||||
else:
|
||||
cls = self.__class__
|
||||
# Should be tested before isdatadescriptor().
|
||||
elif isinstance(obj, property):
|
||||
func = obj.fget
|
||||
name = func.__name__
|
||||
cls = _findclass(func)
|
||||
if cls is None or getattr(cls, name) is not obj:
|
||||
return None
|
||||
elif inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj):
|
||||
name = obj.__name__
|
||||
cls = obj.__objclass__
|
||||
if getattr(cls, name) is not obj:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
for base in cls.__mro__:
|
||||
try:
|
||||
doc = getattr(base, name).__doc__
|
||||
except AttributeError:
|
||||
continue
|
||||
if doc is not None:
|
||||
return doc
|
||||
return None
|
||||
|
||||
def _getdoc(object):
|
||||
# type: (Any) -> unicode
|
||||
"""Get the documentation string for an object.
|
||||
|
||||
All tabs are expanded to spaces. To clean up docstrings that are
|
||||
indented to line up with blocks of code, any whitespace than can be
|
||||
uniformly removed from the second line onwards is removed."""
|
||||
try:
|
||||
doc = object.__doc__
|
||||
except AttributeError:
|
||||
return None
|
||||
if doc is None:
|
||||
try:
|
||||
doc = _finddoc(object)
|
||||
except (AttributeError, TypeError):
|
||||
return None
|
||||
if not isinstance(doc, str):
|
||||
return None
|
||||
return inspect.cleandoc(doc)
|
||||
|
||||
|
||||
def getdoc(obj, attrgetter=safe_getattr, allow_inherited=False):
|
||||
# type: (Any, Callable, bool) -> unicode
|
||||
"""Get the docstring for the object.
|
||||
@ -763,6 +661,6 @@ def getdoc(obj, attrgetter=safe_getattr, allow_inherited=False):
|
||||
if ispartial(obj) and doc == obj.__class__.__doc__:
|
||||
return getdoc(obj.func)
|
||||
elif doc is None and allow_inherited:
|
||||
doc = _getdoc(obj)
|
||||
doc = inspect.getdoc(obj)
|
||||
|
||||
return doc
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
import docutils
|
||||
import pytest
|
||||
@ -22,13 +21,6 @@ pytest_plugins = 'sphinx.testing.fixtures'
|
||||
# Exclude 'roots' dirs for pytest test collector
|
||||
collect_ignore = ['roots']
|
||||
|
||||
# Disable Python version-specific
|
||||
if sys.version_info < (3,):
|
||||
collect_ignore += ['py3']
|
||||
|
||||
if sys.version_info < (3, 5):
|
||||
collect_ignore += ['py35']
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def rootdir():
|
||||
|
@ -1,26 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
py3/test_util_inspect
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests util.inspect functions.
|
||||
|
||||
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from sphinx.util import inspect
|
||||
|
||||
|
||||
def test_Signature_keyword_only_arguments():
|
||||
def func1(arg1, arg2, *, arg3=None, arg4=None):
|
||||
pass
|
||||
|
||||
def func2(*, arg3, arg4):
|
||||
pass
|
||||
|
||||
sig = inspect.Signature(func1).format_args()
|
||||
assert sig == '(arg1, arg2, *, arg3=None, arg4=None)'
|
||||
|
||||
sig = inspect.Signature(func2).format_args()
|
||||
assert sig == '(*, arg3, arg4)'
|
@ -1,348 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_autodoc
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Test the autodoc extension. This tests mainly the Documenters; the auto
|
||||
directives are tested in a test source file translated by test_build.
|
||||
|
||||
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
# "raises" imported for usage by autodoc
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
import six
|
||||
from docutils.statemachine import ViewList
|
||||
from six import StringIO
|
||||
|
||||
from sphinx.ext.autodoc import FunctionDocumenter, ALL, Options
|
||||
from sphinx.testing.util import SphinxTestApp, Struct
|
||||
from sphinx.util import logging
|
||||
from sphinx.util import save_traceback # NOQA
|
||||
|
||||
app = None
|
||||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def setup_module(rootdir, sphinx_test_tempdir):
|
||||
global app
|
||||
srcdir = sphinx_test_tempdir / 'autodoc-root'
|
||||
if not srcdir.exists():
|
||||
(rootdir / 'test-root').copytree(srcdir)
|
||||
app = SphinxTestApp(srcdir=srcdir)
|
||||
app.builder.env.app = app
|
||||
app.builder.env.temp_data['docname'] = 'dummy'
|
||||
app.connect('autodoc-process-docstring', process_docstring)
|
||||
app.connect('autodoc-process-signature', process_signature)
|
||||
app.connect('autodoc-skip-member', skip_member)
|
||||
yield
|
||||
app.cleanup()
|
||||
|
||||
|
||||
directive = options = None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_test():
|
||||
global options, directive
|
||||
global processed_docstrings, processed_signatures
|
||||
|
||||
options = Options(
|
||||
inherited_members = False,
|
||||
undoc_members = False,
|
||||
private_members = False,
|
||||
special_members = False,
|
||||
imported_members = False,
|
||||
show_inheritance = False,
|
||||
noindex = False,
|
||||
annotation = None,
|
||||
synopsis = '',
|
||||
platform = '',
|
||||
deprecated = False,
|
||||
members = [],
|
||||
member_order = 'alphabetic',
|
||||
exclude_members = set(),
|
||||
)
|
||||
|
||||
directive = Struct(
|
||||
env = app.builder.env,
|
||||
genopt = options,
|
||||
result = ViewList(),
|
||||
filename_set = set(),
|
||||
)
|
||||
|
||||
processed_docstrings = []
|
||||
processed_signatures = []
|
||||
|
||||
|
||||
processed_docstrings = []
|
||||
processed_signatures = []
|
||||
|
||||
|
||||
def process_docstring(app, what, name, obj, options, lines):
|
||||
processed_docstrings.append((what, name))
|
||||
if name == 'bar':
|
||||
lines.extend(['42', ''])
|
||||
|
||||
|
||||
def process_signature(app, what, name, obj, options, args, retann):
|
||||
processed_signatures.append((what, name))
|
||||
if name == 'bar':
|
||||
return '42', None
|
||||
|
||||
|
||||
def skip_member(app, what, name, obj, skip, options):
|
||||
if name in ('__special1__', '__special2__'):
|
||||
return skip
|
||||
if name.startswith('_'):
|
||||
return True
|
||||
if name == 'skipmeth':
|
||||
return True
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_generate():
|
||||
logging.setup(app, app._status, app._warning)
|
||||
|
||||
def assert_warns(warn_str, objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
assert len(directive.result) == 0, directive.result
|
||||
assert warn_str in app._warning.getvalue()
|
||||
app._warning.truncate(0)
|
||||
|
||||
def assert_works(objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
assert directive.result
|
||||
# print '\n'.join(directive.result)
|
||||
assert app._warning.getvalue() == ''
|
||||
del directive.result[:]
|
||||
|
||||
def assert_processes(items, objtype, name, **kw):
|
||||
del processed_docstrings[:]
|
||||
del processed_signatures[:]
|
||||
assert_works(objtype, name, **kw)
|
||||
assert set(processed_docstrings) | set(processed_signatures) == set(items)
|
||||
|
||||
def assert_result_contains(item, objtype, name, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.generate(**kw)
|
||||
# print '\n'.join(directive.result)
|
||||
assert app._warning.getvalue() == ''
|
||||
assert item in directive.result
|
||||
del directive.result[:]
|
||||
|
||||
def assert_order(items, objtype, name, member_order, **kw):
|
||||
inst = app.registry.documenters[objtype](directive, name)
|
||||
inst.options.member_order = member_order
|
||||
inst.generate(**kw)
|
||||
assert app._warning.getvalue() == ''
|
||||
items = list(reversed(items))
|
||||
lineiter = iter(directive.result)
|
||||
# for line in directive.result:
|
||||
# if line.strip():
|
||||
# print repr(line)
|
||||
while items:
|
||||
item = items.pop()
|
||||
for line in lineiter:
|
||||
if line == item:
|
||||
break
|
||||
else: # ran out of items!
|
||||
assert False, ('item %r not found in result or not in the '
|
||||
' correct order' % item)
|
||||
del directive.result[:]
|
||||
|
||||
options.members = []
|
||||
|
||||
# no module found?
|
||||
assert_warns("import for autodocumenting 'foobar'",
|
||||
'function', 'foobar', more_content=None)
|
||||
# importing
|
||||
assert_warns("failed to import module 'test_foobar'",
|
||||
'module', 'test_foobar', more_content=None)
|
||||
# attributes missing
|
||||
assert_warns("failed to import function 'foobar' from module 'util'",
|
||||
'function', 'util.foobar', more_content=None)
|
||||
# method missing
|
||||
assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc_py35';",
|
||||
'method', 'test_autodoc_py35.Class.foobar', more_content=None)
|
||||
|
||||
# test auto and given content mixing
|
||||
directive.env.ref_context['py:module'] = 'test_autodoc_py35'
|
||||
assert_result_contains(' Function.', 'method', 'Class.meth')
|
||||
add_content = ViewList()
|
||||
add_content.append('Content.', '', 0)
|
||||
assert_result_contains(' Function.', 'method',
|
||||
'Class.meth', more_content=add_content)
|
||||
assert_result_contains(' Content.', 'method',
|
||||
'Class.meth', more_content=add_content)
|
||||
|
||||
# test check_module
|
||||
inst = FunctionDocumenter(directive, 'save_traceback')
|
||||
inst.generate(check_module=True)
|
||||
assert len(directive.result) == 0
|
||||
|
||||
# assert that exceptions can be documented
|
||||
assert_works('exception', 'test_autodoc_py35.CustomEx', all_members=True)
|
||||
assert_works('exception', 'test_autodoc_py35.CustomEx')
|
||||
|
||||
# test diverse inclusion settings for members
|
||||
should = [('class', 'test_autodoc_py35.Class')]
|
||||
assert_processes(should, 'class', 'Class')
|
||||
should.extend([('method', 'test_autodoc_py35.Class.meth')])
|
||||
options.members = ['meth']
|
||||
options.exclude_members = set(['excludemeth'])
|
||||
assert_processes(should, 'class', 'Class')
|
||||
should.extend([('attribute', 'test_autodoc_py35.Class.prop'),
|
||||
('attribute', 'test_autodoc_py35.Class.descr'),
|
||||
('attribute', 'test_autodoc_py35.Class.attr'),
|
||||
('attribute', 'test_autodoc_py35.Class.docattr'),
|
||||
('attribute', 'test_autodoc_py35.Class.udocattr'),
|
||||
('attribute', 'test_autodoc_py35.Class.mdocattr'),
|
||||
('attribute', 'test_autodoc_py35.Class.inst_attr_comment'),
|
||||
('attribute', 'test_autodoc_py35.Class.inst_attr_inline'),
|
||||
('attribute', 'test_autodoc_py35.Class.inst_attr_string'),
|
||||
('method', 'test_autodoc_py35.Class.moore'),
|
||||
])
|
||||
if six.PY3 and sys.version_info[:2] >= (3, 5):
|
||||
should.extend([
|
||||
('method', 'test_autodoc_py35.Class.do_coroutine'),
|
||||
])
|
||||
options.members = ALL
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.undoc_members = True
|
||||
should.extend((('attribute', 'test_autodoc_py35.Class.skipattr'),
|
||||
('method', 'test_autodoc_py35.Class.undocmeth'),
|
||||
('method', 'test_autodoc_py35.Class.roger')))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.inherited_members = True
|
||||
should.append(('method', 'test_autodoc_py35.Class.inheritedmeth'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
|
||||
# test special members
|
||||
options.special_members = ['__special1__']
|
||||
should.append(('method', 'test_autodoc_py35.Class.__special1__'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.special_members = ALL
|
||||
should.append(('method', 'test_autodoc_py35.Class.__special2__'))
|
||||
assert_processes(should, 'class', 'Class')
|
||||
options.special_members = False
|
||||
|
||||
|
||||
# --- generate fodder ------------
|
||||
__all__ = ['Class']
|
||||
|
||||
#: documentation for the integer
|
||||
integer = 1
|
||||
|
||||
|
||||
class CustomEx(Exception):
|
||||
"""My custom exception."""
|
||||
|
||||
def f(self):
|
||||
"""Exception method."""
|
||||
|
||||
|
||||
class CustomDataDescriptor(object):
|
||||
"""Descriptor class docstring."""
|
||||
|
||||
def __init__(self, doc):
|
||||
self.__doc__ = doc
|
||||
|
||||
def __get__(self, obj, type=None):
|
||||
if obj is None:
|
||||
return self
|
||||
return 42
|
||||
|
||||
def meth(self):
|
||||
"""Function."""
|
||||
return "The Answer"
|
||||
|
||||
|
||||
def _funky_classmethod(name, b, c, d, docstring=None):
|
||||
"""Generates a classmethod for a class from a template by filling out
|
||||
some arguments."""
|
||||
def template(cls, a, b, c, d=4, e=5, f=6):
|
||||
return a, b, c, d, e, f
|
||||
from functools import partial
|
||||
function = partial(template, b=b, c=c, d=d)
|
||||
function.__name__ = name
|
||||
function.__doc__ = docstring
|
||||
return classmethod(function)
|
||||
|
||||
|
||||
class Base(object):
|
||||
def inheritedmeth(self):
|
||||
"""Inherited function."""
|
||||
|
||||
|
||||
if six.PY3 and sys.version_info[:2] >= (3, 5):
|
||||
async def _other_coro_func():
|
||||
return "run"
|
||||
|
||||
|
||||
class Class(Base):
|
||||
"""Class to document."""
|
||||
|
||||
descr = CustomDataDescriptor("Descriptor instance docstring.")
|
||||
|
||||
def meth(self):
|
||||
"""Function."""
|
||||
|
||||
def undocmeth(self):
|
||||
pass
|
||||
|
||||
def skipmeth(self):
|
||||
"""Method that should be skipped."""
|
||||
|
||||
def excludemeth(self):
|
||||
"""Method that should be excluded."""
|
||||
|
||||
# should not be documented
|
||||
skipattr = 'foo'
|
||||
|
||||
#: should be documented -- süß
|
||||
attr = 'bar'
|
||||
|
||||
@property
|
||||
def prop(self):
|
||||
"""Property."""
|
||||
|
||||
docattr = 'baz'
|
||||
"""should likewise be documented -- süß"""
|
||||
|
||||
udocattr = 'quux'
|
||||
u"""should be documented as well - süß"""
|
||||
|
||||
# initialized to any class imported from another module
|
||||
mdocattr = StringIO()
|
||||
"""should be documented as well - süß"""
|
||||
|
||||
roger = _funky_classmethod("roger", 2, 3, 4)
|
||||
|
||||
moore = _funky_classmethod("moore", 9, 8, 7,
|
||||
docstring="moore(a, e, f) -> happiness")
|
||||
|
||||
def __init__(self, arg):
|
||||
self.inst_attr_inline = None #: an inline documented instance attr
|
||||
#: a documented instance attribute
|
||||
self.inst_attr_comment = None
|
||||
self.inst_attr_string = None
|
||||
"""a documented instance attribute"""
|
||||
|
||||
def __special1__(self):
|
||||
"""documented special method"""
|
||||
|
||||
def __special2__(self):
|
||||
# undocumented special method
|
||||
pass
|
||||
|
||||
if six.PY3 and sys.version_info[:2] >= (3, 5):
|
||||
|
||||
async def do_coroutine(self):
|
||||
"""A documented coroutine function"""
|
||||
attr_coro_result = await _other_coro_func() # NOQA
|
8
tests/roots/test-ext-autodoc/target/coroutine.py
Normal file
8
tests/roots/test-ext-autodoc/target/coroutine.py
Normal file
@ -0,0 +1,8 @@
|
||||
class AsyncClass:
|
||||
async def do_coroutine(self):
|
||||
"""A documented coroutine function"""
|
||||
attr_coro_result = await _other_coro_func() # NOQA
|
||||
|
||||
|
||||
async def _other_coro_func():
|
||||
return "run"
|
@ -1426,8 +1426,24 @@ def test_partialfunction():
|
||||
assert call_autodoc('module', 'target.partialfunction') == expected
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 4),
|
||||
reason='functools.partialmethod is available on py34 or above')
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
def test_coroutine():
|
||||
options = {"members": None}
|
||||
actual = do_autodoc(app, 'class', 'target.coroutine.AsyncClass', options)
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:class:: AsyncClass',
|
||||
' :module: target.coroutine',
|
||||
'',
|
||||
' ',
|
||||
' .. py:method:: AsyncClass.do_coroutine()',
|
||||
' :module: target.coroutine',
|
||||
' ',
|
||||
' A documented coroutine function',
|
||||
' '
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_partialmethod(app):
|
||||
expected = [
|
||||
|
@ -33,11 +33,6 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
|
||||
# If supported, build in a non-ASCII source dir
|
||||
test_name = u'\u65e5\u672c\u8a9e'
|
||||
basedir = sphinx_test_tempdir / request.node.originalname
|
||||
# Windows with versions prior to 3.2 (I think) doesn't support unicode on system path
|
||||
# so we force a non-unicode path in that case
|
||||
if (sys.platform == "win32" and
|
||||
not (sys.version_info.major >= 3 and sys.version_info.minor >= 2)):
|
||||
return basedir / 'all'
|
||||
try:
|
||||
srcdir = basedir / test_name
|
||||
if not srcdir.exists():
|
||||
|
@ -10,7 +10,6 @@
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
@ -82,9 +81,6 @@ def test_texinfo(app, status, warning):
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='docutilsconf',
|
||||
docutilsconf='[general]\nsource_link=true\n')
|
||||
@pytest.mark.skip(sys.platform == "win32" and
|
||||
not (sys.version_info.major >= 3 and sys.version_info.minor >= 2),
|
||||
reason="Python < 3.2 on Win32 doesn't handle non-ASCII paths right")
|
||||
def test_docutils_source_link_with_nonascii_file(app, status, warning):
|
||||
srcdir = path(app.srcdir)
|
||||
mb_name = u'\u65e5\u672c\u8a9e'
|
||||
|
@ -105,13 +105,8 @@ def test_getargspec_bound_methods():
|
||||
pass
|
||||
|
||||
assert expected_unbound == inspect.getargspec(Foo.method)
|
||||
if PY3 and sys.version_info >= (3, 4, 4):
|
||||
# On py2, the inspect functions don't properly handle bound
|
||||
# methods (they include a spurious 'self' argument)
|
||||
assert expected_bound == inspect.getargspec(bound_method)
|
||||
# On py2, the inspect functions can't properly handle wrapped
|
||||
# functions (no __wrapped__ support)
|
||||
assert expected_bound == inspect.getargspec(wrapped_bound_method)
|
||||
assert expected_bound == inspect.getargspec(bound_method)
|
||||
assert expected_bound == inspect.getargspec(wrapped_bound_method)
|
||||
|
||||
|
||||
def test_Signature():
|
||||
@ -143,10 +138,7 @@ def test_Signature_partial():
|
||||
p = functools.partial(fun, 10, c=11)
|
||||
|
||||
sig = inspect.Signature(p).format_args()
|
||||
if sys.version_info < (3,):
|
||||
assert sig == '(b, d=2)'
|
||||
else:
|
||||
assert sig == '(b, *, c=11, d=2)'
|
||||
assert sig == '(b, *, c=11, d=2)'
|
||||
|
||||
|
||||
def test_Signature_methods():
|
||||
@ -193,16 +185,9 @@ def test_Signature_methods():
|
||||
|
||||
# wrapped bound method
|
||||
sig = inspect.Signature(wrapped_bound_method).format_args()
|
||||
if sys.version_info < (3,):
|
||||
assert sig == '(*args, **kwargs)'
|
||||
elif sys.version_info < (3, 4, 4):
|
||||
assert sig == '(self, arg1, **kwargs)'
|
||||
else:
|
||||
assert sig == '(arg1, **kwargs)'
|
||||
assert sig == '(arg1, **kwargs)'
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 4),
|
||||
reason='functools.partialmethod is available on py34 or above')
|
||||
def test_Signature_partialmethod():
|
||||
from functools import partialmethod
|
||||
|
||||
@ -228,11 +213,9 @@ def test_Signature_partialmethod():
|
||||
assert sig == '()'
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 4),
|
||||
reason='type annotation test is available on py34 or above')
|
||||
def test_Signature_annotations():
|
||||
from typing_test_data import (
|
||||
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, Node)
|
||||
from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
|
||||
f11, f12, f13, f14, f15, f16, Node)
|
||||
|
||||
# Class annotations
|
||||
sig = inspect.Signature(f0).format_args()
|
||||
@ -297,6 +280,14 @@ def test_Signature_annotations():
|
||||
sig = inspect.Signature(f14).format_args()
|
||||
assert sig == '() -> Any'
|
||||
|
||||
# keyword only arguments (1)
|
||||
sig = inspect.Signature(f15).format_args()
|
||||
assert sig == '(arg1, arg2, *, arg3=None, arg4=None)'
|
||||
|
||||
# keyword only arguments (2)
|
||||
sig = inspect.Signature(f16).format_args()
|
||||
assert sig == '(*, arg3, arg4)'
|
||||
|
||||
# type hints by string
|
||||
sig = inspect.Signature(Node.children).format_args()
|
||||
if (3, 5, 0) <= sys.version_info < (3, 5, 3):
|
||||
@ -437,10 +428,5 @@ def test_isstaticmethod():
|
||||
|
||||
assert inspect.isstaticmethod(Foo.method1, Foo, 'method1') is True
|
||||
assert inspect.isstaticmethod(Foo.method2, Foo, 'method2') is False
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
assert inspect.isstaticmethod(Bar.method1, Bar, 'method1') is False
|
||||
assert inspect.isstaticmethod(Bar.method2, Bar, 'method2') is False
|
||||
else:
|
||||
assert inspect.isstaticmethod(Bar.method1, Bar, 'method1') is True
|
||||
assert inspect.isstaticmethod(Bar.method2, Bar, 'method2') is False
|
||||
assert inspect.isstaticmethod(Bar.method1, Bar, 'method1') is True
|
||||
assert inspect.isstaticmethod(Bar.method2, Bar, 'method2') is False
|
||||
|
@ -76,6 +76,13 @@ def f14() -> Any:
|
||||
pass
|
||||
|
||||
|
||||
def f15(arg1, arg2, *, arg3=None, arg4=None):
|
||||
pass
|
||||
|
||||
def f16(*, arg3, arg4):
|
||||
pass
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self, parent: Optional['Node']) -> None:
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user