Skip to content

Commit

Permalink
run pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Jul 8, 2024
1 parent c3af692 commit c5d073b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
build/*
publish/*
.git/
.git/
4 changes: 2 additions & 2 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ jobs:
run: |
import yaml, os
def add_to_env_and_outputs(name, value):
for var in ('GITHUB_OUTPUT', 'GITHUB_ENV'):
for var in ('GITHUB_OUTPUT', 'GITHUB_ENV'):
with open(os.environ[var], 'a') as fh:
print(f'{name}={value}', file=fh)
with open('pyqgis_conf.yml', 'r') as f:
cfg = yaml.safe_load(f)
version_list = cfg['version_list'].replace(' ', '').split(',')
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ source/i18n/*/conf.py
source/static/
sphinx_rtd_theme/
.token*

79 changes: 43 additions & 36 deletions autoautosummary.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
# see https://stackoverflow.com/questions/20569011/python-sphinx-autosummary-automated-listing-of-member-functions
# added toctree and nosignatures in options

from sphinx.ext.autosummary import Autosummary
from sphinx.ext.autosummary import get_documenter
from docutils.parsers.rst import directives
from sphinx.util.inspect import safe_getattr
# from sphinx.directives import directive
from enum import Enum

import PyQt5
from docutils import nodes
from enum import Enum
from docutils.parsers.rst import directives
from sphinx.ext.autosummary import Autosummary, get_documenter
from sphinx.util.inspect import safe_getattr

# from sphinx.directives import directive


