Also starting to use the 3.6 CI job to test hacks for older packages.
_automatically_created_by_attrs_even_more_indented = """
Automatically created by attrs.
"""
+_generated_by_attrs_template = "Method generated by attrs for class XXX."
_filtered_attrs_functions = set([
('__ne__', """
Check equality and either forward a NotImplemented or return the result
('__ge__', _automatically_created_by_attrs),
('__repr__', _automatically_created_by_attrs),
('__getstate__', _automatically_created_by_attrs_even_more_indented),
- ('__setstate__', _automatically_created_by_attrs_even_more_indented)
+ ('__setstate__', _automatically_created_by_attrs_even_more_indented),
+ # Attrs 20.1 override the above with a generic doc afterwards (ew, dirty)
+ # and add __eq__() as well (before it had no docstring at all).
+ # The __init__() has this generic doc as well, but we don't want to hide it
+ # because it contains vital information on how to construct the class
+ # TODO remove the originals once support for older attrs is dropped
+ ('__eq__', _generated_by_attrs_template),
+ ('__ne__', _generated_by_attrs_template),
+ ('__lt__', _generated_by_attrs_template),
+ ('__le__', _generated_by_attrs_template),
+ ('__gt__', _generated_by_attrs_template),
+ ('__ge__', _generated_by_attrs_template),
+ ('__repr__', _generated_by_attrs_template),
])
def crawl_enum(state: State, path: List[str], enum_, parent_url):
continue
# ... or are auto-generated by attrs
if state.config['ATTRS_COMPATIBILITY']:
- if (name, object.__doc__) in _filtered_attrs_functions: continue
- # Unfortunately the __eq__ doesn't have a docstring,
- # try to match it just from the param names
+ # All methods generated by attrs 20.1+ have a generic
+ # docstring that contains the class name.
+ if (name, (object.__doc__ or '').replace(path[-1], 'XXX')) in _filtered_attrs_functions:
+ continue
+ # Before 20.1, the __eq__() unfortunately doesn't have
+ # a docstring, try to match it just from the param
+ # names
+ # TODO remove once support for older attrs is dropped
if name == '__eq__' and object.__doc__ is None:
try:
signature = inspect.signature(object)
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>inspect_attrs.MyClassAutoAttribs | My Python Project</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+ <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Python Project</a>
+ </div>
+ </div>
+</nav></header>
+<main><article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>
+ <span class="m-breadcrumb"><a href="inspect_attrs.html">inspect_attrs</a>.<wbr/></span>MyClassAutoAttribs <span class="m-thin">class</span>
+ </h1>
+ <p>A class with automatic attr-defined properties</p>
+ <div class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#dunder-methods">Special methods</a></li>
+ <li><a href="#properties">Properties</a></li>
+ <li><a href="#data">Data</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ <section id="dunder-methods">
+ <h2><a href="#dunder-methods">Special methods</a></h2>
+ <dl class="m-doc">
+ <dt id="__init__">
+ <span class="m-doc-wrap-bumper">def <a href="#__init__" class="m-doc-self">__init__</a>(</span><span class="m-doc-wrap">self,
+ annotated: float,
+ complex_annotation: typing.List[typing.Tuple[int, float]] = []) -> None</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="properties">
+ <h2><a href="#properties">Properties</a></h2>
+ <dl class="m-doc">
+ <dt id="annotated">
+ <a href="#annotated" class="m-doc-self">annotated</a>: float <span class="m-label m-flat m-success">get set del</span>
+ </dt>
+ <dd></dd>
+ <dt id="complex_annotation">
+ <a href="#complex_annotation" class="m-doc-self">complex_annotation</a>: typing.List[typing.Tuple[int, float]] <span class="m-label m-flat m-success">get set del</span>
+ </dt>
+ <dd>This is complex.</dd>
+ </dl>
+ </section>
+ <section id="data">
+ <h2><a href="#data">Data</a></h2>
+ <dl class="m-doc">
+ <dt id="unannotated">
+ <a href="#unannotated" class="m-doc-self">unannotated</a> = 4
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
annotated: float,
complex_annotation: typing.List[typing.Tuple[int, float]] = []) -> None</span>
</dt>
- <dd></dd>
+ <dd>Method generated by attrs for class MyClassAutoAttribs.</dd>
</dl>
</section>
<section id="properties">
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>inspect_attrs.MySlotClass | My Python Project</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+ <link rel="stylesheet" href="m-dark+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">My Python Project</a>
+ </div>
+ </div>
+</nav></header>
+<main><article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>
+ <span class="m-breadcrumb"><a href="inspect_attrs.html">inspect_attrs</a>.<wbr/></span>MySlotClass <span class="m-thin">class</span>
+ </h1>
+ <p>A class with attr-defined slots</p>
+ <div class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#dunder-methods">Special methods</a></li>
+ <li><a href="#properties">Properties</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ <section id="dunder-methods">
+ <h2><a href="#dunder-methods">Special methods</a></h2>
+ <dl class="m-doc">
+ <dt id="__init__">
+ <span class="m-doc-wrap-bumper">def <a href="#__init__" class="m-doc-self">__init__</a>(</span><span class="m-doc-wrap">self,
+ annotated: float,
+ complex_annotation: typing.List[typing.Tuple[int, float]] = [],
+ complex_annotation_in_attr: typing.List[typing.Tuple[int, float]] = []) -> None</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="properties">
+ <h2><a href="#properties">Properties</a></h2>
+ <dl class="m-doc">
+ <dt id="annotated">
+ <a href="#annotated" class="m-doc-self">annotated</a>: float <span class="m-label m-flat m-success">get set del</span>
+ </dt>
+ <dd></dd>
+ <dt id="complex_annotation">
+ <a href="#complex_annotation" class="m-doc-self">complex_annotation</a>: typing.List[typing.Tuple[int, float]] <span class="m-label m-flat m-success">get set del</span>
+ </dt>
+ <dd></dd>
+ <dt id="complex_annotation_in_attr">
+ <a href="#complex_annotation_in_attr" class="m-doc-self">complex_annotation_in_attr</a>: typing.List[typing.Tuple[int, float]] <span class="m-label m-flat m-success">get set del</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
complex_annotation: typing.List[typing.Tuple[int, float]] = [],
complex_annotation_in_attr: typing.List[typing.Tuple[int, float]] = []) -> None</span>
</dt>
- <dd></dd>
+ <dd>Method generated by attrs for class MySlotClass.</dd>
</dl>
</section>
<section id="properties">
'ATTRS_COMPATIBILITY': True
})
self.assertEqual(*self.actual_expected_contents('inspect_attrs.MyClass.html'))
- self.assertEqual(*self.actual_expected_contents('inspect_attrs.MyClassAutoAttribs.html'))
- self.assertEqual(*self.actual_expected_contents('inspect_attrs.MySlotClass.html'))
+ if attr.__version_info__ >= (20, 1):
+ self.assertEqual(*self.actual_expected_contents('inspect_attrs.MyClassAutoAttribs.html'))
+ self.assertEqual(*self.actual_expected_contents('inspect_attrs.MySlotClass.html'))
+ else:
+ self.assertEqual(*self.actual_expected_contents('inspect_attrs.MyClassAutoAttribs.html', 'inspect_attrs.MyClassAutoAttribs-attrs193.html'))
+ self.assertEqual(*self.actual_expected_contents('inspect_attrs.MySlotClass.html', 'inspect_attrs.MySlotClass-attrs193.html'))
class Underscored(BaseInspectTestCase):
def test(self):
install-python-deps:
parameters:
+ attrs-version:
+ type: string
+ default: ""
matplotlib-version:
type: string
default: ""
name: Install Python dependencies
# Matplotlib 3.5.1 has different order of attributes than 3.4, so can't
# just use the latest (and 3.4 is not on the Python 3.6 image)
- # Attrs 20.3 add some new properties that I need to ignore first, using
- # 19.3 instead
# Pygments 2.11 (and apparently 2.10 as well) treats certain whitespace
# differently, I have to update the expected output first.
# Docutils 0.18 drops some attribute that htmlsanity relies on, I need
# to update the code first.
command: |
- pip install jinja2 docutils==0.17.1 pygments==2.9.0 pelican Pyphen Pillow coverage codecov qrcode matplotlib<< parameters.matplotlib-version >> attrs==19.3.0
+ pip install jinja2 docutils==0.17.1 pygments==2.9.0 pelican Pyphen Pillow coverage codecov qrcode matplotlib<< parameters.matplotlib-version >> attrs<< parameters.attrs-version >>
- run:
name: Fix unheard-of cursed issues
# otherwise i get Error: unsupported locale setting
- install-base:
extra: graphviz cmake ninja-build wget
- install-python-deps:
+ # Since 3.6 is EOL'd, using this job to test with older versions of
+ # various packages to avoid regressions
+ attrs-version: ==19.3.0
matplotlib-version: ==3.3.4
- checkout
- test-theme