From afce164e9ea66273240f368e57676f63193e4d86 Mon Sep 17 00:00:00 2001
From: Dominic Davis-Foster
Date: Mon, 20 Dec 2021 16:15:52 +0000
Subject: [PATCH 1/2] Add support for Sphinx 4
---
.github/workflows/python_ci.yml | 14 +--
.github/workflows/python_ci_linux.yml | 14 +--
.github/workflows/python_ci_macos.yml | 14 +--
__pkginfo__.py | 4 +-
enum_tools/autoenum.py | 50 ++++++++--
pyproject.toml | 4 +-
repo_helper.yml | 16 +++-
tests/requirements.txt | 2 +-
tests/test_autoenum.py | 54 ++++++++---
.../test_autoenum_/test_flag_flag_html_.html | 87 ++++++++---------
.../test_index_index_html_.html | 95 ++++++++-----------
...est_no_member_doc_no_member_doc_html_.html | 39 ++++----
tests/test_enums.py | 42 +++++++-
tox.ini | 35 ++++++-
14 files changed, 295 insertions(+), 175 deletions(-)
diff --git a/.github/workflows/python_ci.yml b/.github/workflows/python_ci.yml
index 469f90a..89c96c4 100644
--- a/.github/workflows/python_ci.yml
+++ b/.github/workflows/python_ci.yml
@@ -27,13 +27,13 @@ jobs:
fail-fast: False
matrix:
config:
- - {python-version: "3.6", testenvs: "py36,build", experimental: False}
- - {python-version: "3.7", testenvs: "py37,build", experimental: False}
- - {python-version: "3.8", testenvs: "py38,build", experimental: False}
- - {python-version: "3.9", testenvs: "py39,build", experimental: False}
- - {python-version: "3.10", testenvs: "py310-dev,build", experimental: True}
- - {python-version: "pypy-3.6", testenvs: "pypy36,build", experimental: False}
- - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True}
+ - {python-version: "3.6", testenvs: "py36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.7", testenvs: "py37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.8", testenvs: "py38-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.9", testenvs: "py39-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.10", testenvs: "py310-dev-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
+ - {python-version: "pypy-3.6", testenvs: "pypy36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "pypy-3.7", testenvs: "pypy37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
steps:
- name: Checkout 🛎️
diff --git a/.github/workflows/python_ci_linux.yml b/.github/workflows/python_ci_linux.yml
index 4b38cfd..e84a316 100644
--- a/.github/workflows/python_ci_linux.yml
+++ b/.github/workflows/python_ci_linux.yml
@@ -28,13 +28,13 @@ jobs:
fail-fast: False
matrix:
config:
- - {python-version: "3.6", testenvs: "py36,build", experimental: False}
- - {python-version: "3.7", testenvs: "py37,build", experimental: False}
- - {python-version: "3.8", testenvs: "py38,build", experimental: False}
- - {python-version: "3.9", testenvs: "py39,build", experimental: False}
- - {python-version: "3.10", testenvs: "py310-dev,build", experimental: True}
- - {python-version: "pypy-3.6", testenvs: "pypy36,build", experimental: False}
- - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True}
+ - {python-version: "3.6", testenvs: "py36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.7", testenvs: "py37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.8", testenvs: "py38-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.9", testenvs: "py39-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.10", testenvs: "py310-dev-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
+ - {python-version: "pypy-3.6", testenvs: "pypy36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "pypy-3.7", testenvs: "pypy37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
steps:
- name: Checkout 🛎️
diff --git a/.github/workflows/python_ci_macos.yml b/.github/workflows/python_ci_macos.yml
index 54945b1..f3f1082 100644
--- a/.github/workflows/python_ci_macos.yml
+++ b/.github/workflows/python_ci_macos.yml
@@ -27,13 +27,13 @@ jobs:
fail-fast: False
matrix:
config:
- - {python-version: "3.6", testenvs: "py36,build", experimental: False}
- - {python-version: "3.7", testenvs: "py37,build", experimental: False}
- - {python-version: "3.8", testenvs: "py38,build", experimental: False}
- - {python-version: "3.9", testenvs: "py39,build", experimental: False}
- - {python-version: "3.10", testenvs: "py310-dev,build", experimental: True}
- - {python-version: "pypy-3.6", testenvs: "pypy36,build", experimental: False}
- - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True}
+ - {python-version: "3.6", testenvs: "py36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.7", testenvs: "py37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.8", testenvs: "py38-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.9", testenvs: "py39-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "3.10", testenvs: "py310-dev-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
+ - {python-version: "pypy-3.6", testenvs: "pypy36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: False}
+ - {python-version: "pypy-3.7", testenvs: "pypy37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3},build", experimental: True}
steps:
- name: Checkout 🛎️
diff --git a/__pkginfo__.py b/__pkginfo__.py
index 30243c2..6e7dfb2 100644
--- a/__pkginfo__.py
+++ b/__pkginfo__.py
@@ -14,6 +14,6 @@
__all__ = ["extras_require"]
extras_require = {
- "sphinx": ["sphinx<3.5.0,>=3.0.3", "sphinx-toolbox>=1.2.0"],
- "all": ["sphinx<3.5.0,>=3.0.3", "sphinx-toolbox>=1.2.0"]
+ "sphinx": ["sphinx<4.4,>=3.2.0", "sphinx-toolbox>=1.2.0"],
+ "all": ["sphinx<4.4,>=3.2.0", "sphinx-toolbox>=1.2.0"]
}
diff --git a/enum_tools/autoenum.py b/enum_tools/autoenum.py
index 0c86532..788f1ed 100644
--- a/enum_tools/autoenum.py
+++ b/enum_tools/autoenum.py
@@ -54,7 +54,7 @@
# stdlib
from contextlib import suppress
from enum import Enum
-from typing import Any, Dict, List, Optional, Tuple
+from typing import Any, Dict, List, Optional, Tuple, get_type_hints
# 3rd party
from docutils.nodes import Element # nodep
@@ -62,9 +62,18 @@
from sphinx.domains import ObjType # nodep
from sphinx.domains.python import PyClasslike, PyXRefRole # nodep
from sphinx.environment import BuildEnvironment # nodep
-from sphinx.ext.autodoc import ALL, INSTANCEATTR, AttributeDocumenter, ClassDocumenter, Documenter # nodep
+from sphinx.ext.autodoc import ( # nodep
+ ALL,
+ INSTANCEATTR,
+ SUPPRESS,
+ AttributeDocumenter,
+ ClassDocumenter,
+ ClassLevelDocumenter,
+ Documenter
+ )
from sphinx.locale import _ # nodep
-from sphinx.util.inspect import object_description # nodep
+from sphinx.util.inspect import memory_address_re, safe_getattr # nodep
+from sphinx.util.typing import stringify as stringify_typehint # nodep
from sphinx_toolbox.more_autodoc.typehints import format_annotation # nodep
from sphinx_toolbox.utils import begin_generate # nodep
@@ -321,7 +330,6 @@ def import_object(self, raiseerror: bool = False) -> bool:
.. latex:clearpage::
"""
- self._datadescriptor = False
return Documenter.import_object(self, raiseerror=raiseerror)
def generate(
@@ -366,12 +374,40 @@ def add_directive_header(self, sig: str) -> None:
:param sig:
"""
- super().add_directive_header(sig)
+ ClassLevelDocumenter.add_directive_header(self, sig)
+ sourcename = self.get_sourcename()
+ if not self.options.annotation:
+ # obtain type annotation for this attribute
+ try:
+ annotations = get_type_hints(self.parent)
+ except NameError:
+ # Failed to evaluate ForwardRef (maybe TYPE_CHECKING)
+ annotations = safe_getattr(self.parent, "__annotations__", {})
+ except (TypeError, KeyError, AttributeError):
+ # KeyError = a broken class found (refs: https://github.com/sphinx-doc/sphinx/issues/8084)
+ # AttributeError is raised on 3.5.2 (fixed by 3.5.3)
+ annotations = {}
+
+ if self.objpath[-1] in annotations:
+ objrepr = stringify_typehint(annotations.get(self.objpath[-1]))
+ self.add_line(" :type: " + objrepr, sourcename)
+ else:
+ key = ('.'.join(self.objpath[:-1]), self.objpath[-1])
+ if self.analyzer and key in self.analyzer.annotations:
+ self.add_line(" :type: " + self.analyzer.annotations[key], sourcename)
+
+ elif self.options.annotation is SUPPRESS:
+ pass
+ else:
+ self.add_line(" :annotation: %s" % self.options.annotation, sourcename)
if not self.options.annotation:
- with suppress(ValueError):
+ with suppress(Exception):
if self.object is not INSTANCEATTR:
- objrepr = object_description(self.object)
+
+ # Workaround for https://github.com/sphinx-doc/sphinx/issues/9272
+ # which broke Enum displays in 4.1.0
+ objrepr = memory_address_re.sub('', repr(self.object)).replace('\n', ' ')
self.add_line(f' :value: {objrepr}', self.get_sourcename())
diff --git a/pyproject.toml b/pyproject.toml
index 381a506..857add6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -25,8 +25,8 @@ Homepage = "https://github.com/domdfcoding/enum_tools"
Documentation = "https://enum_tools.readthedocs.io/en/latest"
[project.optional-dependencies]
-sphinx = [ "sphinx<3.5.0,>=3.0.3", "sphinx-toolbox>=1.2.0",]
-all = [ "sphinx<3.5.0,>=3.0.3", "sphinx-toolbox>=1.2.0",]
+sphinx = [ "sphinx<4.4,>=3.2.0", "sphinx-toolbox>=1.2.0",]
+all = [ "sphinx<4.4,>=3.2.0", "sphinx-toolbox>=1.2.0",]
[tool.whey]
base-classifiers = [
diff --git a/repo_helper.yml b/repo_helper.yml
index af3c459..f329d28 100644
--- a/repo_helper.yml
+++ b/repo_helper.yml
@@ -12,7 +12,7 @@ short_desc: "Tools to expand Python's enum module."
use_whey: true
tox_testenv_extras: all
standalone_contrib_guide: true
-min_coverage: 85
+min_coverage: 88
docs_fail_on_warning: true
conda_channels:
@@ -51,7 +51,7 @@ keywords:
extras_require:
sphinx:
- - sphinx<3.5.0,>=3.0.3
+ - sphinx<4.4,>=3.2.0
- sphinx-toolbox>=1.2.0
extra_sphinx_extensions:
@@ -76,3 +76,15 @@ sphinx_conf_epilogue:
- enum_tools.autoenum.Type = Type
preserve_custom_theme: true
+
+
+third_party_version_matrix:
+ sphinx:
+ - 3.2
+ - 3.3
+ - 3.4
+ - 3.5
+ - 4.0
+ - 4.1
+ - 4.2
+ - 4.3
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 4931db3..42c2134 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -13,4 +13,4 @@ pytest-regressions>=2.0.1
pytest-rerunfailures>=9.0
pytest-timeout>=1.4.2
sphinx>=3.2.1
-sphinx-toolbox[testing]>=0.3.0
+sphinx-toolbox[testing]>=2.15.2
diff --git a/tests/test_autoenum.py b/tests/test_autoenum.py
index 708fa7f..66b5d53 100644
--- a/tests/test_autoenum.py
+++ b/tests/test_autoenum.py
@@ -9,7 +9,8 @@
# 3rd party
import pytest
-from bs4 import BeautifulSoup # type: ignore
+import sphinx
+from bs4 import BeautifulSoup, NavigableString # type: ignore
from pytest_regressions.file_regression import FileRegressionFixture # type: ignore
from sphinx_toolbox.testing import HTMLRegressionFixture
@@ -53,6 +54,33 @@ def test(app):
# pytestmark = pytest.mark.sphinx('html', testroot='root')
+return_arrow = " → "
+
+
+def preprocess_soup(soup: BeautifulSoup):
+
+ if sphinx.version_info >= (3, 5): # pragma: no cover
+ for em in soup.select("em.property"):
+ child = ''.join(c.string for c in em.contents)
+ for c in em.children:
+ c.extract()
+ em.contents = []
+ em.insert(0, child)
+
+ for dl in soup.select("dl.py.method dt"): # .sig.sig-object.py
+ if return_arrow in dl.contents:
+ arrow_idx = dl.contents.index(return_arrow)
+ dl.contents[arrow_idx] = NavigableString(
+ dl.contents[arrow_idx] + dl.contents[arrow_idx + 1].contents[0]
+ )
+ dl.contents[arrow_idx + 1].extract()
+
+ for dt in soup.select("span.pre"):
+ dt.replace_with_children()
+
+ for dt in soup.select("span.sig-return"):
+ dt.replace_with(NavigableString(dt.get_text()))
+
@pytest.mark.parametrize(
"page", [
@@ -64,6 +92,8 @@ def test_index(page: BeautifulSoup, html_regression: HTMLRegressionFixture):
title = page.find("h1").contents[0].strip()
assert "autoenum Demo" == title
+ preprocess_soup(page)
+
html_regression.check(page, jinja2=True)
# Now test the directive
@@ -81,10 +111,8 @@ def test_index(page: BeautifulSoup, html_regression: HTMLRegressionFixture):
assert class_.find("dt")["id"] == "enum_tools.demo.NoMethods"
assert class_.find("dd").findAll('p')[0].contents[0] == "An enumeration of people without any methods."
- assert str(class_.find("dd").findAll('p')[1].contents[0]) == (
- ''
- 'int
'
- )
+ tag = 'int
'
+ assert str(class_.find("dd").findAll('p')[1].contents[0]) == tag
assert class_.find("dd").findAll('p')[2].contents[0] == "Valid values are as follows:"
attr_count = 0
@@ -147,6 +175,8 @@ def test_flag(page: BeautifulSoup, html_regression: HTMLRegressionFixture):
title = page.find("h1").contents[0].strip()
assert "autoenum Demo - Flag" == title
+ preprocess_soup(page)
+
html_regression.check(page, jinja2=True)
# Now test the directive
@@ -164,10 +194,8 @@ def test_flag(page: BeautifulSoup, html_regression: HTMLRegressionFixture):
assert class_.find("dd").findAll('p')[0].contents[0] == "An enumeration of status codes."
- assert str(class_.find("dd").findAll('p')[1].contents[0]) == (
- ''
- 'int
'
- )
+ tag = 'int
'
+ assert str(class_.find("dd").findAll('p')[1].contents[0]) == tag
assert class_.find("dd").findAll('p')[2].contents[0] == "Valid values are as follows:"
attr_count = 0
@@ -232,6 +260,8 @@ def test_no_member_doc(page: BeautifulSoup, html_regression: HTMLRegressionFixtu
title = page.find("h1").contents[0].strip()
assert "autoenum Demo - Members without docstrings" == title
+ preprocess_soup(page)
+
html_regression.check(page, jinja2=True)
# Now test the directive
@@ -247,10 +277,8 @@ def test_no_member_doc(page: BeautifulSoup, html_regression: HTMLRegressionFixtu
0] == "An enumeration of people without any member docstrings."
if class_count == 0:
- assert str(class_.find("dd").findAll('p')[1].contents[0]) == (
- ''
- 'int
'
- )
+ tag = 'int
'
+ assert str(class_.find("dd").findAll('p')[1].contents[0]) == tag
assert class_.find("dd").findAll('p')[2].contents[0] == "Valid values are as follows:"
else:
assert class_.find("dd").findAll('p')[1].contents[0] == "Valid values are as follows:"
diff --git a/tests/test_autoenum_/test_flag_flag_html_.html b/tests/test_autoenum_/test_flag_flag_html_.html
index a31e080..5229570 100644
--- a/tests/test_autoenum_/test_flag_flag_html_.html
+++ b/tests/test_autoenum_/test_flag_flag_html_.html
@@ -1,4 +1,5 @@
-{% set NEW_ENUM_REPR = python_version >= (3, 11) -%}
+{% set sig_prename_tag=("span" if sphinx_version >= (4, 0) else 'code') -%}
+{% set sig_object_class=(' class="sig sig-object py"' if sphinx_version >= (4, 0) else '') -%}
@@ -30,16 +31,16 @@
- -
+
-
flag
-
+ <{{ sig_prename_tag }} class="sig-prename descclassname">
enum_tools.demo.
-
-
+ {{ sig_prename_tag }}>
+ <{{ sig_prename_tag }} class="sig-name descname">
StatusFlags
-
+ {{ sig_prename_tag }}>
(
@@ -66,9 +67,7 @@
-
-
- int
-
+ int
@@ -77,10 +76,10 @@
Valid values are as follows:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Running
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Running{% else %}<StatusFlags.Running: 1>{% endif %}
@@ -95,10 +94,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Stopped
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Stopped{% else %}<StatusFlags.Stopped: 2>{% endif %}
@@ -113,10 +112,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Error
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Error{% else %}<StatusFlags.Error: 4>{% endif %}
@@ -133,17 +132,15 @@
The
-
- Flag
-
+ Flag
and its members also have the following methods:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
has_errored
-
+ {{ sig_prename_tag }}>
(
@@ -166,16 +163,16 @@
- -
+
-
flag
-
+ <{{ sig_prename_tag }} class="sig-prename descclassname">
enum_tools.demo.
-
-
+ {{ sig_prename_tag }}>
+ <{{ sig_prename_tag }} class="sig-name descname">
StatusFlags
-
+ {{ sig_prename_tag }}>
(
@@ -202,9 +199,7 @@
-
-
- int
-
+ int
@@ -213,10 +208,10 @@
Valid values are as follows:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Running
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Running{% else %}<StatusFlags.Running: 1>{% endif %}
@@ -231,10 +226,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Stopped
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Stopped{% else %}<StatusFlags.Stopped: 2>{% endif %}
@@ -249,10 +244,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Error
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}StatusFlags.Error{% else %}<StatusFlags.Error: 4>{% endif %}
@@ -269,17 +264,15 @@
The
-
- Flag
-
+ Flag
and its members also have the following methods:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
has_errored
-
+ {{ sig_prename_tag }}>
(
diff --git a/tests/test_autoenum_/test_index_index_html_.html b/tests/test_autoenum_/test_index_index_html_.html
index a51329f..031f1a4 100644
--- a/tests/test_autoenum_/test_index_index_html_.html
+++ b/tests/test_autoenum_/test_index_index_html_.html
@@ -1,4 +1,5 @@
-{% set NEW_ENUM_REPR = python_version >= (3, 11) -%}
+{% set sig_prename_tag=("span" if sphinx_version >= (4, 0) else 'code') -%}
+{% set sig_object_class=(' class="sig sig-object py"' if sphinx_version >= (4, 0) else '') -%}
@@ -32,16 +33,16 @@
- -
+
-
enum
-
+ <{{ sig_prename_tag }} class="sig-prename descclassname">
enum_tools.demo.
-
-
+ {{ sig_prename_tag }}>
+ <{{ sig_prename_tag }} class="sig-name descname">
People
-
+ {{ sig_prename_tag }}>
(
@@ -68,9 +69,7 @@
-
-
- int
-
+ int
@@ -79,10 +78,10 @@
Valid values are as follows:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Bob
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}People.Bob{% else %}<People.Bob: 1>{% endif %}
@@ -97,10 +96,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Alice
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}People.Alice{% else %}<People.Alice: 2>{% endif %}
@@ -115,10 +114,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Carol
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}People.Carol{% else %}<People.Carol: 3>{% endif %}
@@ -135,20 +134,18 @@
The
-
- Enum
-
+ Enum
and its members also have the following methods:
- -
+
-
classmethod
-
+ <{{ sig_prename_tag }} class="sig-name descname">
iter_values
-
+ {{ sig_prename_tag }}>
(
@@ -166,13 +163,13 @@
- -
+
-
classmethod
-
+ <{{ sig_prename_tag }} class="sig-name descname">
as_list
-
+ {{ sig_prename_tag }}>
(
@@ -193,16 +190,16 @@
- -
+
-
enum
-
+ <{{ sig_prename_tag }} class="sig-prename descclassname">
enum_tools.demo.
-
-
+ {{ sig_prename_tag }}>
+ <{{ sig_prename_tag }} class="sig-name descname">
NoMethods
-
+ {{ sig_prename_tag }}>
(
@@ -229,9 +226,7 @@
-
-
- int
-
+ int
@@ -240,10 +235,10 @@
Valid values are as follows:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Bob
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMethods.Bob{% else %}<NoMethods.Bob: 1>{% endif %}
@@ -258,10 +253,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Alice
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMethods.Alice{% else %}<NoMethods.Alice: 2>{% endif %}
@@ -276,10 +271,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Carol
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMethods.Carol{% else %}<NoMethods.Carol: 3>{% endif %}
@@ -298,27 +293,21 @@
-
- enum_tools.demo.People
-
+ enum_tools.demo.People
-
- People
-
+ People
-
- People
-
+ People
diff --git a/tests/test_autoenum_/test_no_member_doc_no_member_doc_html_.html b/tests/test_autoenum_/test_no_member_doc_no_member_doc_html_.html
index 852da2d..eb653ff 100644
--- a/tests/test_autoenum_/test_no_member_doc_no_member_doc_html_.html
+++ b/tests/test_autoenum_/test_no_member_doc_no_member_doc_html_.html
@@ -1,4 +1,5 @@
-{% set NEW_ENUM_REPR = python_version >= (3, 11) -%}
+{% set sig_prename_tag=("span" if sphinx_version >= (4, 0) else 'code') -%}
+{% set sig_object_class=(' class="sig sig-object py"' if sphinx_version >= (4, 0) else '') -%}
@@ -30,16 +31,16 @@
- -
+
-
enum
-
+ <{{ sig_prename_tag }} class="sig-prename descclassname">
enum_tools.demo.
-
-
+ {{ sig_prename_tag }}>
+ <{{ sig_prename_tag }} class="sig-name descname">
NoMemberDoc
-
+ {{ sig_prename_tag }}>
(
@@ -66,9 +67,7 @@
-
-
- int
-
+ int
@@ -77,10 +76,10 @@
Valid values are as follows:
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Bob
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMemberDoc.Bob{% else %}<NoMemberDoc.Bob: 1>{% endif %}
@@ -92,10 +91,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Alice
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMemberDoc.Alice{% else %}<NoMemberDoc.Alice: 2>{% endif %}
@@ -107,10 +106,10 @@
- -
-
+ -
+ <{{ sig_prename_tag }} class="sig-name descname">
Carol
-
+ {{ sig_prename_tag }}>
= {% if NEW_ENUM_REPR %}NoMemberDoc.Carol{% else %}<NoMemberDoc.Carol: 3>{% endif %}
@@ -126,9 +125,7 @@
-
- enum_tools.demo.NoMemberDoc.Alice
-
+ enum_tools.demo.NoMemberDoc.Alice
diff --git a/tests/test_enums.py b/tests/test_enums.py
index a874903..ff7519e 100644
--- a/tests/test_enums.py
+++ b/tests/test_enums.py
@@ -5,13 +5,14 @@
# stdlib
import sys
+from enum import Enum
# 3rd party
import pytest
# this package
from enum_tools import IntEnum, StrEnum
-from enum_tools.custom_enums import IterableFlag, IterableIntFlag
+from enum_tools.custom_enums import AutoNumberEnum, IterableFlag, IterableIntFlag, MemberDirEnum, OrderedEnum
NEW_ENUM_REPR = sys.version_info >= (3, 11)
@@ -125,3 +126,42 @@ class FourthFailedStrEnum(StrEnum):
class FifthFailedStrEnum(StrEnum):
one = '1'
two = b'2', "ascii", 9
+
+
+def test_member_dir_enum():
+
+ class MyEnum(int, MemberDirEnum):
+ apple = 1
+ orange = 2
+
+ assert dir(MyEnum) == ["__class__", "__doc__", "__members__", "__module__", "apple", "orange"]
+
+
+def test_auto_number_enum():
+
+ class MyEnum(AutoNumberEnum):
+ apple = 1
+ orange = 1
+
+ assert MyEnum.apple._value_ == 1
+ assert MyEnum.orange._value_ == 2
+
+
+def test_ordered_enum():
+
+ class MyEnum(OrderedEnum):
+ apple = 1
+ orange = 2
+ strawberry = 0
+
+ assert MyEnum.apple < MyEnum.orange
+ assert MyEnum.apple <= MyEnum.orange
+ assert MyEnum.apple > MyEnum.strawberry
+ assert MyEnum.apple >= MyEnum.strawberry
+
+ class MyEnum2(Enum):
+ apple = 1
+ orange = 2
+
+ with pytest.raises(TypeError, match="'<' not supported between instances of 'MyEnum' and 'MyEnum'"):
+ MyEnum2.apple < MyEnum2.orange # type: ignore[operator]
diff --git a/tox.ini b/tox.ini
index c6a4e8c..4e92080 100644
--- a/tox.ini
+++ b/tox.ini
@@ -16,7 +16,16 @@
# * pytest
[tox]
-envlist = py36, py37, py38, py39, py310-dev, pypy36, pypy37, mypy, build
+envlist =
+ py36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py38-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py39-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py310-dev-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ pypy36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ pypy37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ mypy
+ build
skip_missing_interpreters = True
isolated_build = True
requires =
@@ -25,15 +34,31 @@ requires =
tox-pip-version>=0.0.7
[envlists]
-test = py36, py37, py38, py39, py310-dev, pypy36, pypy37
+test =
+ py36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py38-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py39-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ py310-dev-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ pypy36-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
+ pypy37-sphinx{3.2,3.3,3.4,3.5,4.0,4.1,4.2,4.3}
qa = mypy, lint
-cov = py36, coverage
+cov = py36-sphinx3.2, coverage
[testenv]
setenv =
PYTHONDEVMODE=1
PIP_DISABLE_PIP_VERSION_CHECK=1
-deps = -r{toxinidir}/tests/requirements.txt
+deps =
+ -r{toxinidir}/tests/requirements.txt
+ sphinx3.2: sphinx~=3.2.0
+ sphinx3.3: sphinx~=3.3.0
+ sphinx3.4: sphinx~=3.4.0
+ sphinx3.5: sphinx~=3.5.0
+ sphinx4.0: sphinx~=4.0.0
+ sphinx4.1: sphinx~=4.1.0
+ sphinx4.2: sphinx~=4.2.0
+ sphinx4.3: sphinx~=4.3.0
extras = all
commands =
python --version
@@ -158,7 +183,7 @@ unused-arguments-ignore-variadic-names = True
plugins = coverage_pyver_pragma
[coverage:report]
-fail_under = 85
+fail_under = 88
exclude_lines =
raise AssertionError
raise NotImplementedError
From 2412a6421f7a4fafb560a5ab52a17e2ec654d7ef Mon Sep 17 00:00:00 2001
From: Dominic Davis-Foster
Date: Mon, 20 Dec 2021 16:50:42 +0000
Subject: [PATCH 2/2] Fix typos
---
tests/test_enums.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/test_enums.py b/tests/test_enums.py
index ff7519e..54d97a8 100644
--- a/tests/test_enums.py
+++ b/tests/test_enums.py
@@ -88,7 +88,7 @@ class Color(IterableFlag):
def test_strenum():
# From https://github.com/python/cpython/pull/22337
- # PDF License
+ # PSF License
class GoodStrEnum(StrEnum):
one = '1'
@@ -163,5 +163,5 @@ class MyEnum2(Enum):
apple = 1
orange = 2
- with pytest.raises(TypeError, match="'<' not supported between instances of 'MyEnum' and 'MyEnum'"):
+ with pytest.raises(TypeError, match="'<' not supported between instances of 'MyEnum2' and 'MyEnum2'"):
MyEnum2.apple < MyEnum2.orange # type: ignore[operator]