class AutoAutoSummary(Autosummary):
Expand All @@ -22,13 +22,14 @@ class AutoAutoSummary(Autosummary):
see https://stackoverflow.com/questions/20569011/python-sphinx-autosummary-automated-listing-of-member-functions
"""

option_spec = {
'methods': directives.unchanged,
'signals': directives.unchanged,
'enums': directives.unchanged,
'attributes': directives.unchanged,
'nosignatures': directives.unchanged,
'toctree': directives.unchanged
"methods": directives.unchanged,
"signals": directives.unchanged,
"enums": directives.unchanged,
"attributes": directives.unchanged,
"nosignatures": directives.unchanged,
"toctree": directives.unchanged,
}

required_arguments = 1
Expand All @@ -46,20 +47,22 @@ def get_members(doc, obj, typ, include_public=None, signal=False, enum=False):
try:
chobj = safe_getattr(obj, name)
documenter = get_documenter(doc.settings.env.app, chobj, obj)
#cl = get_class_that_defined_method(chobj)
#print(name, chobj.__qualname__, type(chobj), issubclass(chobj, Enum), documenter.objtype)
# cl = get_class_that_defined_method(chobj)
# print(name, chobj.__qualname__, type(chobj), issubclass(chobj, Enum), documenter.objtype)
if documenter.objtype == typ:
if typ == 'attribute':
if signal and type(chobj) != PyQt5.QtCore.pyqtSignal:
if typ == "attribute":
if signal and isinstance(chobj, PyQt5.QtCore.pyqtSignal):
continue
if not signal and type(chobj) == PyQt5.QtCore.pyqtSignal:
if not signal and isinstance(chobj, PyQt5.QtCore.pyqtSignal):
continue
# skip monkey patched enums
# the monkeypatched enums coming out of scoped enum inherit Enum
# while the standard/old ones do not
if hasattr(chobj, '__objclass__') and issubclass(chobj.__objclass__, Enum):
if hasattr(chobj, "__objclass__") and issubclass(
chobj.__objclass__, Enum
):
continue
elif typ == 'class':
elif typ == "class":
if enum:
if not issubclass(chobj, Enum):
continue
Expand All @@ -68,7 +71,7 @@ def get_members(doc, obj, typ, include_public=None, signal=False, enum=False):
items.append(name)
except AttributeError:
continue
public = [x for x in items if x in include_public or not x.startswith('_')]
public = [x for x in items if x in include_public or not x.startswith("_")]
return public, items
except BaseException as e:
print(str(e))
Expand All @@ -80,25 +83,29 @@ def run(self):
rubric_elems = None
rubric_public_elems = None
try:
(module_name, class_name) = clazz.rsplit('.', 1)
(module_name, class_name) = clazz.rsplit(".", 1)
m = __import__(module_name, globals(), locals(), [class_name])
c = getattr(m, class_name)
if 'methods' in self.options:
rubric_title = 'Methods'
_, rubric_elems = self.get_members(self.state.document, c, 'method', ['__init__'])
elif 'enums' in self.options:
rubric_title = 'Enums'
_, rubric_elems = self.get_members(self.state.document, c, 'class', None, False, True)
elif 'signals' in self.options:
rubric_title = 'Signals'
_, rubric_elems = self.get_members(self.state.document, c, 'attribute', None, True)
elif 'attributes' in self.options:
rubric_title = 'Attributes'
_, rubric_elems = self.get_members(self.state.document, c, 'attribute', None, False)
if "methods" in self.options:
rubric_title = "Methods"
_, rubric_elems = self.get_members(self.state.document, c, "method", ["__init__"])
elif "enums" in self.options:
rubric_title = "Enums"
_, rubric_elems = self.get_members(
self.state.document, c, "class", None, False, True
)
elif "signals" in self.options:
rubric_title = "Signals"
_, rubric_elems = self.get_members(self.state.document, c, "attribute", None, True)
elif "attributes" in self.options:
rubric_title = "Attributes"
_, rubric_elems = self.get_members(
self.state.document, c, "attribute", None, False
)

if rubric_elems:
rubric_public_elems = list(filter(lambda e: not e.startswith('_'), rubric_elems))
self.content = ["~%s.%s" % (clazz, elem) for elem in rubric_public_elems]
rubric_public_elems = list(filter(lambda e: not e.startswith("_"), rubric_elems))
self.content = [f"~{clazz}.{elem}" for elem in rubric_public_elems]
except BaseException as e:
print(str(e))
raise e
Expand All @@ -107,6 +114,6 @@ def run(self):
ret = super().run()
if rubric_title:
if rubric_public_elems and len(rubric_public_elems) > 0:
rub = nodes.rubric('', rubric_title)
rub = nodes.rubric("", rubric_title)
ret.insert(0, rub)
return ret
1 change: 0 additions & 1 deletion conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,3 @@ def setup(app):
app.connect('autodoc-skip-member', skip_member)
except BaseException as e:
raise e

66 changes: 34 additions & 32 deletions process_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
#
# This logic has been copied from the existing extension with some tuning for PyQGIS

import re
import enum
import yaml
import re

import yaml

with open('pyqgis_conf.yml', 'r') as f:
with open("pyqgis_conf.yml") as f:
cfg = yaml.safe_load(f)


Expand All @@ -19,40 +19,45 @@

# https://regex101.com/r/lSB3rK/2/
py_ext_sig_re = re.compile(
r'''^ ([\w.]+::)? # explicit module name
r"""^ ([\w.]+::)? # explicit module name
([\w.]+\.)? # module and/or class name(s)
(\w+) \s* # thing name
(?: \((.*)\) # optional: arguments
(?:\s* -> \s* ([\w.]+(?:\[.*?\])?))? # return annotation
(?:\s* \[(signal)\])? # is signal
)? $ # and nothing more
''', re.VERBOSE)
""",
re.VERBOSE,
)


def show_inheritance(obj):
# handle inheritance printing to patch qgis._core with qgis.core
# https://github.com/sphinx-doc/sphinx/blob/685e3fdb49c42b464e09ec955e1033e2a8729fff/sphinx/ext/autodoc/__init__.py#L1103-L1109
if hasattr(obj, '__bases__') and len(obj.__bases__):
bases = [b.__module__ in ('__builtin__', 'builtins') and
':class:`%s`' % b.__name__ or
':class:`%s.%s`' % (b.__module__, b.__name__)
for b in obj.__bases__]
return 'Bases: %s' % ', '.join(bases)
if hasattr(obj, "__bases__") and len(obj.__bases__):
bases = [
b.__module__ in ("__builtin__", "builtins")
and ":class:`%s`" % b.__name__
or f":class:`{b.__module__}.{b.__name__}`"
for b in obj.__bases__
]
return "Bases: %s" % ", ".join(bases)
return None


def create_links(doc: str) -> str:
# fix inheritance
doc = re.sub(r'qgis\._(core|gui|analysis|processing)\.', r'', doc)
doc = re.sub(r"qgis\._(core|gui|analysis|processing)\.", r"", doc)
# class
doc = re.sub(r'\b(Qgi?s[A-Z]\w+)([, )]|\. )', r':py:class:`.\1`\2', doc)
doc = re.sub(r"\b(Qgi?s[A-Z]\w+)([, )]|\. )", r":py:class:`.\1`\2", doc)
return doc


def process_docstring(app, what, name, obj, options, lines):
# print('d', what, name, obj, options)
bases = show_inheritance(obj)
if bases:
lines.insert(0, '')
lines.insert(0, "")
lines.insert(0, bases)

for i in range(len(lines)):
Expand All @@ -62,25 +67,25 @@ def process_docstring(app, what, name, obj, options, lines):
lines[i] = create_links(lines[i])

# add return type and param type
if what != 'class' and not isinstance(obj, enum.EnumMeta) and obj.__doc__:
signature = obj.__doc__.split('\n')[0]
if signature != '':
if what != "class" and not isinstance(obj, enum.EnumMeta) and obj.__doc__:
signature = obj.__doc__.split("\n")[0]
if signature != "":
match = py_ext_sig_re.match(signature)
if not match:
print(obj)
if name not in cfg['non-instantiable']:
raise Warning('invalid signature for {}: {}'.format(name, signature))
if name not in cfg["non-instantiable"]:
raise Warning(f"invalid signature for {name}: {signature}")
else:
exmod, path, base, args, retann, signal = match.groups()

if args:
args = args.split(', ')
args = args.split(", ")
for arg in args:
try:
argname, hint = arg.split(': ')
argname, hint = arg.split(": ")
except ValueError:
continue
searchfor = ':param {}:'.format(argname)
searchfor = f":param {argname}:"
insert_index = None

for i, line in enumerate(lines):
Expand All @@ -93,28 +98,25 @@ def process_docstring(app, what, name, obj, options, lines):
insert_index = len(lines)

if insert_index is not None:
lines.insert(
insert_index,
':type {}: {}'.format(argname, create_links(hint))
)
lines.insert(insert_index, f":type {argname}: {create_links(hint)}")

if retann:
insert_index = len(lines)
for i, line in enumerate(lines):
if line.startswith(':rtype:'):
if line.startswith(":rtype:"):
insert_index = None
break
elif line.startswith(':return:') or line.startswith(':returns:'):
elif line.startswith(":return:") or line.startswith(":returns:"):
insert_index = i

if insert_index is not None:
if insert_index == len(lines):
# Ensure that :rtype: doesn't get joined with a paragraph of text, which
# prevents it being interpreted.
lines.append('')
lines.append("")
insert_index += 1

lines.insert(insert_index, ':rtype: {}'.format(create_links(retann)))
lines.insert(insert_index, f":rtype: {create_links(retann)}")


def process_signature(app, what, name, obj, options, signature, return_annotation):
Expand All @@ -125,7 +127,7 @@ def process_signature(app, what, name, obj, options, signature, return_annotatio

def skip_member(app, what, name, obj, skip, options):
# skip monkey patched enums (base classes are different)
if hasattr(obj, 'is_monkey_patched') and obj.is_monkey_patched:
print(f'skipping monkey patched enum {name}')
if hasattr(obj, "is_monkey_patched") and obj.is_monkey_patched:
print(f"skipping monkey patched enum {name}")
return True
return skip
Loading

0 comments on commit c5d073b

Please sign in to comment.