[PATCH v2 11/11] docs: maintainers_include: parse MAINTAINERS just once

Mauro Carvalho Chehab
2026-04-17T06:11:27Z

Change the logic to parse MAINTAINERS file content just once,
while still allowing using it multiple times.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
Documentation/sphinx/maintainers_include.py | 61 +++++++--------------
1 file changed, 21 insertions(+), 40 deletions(-)

diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py
index ae52e8198750..436e7ac42ffc 100755
--- a/Documentation/sphinx/maintainers_include.py
+++ b/Documentation/sphinx/maintainers_include.py
@@ -37,14 +37,13 @@ def ErrorString(exc): # Shamelessly stolen from docutils

__version__ = '1.0'

-app_dir = "."
+maint_parser = None

class MaintainersParser:
"""Parse MAINTAINERS file(s) content"""

- def __init__(self, path):
- global app_dir
-
+ def __init__(self, app_dir, path):
+ self.path = path
self.profile_toc = set()
self.profile_entries = {}

@@ -67,7 +66,6 @@ class MaintainersParser:
subsystem_name = None

base_dir, doc_dir, sphinx_dir = app_dir.partition("Documentation")
- print("BASE DIR", base_dir)

for line in open(path):
# Have we reached the end of the preformatted Descriptions text?
@@ -105,8 +103,6 @@ class MaintainersParser:
else:
entry = "/" + entry

- print(f"{name}: entry: {entry} FULL: {full_name} path: {path}")
-
if "*" in entry:
for e in glob(entry):
self.profile_toc.add(e)
@@ -217,14 +213,17 @@ class MaintainersInclude(Include):
"""MaintainersInclude (``maintainers-include``) directive"""
required_arguments = 0

- def emit(self, path):
+ def emit(self):
"""Parse all the MAINTAINERS lines into ReST for human-readability"""
+ global maint_parser

- output = MaintainersParser(path).output
+ path = maint_parser.path
+ output = maint_parser.output

# For debugging the pre-rendered results...
#print(output, file=open("/tmp/MAINTAINERS.rst", "w"))

+ self.state.document.settings.record_dependencies.add(path)
self.state_machine.insert_input(statemachine.string2lines(output), path)

def run(self):
@@ -232,19 +231,8 @@ class MaintainersInclude(Include):
if not self.state.document.settings.file_insertion_enabled:
raise self.warning('"%s" directive disabled.' % self.name)

- # Walk up source path directories to find Documentation/../
- path = self.state_machine.document.attributes['source']
- path = os.path.realpath(path)
- tail = path
- while tail != "Documentation" and tail != "":
- (path, tail) = os.path.split(path)
-
- # Append "MAINTAINERS"
- path = os.path.join(path, "MAINTAINERS")
-
try:
- self.state.document.settings.record_dependencies.add(path)
- lines = self.emit(path)
+ lines = self.emit()
except IOError as error:
raise self.severe('Problems with "%s" directive path:\n%s.' %
(self.name, ErrorString(error)))
@@ -254,16 +242,17 @@ class MaintainersInclude(Include):
class MaintainersProfile(Include):
required_arguments = 0

- def emit(self, path):
+ def emit(self):
"""Parse all the MAINTAINERS lines looking for profile entries"""
+ global maint_parser

- maint = MaintainersParser(path)
+ path = maint_parser.path

#
# Produce a list with all maintainer profiles, sorted by subsystem name
#
output = ""
- for profile, entry in sorted(maint.profile_entries.items()):
+ for profile, entry in sorted(maint_parser.profile_entries.items()):
if entry.startswith("http"):
output += f"- `{profile} <{entry}>`_\n"
else:
@@ -276,13 +265,12 @@ class MaintainersProfile(Include):
output += "\n.. toctree::\n"
output += " :hidden:\n\n"

- for fname in maint.profile_toc:
+ for fname in maint_parser.profile_toc:
output += f" {fname}\n"

output += "\n"

- print(output)
-
+ self.state.document.settings.record_dependencies.add(path)
self.state_machine.insert_input(statemachine.string2lines(output), path)

def run(self):
@@ -290,19 +278,8 @@ class MaintainersProfile(Include):
if not self.state.document.settings.file_insertion_enabled:
raise self.warning('"%s" directive disabled.' % self.name)

- # Walk up source path directories to find Documentation/../
- path = self.state_machine.document.attributes['source']
- path = os.path.realpath(path)
- tail = path
- while tail != "Documentation" and tail != "":
- (path, tail) = os.path.split(path)
-
- # Append "MAINTAINERS"
- path = os.path.join(path, "MAINTAINERS")
-
try:
- self.state.document.settings.record_dependencies.add(path)
- lines = self.emit(path)
+ lines = self.emit()
except IOError as error:
raise self.severe('Problems with "%s" directive path:\n%s.' %
(self.name, ErrorString(error)))
@@ -310,13 +287,17 @@ class MaintainersProfile(Include):
return []

def setup(app):
- global app_dir
+ global maint_parser

#
# NOTE: we're using os.fspath() here because of a Sphinx warning:
# RemovedInSphinx90Warning: Sphinx 9 will drop support for representing paths as strings. Use "pathlib.Path" or "os.fspath" instead.
#
app_dir = os.fspath(app.srcdir)
+ srctree = os.path.abspath(os.environ["srctree"])
+ path = os.path.join(srctree, "MAINTAINERS")
+
+ maint_parser = MaintainersParser(app_dir, path)

app.add_directive("maintainers-include", MaintainersInclude)
app.add_directive("maintainers-profile-toc", MaintainersProfile)
--
2.53.0