Skip to content

Commit

Permalink
Merge branch '3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed Nov 4, 2020
2 parents b93aa31 + ab707be commit 8bf8416
Show file tree
Hide file tree
Showing 18 changed files with 229 additions and 76 deletions.
42 changes: 40 additions & 2 deletions .github/workflows/main.yml
@@ -1,9 +1,47 @@
name: CI on Windows
name: CI

on: [push, pull_request]

jobs:
build:
ubuntu:
runs-on: ubuntu-16.04
strategy:
fail-fast: false
matrix:
name: [py36, py37, py38]
include:
- name: py36
python: 3.6
docutils: du13
- name: py37
python: 3.7
docutils: du14
- name: py38
python: 3.8
docutils: du15
coverage: "--cov ./ --cov-append --cov-config setup.cfg"
env:
PYTEST_ADDOPTS: ${{ matrix.coverage }}

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: Check Python version
run: python --version
- name: Install graphviz
run: sudo apt-get install graphviz
- name: Install dependencies
run: pip install -U tox codecov
- name: Run Tox
run: tox -e ${{ matrix.docutils }} -- -vv
- name: codecov
uses: codecov/codecov-action@v1
if: matrix.coverage

windows:
runs-on: windows-latest
strategy:
matrix:
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/nodejs.yml
@@ -0,0 +1,21 @@
name: CI (node.js)

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
env:
node-version: 10.7

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node-version }}
- run: npm install
- name: Run headless test
uses: GabrielBB/xvfb-action@v1
with:
run: npm test
43 changes: 0 additions & 43 deletions .travis.yml

This file was deleted.

6 changes: 6 additions & 0 deletions CHANGES
Expand Up @@ -64,9 +64,15 @@ Deprecated
Features added
--------------

* #6914: Add a new event :event:`warn-missing-reference` to custom warning
messages when failed to resolve a cross-reference
* #6914: Emit a detailed warning when failed to resolve a ``:ref:`` reference

Bugs fixed
----------

* #7613: autodoc: autodoc does not respect __signature__ of the class

Testing
--------

Expand Down
6 changes: 3 additions & 3 deletions doc/develop.rst
Expand Up @@ -22,9 +22,9 @@ Extensions

To learn how to write your own extension, see :ref:`dev-extensions`.

The `sphinx-contrib <https://bitbucket.org/birkenfeld/sphinx-contrib/>`_
repository contains many contributed extensions. Some of them have their own
releases on PyPI, others you can install from a checkout.
The `sphinx-contrib <https://github.com/sphinx-contrib>`_ repository contains many
contributed extensions. Some of them have their own releases on PyPI, others you
can install from a checkout.

This is the current list of contributed extensions in that repository:

Expand Down
9 changes: 9 additions & 0 deletions doc/extdev/appapi.rst
Expand Up @@ -186,6 +186,7 @@ type for that event::
13. apply post-transforms (by priority): docutils.document -> docutils.document
14. event.doctree-resolved(app, doctree, docname)
- (for any reference node that fails to resolve) event.missing-reference(env, node, contnode)
- (for any reference node that fails to resolve) event.warn-missing-reference(domain, node)

15. Generate output files
16. event.build-finished(app, exception)
Expand Down Expand Up @@ -284,6 +285,14 @@ Here is a more detailed list of these events.

.. versionadded:: 0.5

.. event:: warn-missing-reference (app, domain, node)

Emitted when a cross-reference to an object cannot be resolved even after
:event:`missing-reference`. If the event handler can emit warnings for
the missing reference, it should return ``True``.

.. versionadded:: 3.4

.. event:: doctree-resolved (app, doctree, docname)

Emitted when a doctree has been "resolved" by the environment, that is, all
Expand Down
17 changes: 15 additions & 2 deletions sphinx/domains/std.py
Expand Up @@ -595,8 +595,6 @@ class StandardDomain(Domain):

dangling_warnings = {
'term': 'term not in glossary: %(target)s',
'ref': 'undefined label: %(target)s (if the link has no caption '
'the label must precede a section header)',
'numref': 'undefined label: %(target)s',
'keyword': 'unknown keyword: %(target)s',
'doc': 'unknown document: %(target)s',
Expand Down Expand Up @@ -1075,8 +1073,23 @@ def get_full_qualified_name(self, node: Element) -> str:
return None


def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref) -> bool:
if domain.name != 'std' or node['reftype'] != 'ref':
return None
else:
target = node['reftarget']
if target not in domain.anonlabels: # type: ignore
msg = __('undefined label: %s')
else:
msg = __('Failed to create a cross reference. A title or caption not found: %s')

logger.warning(msg % target, location=node, type='ref', subtype=node['reftype'])
return True


def setup(app: "Sphinx") -> Dict[str, Any]:
app.add_domain(StandardDomain)
app.connect('warn-missing-reference', warn_missing_reference)

