chiark / gitweb /
documentation/python: adapt for attrs 20.1+.
authorVladimír Vondruš <mosra@centrum.cz>
Mon, 3 Jan 2022 12:22:45 +0000 (13:22 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Mon, 3 Jan 2022 12:30:12 +0000 (13:30 +0100)
Also starting to use the 3.6 CI job to test hacks for older packages.

documentation/python.py
documentation/test_python/inspect_attrs/inspect_attrs.MyClassAutoAttribs-attrs193.html [new file with mode: 0644]
documentation/test_python/inspect_attrs/inspect_attrs.MyClassAutoAttribs.html
documentation/test_python/inspect_attrs/inspect_attrs.MySlotClass-attrs193.html [new file with mode: 0644]
documentation/test_python/inspect_attrs/inspect_attrs.MySlotClass.html
documentation/test_python/test_inspect.py
package/ci/circleci.yml

index ac6028b9cd697d2f679370b178ba62967825f7d5..0955da752a459613835e17e177f2894444c97d58 100755 (executable)
@@ -329,6 +329,7 @@ _automatically_created_by_attrs = """
 _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
@@ -340,7 +341,19 @@ _filtered_attrs_functions = set([
     ('__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):
@@ -452,9 +465,14 @@ def crawl_class(state: State, path: List[str], class_):
                         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)
diff --git a/documentation/test_python/inspect_attrs/inspect_attrs.MyClassAutoAttribs-attrs193.html b/documentation/test_python/inspect_attrs/inspect_attrs.MyClassAutoAttribs-attrs193.html
new file mode 100644 (file)
index 0000000..e2c2300
--- /dev/null
@@ -0,0 +1,77 @@
+<!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]] = []) -&gt; 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>
index e2c23002d8ae4c87482eea09c77a33a27bdd8b7c..bf951880eb607512b316dbbe60285bb2a668b556 100644 (file)
@@ -44,7 +44,7 @@
               annotated: float,
               complex_annotation: typing.List[typing.Tuple[int, float]] = []) -&gt; None</span>
             </dt>
-            <dd></dd>
+            <dd>Method generated by attrs for class MyClassAutoAttribs.</dd>
           </dl>
         </section>
         <section id="properties">
diff --git a/documentation/test_python/inspect_attrs/inspect_attrs.MySlotClass-attrs193.html b/documentation/test_python/inspect_attrs/inspect_attrs.MySlotClass-attrs193.html
new file mode 100644 (file)
index 0000000..bfc0571
--- /dev/null
@@ -0,0 +1,72 @@
+<!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]] = []) -&gt; 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>
index bfc0571cbeb889dff6c96ae61d5485bedd62d76d..eb8b3fca5c98093d73fbbcca75b1bbbf92011a9c 100644 (file)
@@ -44,7 +44,7 @@
               complex_annotation: typing.List[typing.Tuple[int, float]] = [],
               complex_annotation_in_attr: typing.List[typing.Tuple[int, float]] = []) -&gt; None</span>
             </dt>
-            <dd></dd>
+            <dd>Method generated by attrs for class MySlotClass.</dd>
           </dl>
         </section>
         <section id="properties">
index 8c5a642aa0cbcffe110f9a5127d87d05bc1462be..feb385528862fb223295e013a0b2c1de5de95fdd 100644 (file)
@@ -249,8 +249,12 @@ class Attrs(BaseInspectTestCase):
             '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):
index 06727fccc22604d777d63164c8e41bf6735ce1c3..9f500a521e791d5bab8971201b1b60727aeeb3eb 100644 (file)
@@ -45,6 +45,9 @@ commands:
 
   install-python-deps:
     parameters:
+      attrs-version:
+        type: string
+        default: ""
       matplotlib-version:
         type: string
         default: ""
@@ -53,14 +56,12 @@ commands:
         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
@@ -181,6 +182,9 @@ jobs:
     - 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