return {
'version': 'builtin',
Expand Down
1 change: 1 addition & 0 deletions sphinx/events.py
Expand Up @@ -45,6 +45,7 @@ class EventListener(NamedTuple):
'doctree-read': 'the doctree before being pickled',
'env-merge-info': 'env, read docnames, other env instance',
'missing-reference': 'env, node, contnode',
'warn-missing-reference': 'domain, node',
'doctree-resolved': 'doctree, docname',
'env-updated': 'env',
'html-collect-pages': 'builder',
Expand Down
7 changes: 6 additions & 1 deletion sphinx/ext/autodoc/__init__.py
Expand Up @@ -1376,7 +1376,12 @@ def get_user_defined_function_or_method(obj: Any, attr: str) -> Any:
# This sequence is copied from inspect._signature_from_callable.
# ValueError means that no signature could be found, so we keep going.

# First, let's see if it has an overloaded __call__ defined
# First, we check the obj has a __signature__ attribute
if (hasattr(self.object, '__signature__') and
isinstance(self.object.__signature__, Signature)):
return None, None, self.object.__signature__

# Next, let's see if it has an overloaded __call__ defined
# in its metaclass
call = get_user_defined_function_or_method(type(self.object), '__call__')

Expand Down
5 changes: 4 additions & 1 deletion sphinx/transforms/post_transforms/__init__.py
Expand Up @@ -166,7 +166,10 @@ def warn_missing_reference(self, refdoc: str, typ: str, target: str,
warn = False
if not warn:
return
if domain and typ in domain.dangling_warnings:

if self.app.emit_firstresult('warn-missing-reference', domain, node):
return
elif domain and typ in domain.dangling_warnings:
msg = domain.dangling_warnings[typ]
elif node.get('refdomain', 'std') not in ('', 'std'):
msg = (__('%s:%s reference target not found: %%(target)s') %
Expand Down
Empty file.
7 changes: 7 additions & 0 deletions tests/roots/test-domain-py-xref-warning/index.rst
@@ -0,0 +1,7 @@
test-domain-py-xref-warning
===========================

.. _existing-label:

:ref:`no-label`
:ref:`existing-label`
11 changes: 11 additions & 0 deletions tests/roots/test-ext-autodoc/target/classes.py
@@ -1,3 +1,6 @@
from inspect import Parameter, Signature


class Foo:
pass

Expand All @@ -10,3 +13,11 @@ def __init__(self, x, y):
class Baz:
def __new__(cls, x, y):
pass


class Qux:
__signature__ = Signature(parameters=[Parameter('foo', Parameter.POSITIONAL_OR_KEYWORD),
Parameter('bar', Parameter.POSITIONAL_OR_KEYWORD)])

def __init__(self, x, y):
pass
8 changes: 8 additions & 0 deletions tests/test_domain_py.py
Expand Up @@ -876,3 +876,11 @@ def test_noindexentry(app):
assert_node(doctree, (addnodes.index, desc, addnodes.index, desc))
assert_node(doctree[0], addnodes.index, entries=[('single', 'f (built-in class)', 'f', '', None)])
assert_node(doctree[2], addnodes.index, entries=[])


@pytest.mark.sphinx('dummy', testroot='domain-py-xref-warning')
def test_warn_missing_reference(app, status, warning):
app.build()
assert 'index.rst:6: WARNING: undefined label: no-label' in warning.getvalue()
assert ('index.rst:6: WARNING: Failed to create a cross reference. A title or caption not found: existing-label'
in warning.getvalue())
33 changes: 20 additions & 13 deletions tests/test_ext_autodoc.py
Expand Up @@ -1832,19 +1832,26 @@ def test_autodoc_for_egged_code(app):
def test_singledispatch(app):
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.singledispatch', options)
assert list(actual) == [
'',
'.. py:module:: target.singledispatch',
'',
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]
if sys.version_info < (3, 6):
# check the result via "in" because the order of singledispatch signatures is
# usually changed (because dict is not OrderedDict yet!)
assert '.. py:function:: func(arg, kwarg=None)' in actual
assert ' func(arg: int, kwarg=None)' in actual
assert ' func(arg: str, kwarg=None)' in actual
else:
assert list(actual) == [
'',
'.. py:module:: target.singledispatch',
'',
'',
'.. py:function:: func(arg, kwarg=None)',
' func(arg: int, kwarg=None)',
' func(arg: str, kwarg=None)',
' :module: target.singledispatch',
'',
' A function for general use.',
'',
]


@pytest.mark.skipif(sys.version_info < (3, 8),
Expand Down
50 changes: 50 additions & 0 deletions tests/test_ext_autodoc_autoclass.py
@@ -0,0 +1,50 @@
"""
test_ext_autodoc_autoclass
~~~~~~~~~~~~~~~~~~~~~~~~~~
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-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import pytest

from test_ext_autodoc import do_autodoc


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_classes(app):
actual = do_autodoc(app, 'function', 'target.classes.Foo')
assert list(actual) == [
'',
'.. py:function:: Foo()',
' :module: target.classes',
'',
]

actual = do_autodoc(app, 'function', 'target.classes.Bar')
assert list(actual) == [
'',
'.. py:function:: Bar(x, y)',
' :module: target.classes',
'',
]

actual = do_autodoc(app, 'function', 'target.classes.Baz')
assert list(actual) == [
'',
'.. py:function:: Baz(x, y)',
' :module: target.classes',
'',
]

actual = do_autodoc(app, 'function', 'target.classes.Qux')
assert list(actual) == [
'',
'.. py:function:: Qux(foo, bar)',
' :module: target.classes',
'',
]

0 comments on commit 8bf8416

Please sign in to comment.