From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5D633ACF01; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=GitdkBy/O9G1XUPWLBfe0PeKqBARNP8RBHEDJm5d1MNm8djA72duyP0yutBluLHi6YGK7ou3Ur/MCsSb2JsbzKJkif1yUGLa+vfIaW/QFdlxv9weLWXqUi8/XYL4bDnoE2Gji+4w3zfJDIXslnqFFbs/Rf7/druqb+P/t+PuiZw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=c+lWtus7uYVGOL7ZaUEaEUQ07MpkIkG4WhZzL62rQhY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PXqfI5Fv6vpwwP9xrhjkseVtlVSLUIAHMaKyhVNTmy1p7eTa2dz/YluRO1AhiOFZ+bakOTjr7qT0pWHzmVIpxEN1z/LMZKqKSkAG0QmQ0yV6dDG4+/9pA2Zy21/q0EQfokoHOv3Lq083VrPvLd7rJ8Jprk2BaRXl/f1GxHGUuvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MGuPs9xj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MGuPs9xj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DFCB2C2BCB0; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=c+lWtus7uYVGOL7ZaUEaEUQ07MpkIkG4WhZzL62rQhY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MGuPs9xjUkE5gdBJmQr4gw+D29rzhHUuMRDvBDGbmfB3nxC3RqZ3dwfbiO6hvwL3A uqHV5fJ06hfLK87n+JFNl/MKoD/0OmOB8kPsh/SVphgxQy2tM1UodiKL3Vipyam+25 TD1YjUyUrYR+XDJYvtEX67xWKu3lK42s8bwfY3w/EMgqRpdWLG90RTWsOpxZucTYGp z/+0BXRj+5ksZUttwFT3ip9jcUQLvND3ChvwGWbVkVMavcG+nh1FO25AT8aPQYMLRH 6iX1fSla1xILO68Ga5RMrOgEEgYeg2CE5bUa+9y53XM0B3UssQHFzzQixUyNz6Xl5N DgbRvLWj1fYUw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027U8-3NzE; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List , Mauro Carvalho Chehab Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Shuah Khan Subject: [PATCH 01/15] unittests: unittest_helper: store verbosity at the environment Date: Tue, 3 Feb 2026 15:55:29 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab As tests may want to add their own verbosed messages, pass the defined verbosity level to the test classes via env. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/unittest_helper.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/lib/python/unittest_helper.py b/tools/lib/python/unittes= t_helper.py index d2efb78d8561..55d444cd73d4 100755 --- a/tools/lib/python/unittest_helper.py +++ b/tools/lib/python/unittest_helper.py @@ -279,14 +279,19 @@ class TestUnits: if not caller_file and not suite: raise TypeError("Either caller_file or suite is needed at Test= Units") =20 - if env: - patcher =3D patch.dict(os.environ, env) - patcher.start() - # ensure it gets stopped after - atexit.register(patcher.stop) - verbose =3D args.verbose =20 + if not env: + env =3D os.environ.copy() + + env["VERBOSE"] =3D f"{verbose}" + + patcher =3D patch.dict(os.environ, env) + patcher.start() + # ensure it gets stopped after + atexit.register(patcher.stop) + + if verbose >=3D 2: unittest.TextTestRunner(verbosity=3Dverbose).run =3D lambda su= ite: suite =20 --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 447B33EBF36; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=jyj0dMi3DzTvzLTV7kty9YeZGdCyI4zCZ/VFH6tqmre2Me86rf6JYtGbO3Uk7Kk2YBTLFZsOCnG9DxLozLkl9gfA4BfwOjhVFK9BqkJrHr7rOTw+RiZG4CEUFbXC8SBxHY6Ri/9foxmgFN6sSO9nzGaC/PXhrC49sU3nSGJIW14= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=6TUEdCCxf08mni1+KzD0z773NWtkiX5r/4OgHtBbpcY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EVtFaDeRcT9N0o/ywQ++iRIYd2JMEHdC8JRuKUfYoWFPgOF6No0so4RAbxU+7dl61HMcw+yOKtAvyS3hQDtoEsHy3TEXHBkrkLiVmt6rwUdMO9h2gaL4SSP7WV9VxEzEFt6Grr6K/GnQoWG1mwa+Gi6ao4iwGk4qGaKFnrTLMdE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f/bQSeNP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f/bQSeNP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CC5F0C19425; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=6TUEdCCxf08mni1+KzD0z773NWtkiX5r/4OgHtBbpcY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f/bQSeNPKVBnGLOf+itkb2gDEcFCKRHYs+aiw6PiKdgLt4o71F3N5tr76bcNpMNPN 3vEZBdVFIiC6PHGZcagl86QcjVryyX2m7oRKDzOdGu4IQGVRtiOVRJ4kGIkE4tj38i uERQ7br/KO6UvRtiQF/ENIbwhf3JuFSxAiYF9V4+XdhXpggJKNy1TQ6iMN/CCnzJyp z9iAaF3+G55eaCwhBxjMtagO585LYHdTr/VVOir1IqdnboQCw61cFSbWdARZodtZxv OakLzPCrEByihX5r/4YtYMMvI66sM55GXqM6qiwZT8QK/FMD+LkS0TWJl61Gi1jRsa pLajFLtzStm2g== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027UC-3Vdm; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 02/15] unittests: rename kdoc_xforms.py Date: Tue, 3 Feb 2026 15:55:30 +0100 Message-ID: <3ebef224a92a4661e187130763b8bd4096054056.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Let's start all tests with "tests_", as this makes easer to have an unique runner for all tests. So: tools/unittests/kdoc_xforms.py -> tools/unittests/test_kdoc_xforms.py No changes at the code. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/{kdoc_xforms.py =3D> test_kdoc_xforms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/unittests/{kdoc_xforms.py =3D> test_kdoc_xforms.py} (100%) diff --git a/tools/unittests/kdoc_xforms.py b/tools/unittests/test_kdoc_xfo= rms.py similarity index 100% rename from tools/unittests/kdoc_xforms.py rename to tools/unittests/test_kdoc_xforms.py --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A29C33ACF00; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=ATYyUXtyG9/TR3Syt00un0967TG+FSCbN37usHptiUPKlNYhB1l2lzVrsdZw4n4L7y46Ni28TxiUJzF7R+67Lr/q0b9kdrdQI8IGJXVW+ehg+fc2LAIQQS3db7eIoCu6U9bVfldAzaPwkqPmUa4w3G7p+6XBtMJ7l3ndHKRIzBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=PaOLRDk0iXEcEwnWCzqzsJpfgjdAgDVAImrhDci59t0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Db9t8wO7dKwuxxgx2owYTHkxHZV1cGiiNFI9ZcZvjXPyz5qZpS6k3K0ugtiID/wOmWEClGvGmEmOfUjoDjXlYcAtroBxQr9rhQIPgHHKC0oG2UEALwnVeSX6lNbnzqm4UO+zF1yCpIrw+zefXolwZwSn9mY5GpxihsG9z1vTyjk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I1hn9eZu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="I1hn9eZu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D149FC19421; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=PaOLRDk0iXEcEwnWCzqzsJpfgjdAgDVAImrhDci59t0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I1hn9eZuOhs+VkCXrq2GGv2yAIF1R19EMOw09r7vylNK5xcOun/eGN5cJ0Yieslpd aNWM8UUSJqXjZRG5ODUfTLOrq3hKxsMHSUPY8hFKe4tb1IA54ZhkJGI1BGvRaxYc0U gpda/OI0ekDOR7VKjlFVSCvN9G8RvOEizWZqVd1j+1FH3De/Us2ffpl4EwqMHpPMYy +r92h3ogzzzHF1nEoHxuIrc6c+Appnq+v6nv9Vxlwysaqrs79AhPCVg2XU85LiXwJZ b9l9Q2RMZLrqoA7eNZTRwduPmKjo/Y9TVneGLT1jzmjMRPgh4om4qMcWvgG4PSpGtz 7KlzFy/Y562hQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027UG-3clW; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 03/15] unittests: add a runner to execute all unittests Date: Tue, 3 Feb 2026 15:55:31 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab We'll soon have multiple unit tests, add a runner that will discover all of them and execute all tests. It was opted to discover only files that starts with "test", as this way unittest discover won't try adding libraries or other stuff that might not contain unittest classes. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/run.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 tools/unittests/run.py diff --git a/tools/unittests/run.py b/tools/unittests/run.py new file mode 100755 index 000000000000..8c19036d43a1 --- /dev/null +++ b/tools/unittests/run.py @@ -0,0 +1,17 @@ +#!/bin/env python3 +import os +import unittest +import sys + +TOOLS_DIR=3Dos.path.join(os.path.dirname(os.path.realpath(__file__)), "..") +sys.path.insert(0, TOOLS_DIR) + +from lib.python.unittest_helper import TestUnits + +if __name__ =3D=3D "__main__": + loader =3D unittest.TestLoader() + + suite =3D loader.discover(start_dir=3Dos.path.join(TOOLS_DIR, "unittes= ts"), + pattern=3D"test*.py") + + TestUnits().run("", suite=3Dsuite) --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE6AE3ACF0A; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130556; cv=none; b=p4c8m3t9818O+V4XNg0Yy8zip6WZmRmDcrcC4QG/SuL8ZhN5aHA3OfcKRPFEUKHgMIvzKk33Ra7Iy6MXvbbB54tK90AVWy62Ql8hr/gcdrN4hpEEUnckzNHbqB6uSzFfeJIDUEx4y3wCaxLJAA+8HZWkxOdOdi26Z6w2jPbCKqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130556; c=relaxed/simple; bh=oYC2GDc/Bqbgq6yNVkLkZHK+JYaKpKvhsSMfDzpAVDw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L9dFvz8T0b9feSY7Err3Ll4teDs1vDsCsE5o7Kh31Shl1Pd2GK70fOhOUrJ5nipLM7PuaVrqMCgXMKrb9WrOEiBij1vjdu7BCl2R98l1SpKlkjqvuAydkS33sipg7CjaxEXMQmYz3sufxcbJMYHIIXUoZsRRMX8gR6ZJHvCIZuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=luSuWlcx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="luSuWlcx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E2638C2BCB1; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=oYC2GDc/Bqbgq6yNVkLkZHK+JYaKpKvhsSMfDzpAVDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=luSuWlcxOOfFHZykyos6xDVZrUMWIAd/9CNjdv+ApDoY/8jWuN0PEAt+hghKg1aD1 H7svdm2dcDuz+hMF83ewGK7UNEwW+taoNlquclkdZtZLgC8XFvQXeNRaD6fwzvwTXm j65wJdgdV2mRwsAVnRIlmFRG6RgqR4u0O+L7eU8TcjqySrAt9CjaZ+ktfhzAIGBaai rYsrG9oY6SjUivUFw11JYv+BJi8d9WiAT4q5Hn7JYh0vfgVoFqxrHp+KlQh627DCdS v4UD1gmCt1eQkrX1QNPPCp6k0h+oex9AmfwDZc+3wngh1OE6lMb2y3ITXoqwRgtUh2 qcqJqCMC4zp+g== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027UK-3jsn; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 04/15] docs: kdoc_files: use a class to group config parameters Date: Tue, 3 Feb 2026 15:55:32 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Instead of abusing argparse.Namespace, define a class to store configuration parameters and logger. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_files.py | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 8c2059623949..1c5cb9e5f0e8 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -9,7 +9,6 @@ Classes for navigating through the files that kernel-doc ne= eds to handle to generate documentation. """ =20 -import argparse import logging import os import re @@ -87,6 +86,28 @@ class GlobSourceFiles: file_not_found_cb(fname) =20 =20 +class KdocConfig(): + """ + Stores all configuration attributes that kdoc_parser and kdoc_output + needs. + """ + def __init__(self, verbose=3DFalse, werror=3DFalse, wreturn=3DFalse, + wshort_desc=3DFalse, wcontents_before_sections=3DFalse, + logger=3DNone): + + self.verbose =3D verbose + self.werror =3D werror + self.wreturn =3D wreturn + self.wshort_desc =3D wshort_desc + self.wcontents_before_sections =3D wcontents_before_sections + + if logger: + self.log =3D logger + else: + self.log =3D logging.getLogger(__file__) + + self.warning =3D self.log.warning + class KernelFiles(): """ Parse kernel-doc tags on multiple kernel source files. @@ -224,29 +245,25 @@ class KernelFiles(): if kdoc_werror: werror =3D kdoc_werror =20 + if not logger: + logger =3D logging.getLogger("kernel-doc") + else: + logger =3D logger + # Some variables are global to the parser logic as a whole as they= are # used to send control configuration to KernelDoc class. As such, # those variables are read-only inside the KernelDoc. - self.config =3D argparse.Namespace + self.config =3D KdocConfig(verbose, werror, wreturn, wshort_desc, + wcontents_before_sections, logger) =20 - self.config.verbose =3D verbose - self.config.werror =3D werror - self.config.wreturn =3D wreturn - self.config.wshort_desc =3D wshort_desc - self.config.wcontents_before_sections =3D wcontents_before_sections + # Override log warning, as we want to count errors + self.config.warning =3D self.warning =20 if xforms: self.xforms =3D xforms else: self.xforms =3D CTransforms() =20 - if not logger: - self.config.log =3D logging.getLogger("kernel-doc") - else: - self.config.log =3D logger - - self.config.warning =3D self.warning - self.config.src_tree =3D os.environ.get("SRCTREE", None) =20 # Initialize variables that are internal to KernelFiles --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A08123ACEFD; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=IfEaCY9eI2iK1bz2PZ1NLPunCTOyZUHvb9Zuishe++BWOAR/f4nzcerSznjTAyH4hDbn1CXf46NRNjxQ8Q0TSfHtPylu276qlo/YgLwUh1fpoZPnv4b8arQ36yoOa1lt4liNUbCXZa8Wve9E1O/dzehPy72vDoa3TPDrGIWd+zc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=D+Yw/P1wo2Fe3Sse9jDq5scutU3896nHCn53LsY9Ih8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hya5Q1Bu07hPiWHQ/JbhBZwyM3PzUX1bAauqlkj0G9qhYAdxM1qgBlQEplYY3tV+pX0ASsIBACMA7e6PXDyZMj78xCflCXF7NHsU62iD8iUUq5OXwDhOqe23KHjg0M0P5vkg3NtCc5owiYuzsaChSDJsrkS64ncKHIMJEw/1eNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UtxuMrO4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UtxuMrO4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D6E53C4AF0B; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=D+Yw/P1wo2Fe3Sse9jDq5scutU3896nHCn53LsY9Ih8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UtxuMrO49Ra/ZBPDGjreRGGTyu4RY7XGuABGvJ2mTw/VIqIebsyXRJ9H7A+DJMasF EVx3jT7oX53ngTFIfHLTm2MVwfluhS2e8MqpHLNvNJJ7wOCw3dCeikPCcH3J6B2E2M 3t7u838xJ7CLOsxYo0A9HyMKgjmBOAqdPZzK2nq51hgaWc5LAcwifmQFGuWdXHTx5i DFKRuYjyg6Pkf2otPR82l3ThmSXcFcmYoL/mEdvwsIsq78er0Xuwp9SDd4umbkg/bQ pOxIc5iSSyMLz9ovw1NR7vGr/vNu/On0+VpLa2EUMF2Qr30Q9ekCeklyshqZqHcb9c CN/p7WneEPSuQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027UO-3rI4; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 05/15] docs: kdoc_files: move output symbols logic to kdoc_output Date: Tue, 3 Feb 2026 15:55:33 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab When writing unittests for kdoc_output, it became clear that the logic with handles a series of KdocItem symbols from a single file belons to kdoc_output, and not to kdoc_files. Move the code to it. While here, also ensure that self.config will be placed together with set.out_style. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_files.py | 18 ++---------------- tools/lib/python/kdoc/kdoc_output.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 1c5cb9e5f0e8..58f4ee08e226 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -269,6 +269,7 @@ class KernelFiles(): # Initialize variables that are internal to KernelFiles =20 self.out_style =3D out_style + self.out_style.set_config(self.config) =20 self.errors =3D 0 self.results =3D {} @@ -311,8 +312,6 @@ class KernelFiles(): returning kernel-doc markups on each interaction. """ =20 - self.out_style.set_config(self.config) - if not filenames: filenames =3D sorted(self.results.keys()) =20 @@ -336,25 +335,12 @@ class KernelFiles(): function_table, enable_lineno, no_doc_sections) =20 - msg =3D "" if fname not in self.results: self.config.log.warning("No kernel-doc for file %s", fname) continue =20 symbols =3D self.results[fname] - self.out_style.set_symbols(symbols) - - for arg in symbols: - m =3D self.out_msg(fname, arg.name, arg) - - if m is None: - ln =3D arg.get("ln", 0) - dtype =3D arg.get('type', "") - - self.config.log.warning("%s:%d Can't handle %s", - fname, ln, dtype) - else: - msg +=3D m =20 + msg =3D self.out_style.output_symbols(fname, symbols) if msg: yield fname, msg diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/k= doc_output.py index 44e40a6e8ca6..ece03cd9d321 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -222,6 +222,27 @@ class OutputFormat: =20 return None =20 + def output_symbols(self, fname, symbols): + """ + Handles a set of KdocItem symbols. + """ + self.set_symbols(symbols) + + msg =3D "" + for arg in symbols: + m =3D self.msg(fname, arg.name, arg) + + if m is None: + ln =3D arg.get("ln", 0) + dtype =3D arg.get('type', "") + + self.config.log.warning("%s:%d Can't handle %s", + fname, ln, dtype) + else: + msg +=3D m + + return msg + # Virtual methods to be overridden by inherited classes # At the base class, those do nothing. def set_symbols(self, symbols): --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A072C3ACEFB; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=j7rs6Q2Y9TtH+olHxnbqWH9dkBMzx/j6owBy3LZdTwQrLQNvcFR83Xp0Ey0gbpMJpr7nBC5p4wSwDcOdxyQ9GCsm3QVv3Ah5z5hrYis1ws8WEavqDtTjqeMNcOranIIGjh1DtJfv01BayLqGaUNSMifxYQd/8hLTVnyelE32TOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=rjYPYvJZXqQuJOofuiN0Kf8CTYyF0WAZo3QvwumSH8M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fvI/n1qj08Zsa8XYr3daE4aHeiwJqBs2k6JgU2a2j/z9t2FD70NiIuahCrcfE1aObg1S261j79F8kgwU91IsbP4cBIafTTSfXtzMAxHlQWApUfPuFJfgg4PwlvQQVZN1HWM9O9tGc/3NCBRDcSnksi8u6ym8W8Zl+Bf1j1YhBK4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sRDN8GE7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sRDN8GE7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E218CC2BCB2; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=rjYPYvJZXqQuJOofuiN0Kf8CTYyF0WAZo3QvwumSH8M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sRDN8GE7yACx+mYYZqsJZJpUeBGrKHPcjsn29FdMuyQ10AkIcqIbd49R8kgMkLtZZ MPvX62SV9bxBAANi0CB5XTy0gZCT8DlvEBjya6o4iGtL2wqxAJESwrJFIYu/5uynwC nr/5UrnVGyHEO0AcWWuwH6fSCORBe3qyzXauSEYD0voVGzY/WWuefW0/hJ1KVTIlg7 TQ1TwVlh5bBXq0VlpU5kjEAX1tl6qcTRWlRvdM5h864RsxBg3Vcy6ghJBWCikNhyJp 7ua5G5dlLZx0DwGLqZSbQbNvdT3QkHfAPjnQqFl4F7pf4LnbGGFRDMMaFwYIbFO6e3 L5hy9/dH59QmQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027US-3yRi; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 06/15] docs: kdoc_item: fix initial value for parameterdesc_start_lines Date: Tue, 3 Feb 2026 15:55:34 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Ensure that parameterdesc_start_lines is a dict at init time, as this is how it will be set later on at the parser. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index 2b8a93f79716..c0585cdbcbd1 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -22,7 +22,7 @@ class KdocItem: self.sections =3D {} self.sections_start_lines =3D {} self.parameterlist =3D [] - self.parameterdesc_start_lines =3D [] + self.parameterdesc_start_lines =3D {} self.parameterdescs =3D {} self.parametertypes =3D {} # --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5971A394497; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=EvUNk4St1HLcNlX9XHA1N96N/cQv8vfHw8Y09oGfEtU/OjSuLft5sARqfdth9k0/iNYhUbEMn2nXHxU/c2I/SH/1uaTCbSGS+YqQl5rC5bm4kto3Fd7llW8uXYifEl3lQF3/BXF8dzg+OA/6xOZ+QsZYBuvdPY6hzZArlORmMvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=12OPqlskckL5HqlY4jj0+cdjZZti4SPQGDREnmoAJkE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BOTf3WsmN0YU/O5EpF15OdI6qqvkyKOKXLSlKB5km2xylERfIEPgetK0vZTeJxvdPDP9CuHojyYfaZheyWDehBKkjzNjmS0rI0dkvzP5VzbEdMieUGvq+MXKSXwhExE+KaLuwVWIyoLADeZkx5cU9S/XRDDL35QPVSVfgoBWl6A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UF3f7nYZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UF3f7nYZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C40EEC116D0; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=12OPqlskckL5HqlY4jj0+cdjZZti4SPQGDREnmoAJkE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UF3f7nYZYJt6LtqA2Z3zw8NAsjuv9yMpfu6WiKu17rek7bSmj89fM+kusmyUie9d8 mlx6WQj3wtEuJW+bx1FwgLEg3IPtJitI9WaznY6CVQx3Tb+UvcD+nAp6uK7gqadp9u mI13SgvP6IZsu4lghJrb6oh+dhMwQLMTkiWrWwms90SiWjj6HaciGT2YKsYFUatGf5 UTXh6wjfYfzftZHQ2LrCdvr2KnphduVLFSn2s804ntBnlnOQGkbJq8jD4ovPz7ToUc kVdQayOCmV1z7UMpWxM+S9SstoOeAbhYrbnpKhtXd4P9V1364dsAmvpeN91yvjCrzU ZJQnkBvuCEUWw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHom-000000027UW-45YU; Tue, 03 Feb 2026 15:55:52 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 07/15] docs: kdoc_item: add support to generate a KdocItem from a dict Date: Tue, 3 Feb 2026 15:55:35 +0100 Message-ID: <01ec6c8007e9ccd40ab07e09b457912ea6866ac7.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab When reading the contents on a KdocItem using YAML, the data will be imported into a dict. Add a method to create a new KdocItem from a dict to allow converting such input into a real KdocItem. While here, address an issue that, if the class is initialized with an internal parameter outside the 4 initial arguments, it would end being added inside other_stuff, which breaks initializing it from a dict. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index c0585cdbcbd1..5f41790efacb 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -25,12 +25,31 @@ class KdocItem: self.parameterdesc_start_lines =3D {} self.parameterdescs =3D {} self.parametertypes =3D {} + + self.warnings =3D [] + # # Just save everything else into our own dict so that the output # side can grab it directly as before. As we move things into more # structured data, this will, hopefully, fade away. # - self.other_stuff =3D other_stuff + known_keys =3D { + 'declaration_start_line', + 'sections', + 'sections_start_lines', + 'parameterlist', + 'parameterdesc_start_lines', + 'parameterdescs', + 'parametertypes', + 'warnings', + } + + self.other_stuff =3D {} + for k, v in other_stuff.items(): + if k in known_keys: + setattr(self, k, v) # real attribute + else: + self.other_stuff[k] =3D v =20 def get(self, key, default =3D None): """ @@ -41,6 +60,20 @@ class KdocItem: def __getitem__(self, key): return self.get(key) =20 + @classmethod + def from_dict(cls, d): + """Create a KdocItem from a plain dict.""" + + cp =3D d.copy() + name =3D cp.pop('name', None) + fname =3D cp.pop('fname', None) + type =3D cp.pop('type', None) + start_line =3D cp.pop('start_line', 1) + other_stuff =3D cp.pop('other_stuff', {}) + + # Everything that=E2=80=99s left goes straight to __init__ + return cls(name, fname, type, start_line, **cp, **other_stuff) + # # Tracking of section and parameter information. # --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A254A3ACEFE; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=oy3sLthCN9nZi9qCAjRpu1zezErfJfFJM7TF0XFhZz3JasKUtLGY6X1cu3Um/OB3nYsAC1n+hUzxHIh2fLoCT7rR6HmLyYMF4rmd3tmfMa3aFjmIHu4fyXh1MEhr3rZXp4DEjORd6TNs7F4ZVAHZ0sq/OUYQpahz1xa9BCFeSrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=17maUKpPJIi7w1foiKEU2VL1TpBiPLMmE6g5vXMaPPg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Dk0Vhiv+igG+a44cPWF4dt63al0u59BlM30zJw3jO4f8uyE6pKkGJGZNTkblPICqk/9+tk6wSdmNeFsamUYl+dZNnsbTd3ObMKNlM64RPCdeef9hggrRW/IAF4WyZcUv4/7ZYfsu1KsLt7nHK6MjhOQdtqkH3OHBzTl5TOq6nPE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hN/0/vB8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hN/0/vB8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CEF3DC2BC86; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=17maUKpPJIi7w1foiKEU2VL1TpBiPLMmE6g5vXMaPPg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hN/0/vB8P2viE4jK2hZPmWbCPuy9ipAhbu6ODwL3O2A5CK7gg4R9qsExYYTK65+oP ZF4FZEXoDo85ba/U51i2ZqySOt6ZZ8MsH4VzP1/kh81ntU1xRgfz/IMa8tEXQ6px1c 50ryOvcbHaEmBvnVd9g9a5mXB1mdayGnuMr2PMWe3QV7NBq1T4YKGWGMWiwiTsUj/6 BR3EL5RCNEv8fpfxa8NjFtlz/hLFnrTS1lxUftnKbpj7THMU9t68bOcNVyWSAHovic P0PyuhmpZT8PXvFsmZCBise4nnZoYnXEIcvNpq4YUUWf9Wr5Bu0aqeAuxeiKP7zAZU 7W1tUCGUSyv4A== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Ua-00if; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Aleksandr Loktionov , Jani Nikula , Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 08/15] docs: kdoc_item: fix a typo on sections_start_lines Date: Tue, 3 Feb 2026 15:55:36 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Currently, there are 15 occurrences of section?_start_lines, with 10 using the plural way. This is an issue, as, while kdoc_output works with KdocItem, the term doesn't match its init value. The variable sections_start_lines stores multiple sections, so placing it in plural is its correct way. So, ensure that, on all parts of kdoc, this will be referred as sections_start_lines. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 2 +- tools/lib/python/kdoc/kdoc_output.py | 2 +- tools/lib/python/kdoc/kdoc_parser.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index 5f41790efacb..fe08cac861c2 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -82,7 +82,7 @@ class KdocItem: Set sections and start lines. """ self.sections =3D sections - self.section_start_lines =3D start_lines + self.sections_start_lines =3D start_lines =20 def set_params(self, names, descs, types, starts): """ diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/k= doc_output.py index ece03cd9d321..6ab5a13edbb5 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -389,7 +389,7 @@ class RestFormat(OutputFormat): else: self.data +=3D f'{self.lineprefix}**{section}**\n\n' =20 - self.print_lineno(args.section_start_lines.get(section, 0)) + self.print_lineno(args.sections_start_lines.get(section, 0)) self.output_highlight(text) self.data +=3D "\n" self.data +=3D "\n" diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/k= doc_parser.py index a280fe581937..940c848d4d80 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -152,7 +152,7 @@ class KernelEntry: self.parametertypes =3D {} self.parameterdesc_start_lines =3D {} =20 - self.section_start_lines =3D {} + self.sections_start_lines =3D {} self.sections =3D {} =20 self.anon_struct_union =3D False @@ -232,7 +232,7 @@ class KernelEntry: self.sections[name] +=3D '\n' + contents else: self.sections[name] =3D contents - self.section_start_lines[name] =3D self.new_start_line + self.sections_start_lines[name] =3D self.new_start_line self.new_start_line =3D 0 =20 # self.config.log.debug("Section: %s : %s", name, pformat(vars(self= ))) @@ -326,7 +326,7 @@ class KernelDoc: for section in ["Description", "Return"]: if section in sections and not sections[section].rstrip(): del sections[section] - item.set_sections(sections, self.entry.section_start_lines) + item.set_sections(sections, self.entry.sections_start_lines) item.set_params(self.entry.parameterlist, self.entry.parameterdesc= s, self.entry.parametertypes, self.entry.parameterdesc_start_lines) --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B0F23ACEFA; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=fdKqQjMiKq3+phNmijydZq8xcwIG5xdSl2AAq7wqdNe5PlaU5OqYumsvx7o2nT6wQ1JWPXHnxUu7p+FhjedXl5Yi5P8bQWw6tB7wapmSOBX9LZFxYWf8EbR6y5YH/4C7Aj+Al4I3L4USnWWTY1N43MMKWuwTmzCVl0/+kUuxHpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=NG3dg7pu+frczz+Zr/hP/7FD6w4QMq2rfMP2u6GHZtM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UKOY+sLlMDFL/EaD4oEG73I+M+Ms+McPQ26ZWFQXgXJW+UBuu6LrN15OVAeWUeMIc0fKjsECZiuqdWvo4rSZ2/1wFBgNLAnq+RyATKF4NKHrANVcfUnwECOSS6PqumRStZgRgvwbmlg4Er8mknAo2ihXtBv1WVTi6/MyNQV0M0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZxIKqZOW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZxIKqZOW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DC6ECC2BC87; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=NG3dg7pu+frczz+Zr/hP/7FD6w4QMq2rfMP2u6GHZtM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZxIKqZOW1G/9R7qtIn+1wUtTOSdXgPWo/du678TCWD7usQXpG5/VQmaywbEeDB3hB GDeb5PPwco9ZYcUV0DsLApsVqiSpPMYuMLK/u+shHf7oAr/n0pSx1S7988u912W7Go 700G9XRZdQfNLcZrJeGGYOeQr6y/rOBiBC/8Cb/oF8T1VLgpFPSm2qOWMgyUmtgOC7 ddvnnX5/QkQBYcqHxD0bAkCdfFHwnkYeiTDp91cfAtl52dxamyAHglE9WYdTrEftk2 +j54mwwMEdV+hcZeHj/nbhMaPpwbi+XX6E7/WTnpWY0oIXmDQ9GEqysjbmgB8V/oHI w0oATmsxvpazw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Ue-07jM; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 09/15] docs: unittests: add a parser to test kernel-doc parser logic Date: Tue, 3 Feb 2026 15:55:37 +0100 Message-ID: <89897c6344749de5cbf2b59a2a1ae24ff58154c1.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Validating that kernel-doc is parsing data properly is tricky. Add an unittest skeleton that alllows passing a source code and check if the corresponding values of export_table and entries returned by the parser are properly filled. It works by mocking a file input with the contents of a source string, an comparing if: - exports set matches; - expected KernelItem entries match. Create a new TestSelfValidate meant to check if the logic inside KdocParser.run_test() does its job of checking for differences inside KdocItem. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_kdoc_parser.py | 198 ++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100755 tools/unittests/test_kdoc_parser.py diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdo= c_parser.py new file mode 100755 index 000000000000..f3ff750ac0e9 --- /dev/null +++ b/tools/unittests/test_kdoc_parser.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . +# +# pylint: disable=3DC0200,C0413,W0102,R0914 + +""" +Unit tests for kernel-doc parser. +""" + +import os +import unittest +import re +import sys + +from textwrap import dedent +from unittest.mock import patch, MagicMock, mock_open + +SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) + +from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_item import KdocItem +from kdoc.xforms_lists import CTransforms +from unittest_helper import run_unittest + +#: Regex to help cleaning whitespaces +RE_WHITESPC =3D re.compile(r"\s++") + +def clean_whitespc(val, relax_whitespace=3DFalse): + """ + Cleanup whitespaces to avoid false positives. + + By default, strip only bein/end whitespaces, but, when relax_whitespace + is true, also replace multiple whitespaces in the middle. + """ + + if isinstance(val, str): + val =3D val.strip() + if relax_whitespace: + val =3D RE_WHITESPC.sub("", val) + elif isinstance(val, list): + val =3D [clean_whitespc(item, relax_whitespace) for item in val] + elif isinstance(val, dict): + val =3D {k: clean_whitespc(v, relax_whitespace) for k, v in val.it= ems()} + return val + +# +# Helper class to help mocking with +# +class KdocParser(unittest.TestCase): + """ + Base class to run KernelDoc parser class + """ + + DEFAULT =3D vars(KdocItem("", "", "", 0)) + + def setUp(self): + self.maxDiff =3D None + self.config =3D MagicMock() + self.config.log =3D MagicMock() + self.config.log.debug =3D MagicMock() + self.xforms =3D CTransforms() + + + def run_test(self, source, __expected_list, exports=3D{}, fname=3D"tes= t.c", + relax_whitespace=3DFalse): + """ + Stores expected values and patch the test to use source as + a "file" input. + """ + debug_level =3D int(os.getenv("VERBOSE", "0")) + source =3D dedent(source) + + # Ensure that default values will be there + expected_list =3D [] + for e in __expected_list: + new_e =3D self.DEFAULT.copy() + new_e["fname"] =3D fname + for key, value in e.items(): + new_e[key] =3D value + + expected_list.append(new_e) + + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + self.assertEqual(export_table, exports) + self.assertEqual(len(entries), len(expected_list)) + + for i in range(0, len(entries)): + + entry =3D entries[i] + expected =3D expected_list[i] + self.assertNotEqual(expected, None) + self.assertNotEqual(expected, {}) + self.assertIsInstance(entry, KdocItem) + + d =3D vars(entry) + for key, value in expected.items(): + result =3D clean_whitespc(d[key], relax_whitespace) + value =3D clean_whitespc(value, relax_whitespace) + + if debug_level > 1: + sys.stderr.write(f"{key}: assert('{result}' =3D=3D= '{value}')\n") + + self.assertEqual(result, value, msg=3Df"at {key}") + + +# +# Selttest class +# +class TestSelfValidate(KdocParser): + """ + Tests to check if logic inside KdocParser.run_test() is working. + """ + + SOURCE =3D """ + /** + * function3: Exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int function3(char *arg1) { return 0; }; + EXPORT_SYMBOL(function3); + """ + + EXPECTED =3D [{ + 'name': 'function3', + 'type': 'function', + 'declaration_start_line': 2, + + 'sections': { + 'Description': 'Does nothing\n\n', + 'Return': '\nalways return 0.\n' + }, + 'other_stuff': { + 'func_macro': False, + 'functiontype': 'int', + 'purpose': 'Exported function', + 'typedef': False + }, + 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, + 'parameterlist': ['arg1'], + 'parameterdesc_start_lines': {'arg1': 3}, + 'parametertypes': {'arg1': 'char *arg1'}, + }] + + EXPORTS =3D {"function3"} + + def test_parse_pass(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, self.EXPECTED, self.EXPORTS) + + @unittest.expectedFailure + def test_no_exports(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [], {}) + + @unittest.expectedFailure + def test_with_empty_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [], self.EXPORTS) + + @unittest.expectedFailure + def test_with_unfilled_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [{}], self.EXPORTS) + + @unittest.expectedFailure + def test_with_default_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [self.DEFAULT.copy()], self.EXPORTS) + +# +# Run all tests +# +if __name__ =3D=3D "__main__": + run_unittest(__file__) --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 989193ACEF9; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=YGG3flz/3bkkVgR9Zc9CliaC9vZ405nzBm9FxBBWzE9rUMMY5/br827hVnCUE1r+ChuFtSYdFjfi8fpLw4THtXFgKCzDnilOK5nPtNG0LvhvqRs3U/I584l/vX8kYWXSRWk9XbyTqeg7z7NYOzRo6V/Itqd+VLErcKf+XdxqZnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=evoBKNHKPvItoY9jitBsJ0pNF0jXPhqQ6qV4iI8PcEA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CibFdxYNySNt8QIBfbSWgVSpTqmNkfJAb9JNUvJvzCEIuFYczc2FOxGOqjQQqbHow9EQ8vh9FondhVoTbMhihee8QOtgVAQhTIy361VE4oJro9+J2moLJ7/O5A/AmpS6cST3tY8lPqKBkMz/EtrRrFlhLVX7SVBA9CDi3mh0yN0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Iw3egPAY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Iw3egPAY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D4179C2BCAF; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130554; bh=evoBKNHKPvItoY9jitBsJ0pNF0jXPhqQ6qV4iI8PcEA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Iw3egPAYA419fVh3rFnF8EZIFK1u7V4HfqXv2CRWioPSAeQeAFsIXzmilM07g1GSf cBsztuJEmHC4GjgWbKnVKWYd0RGfEDeb7NiN6isacV2CjZ7WLYGisS307eVuZNXFqU dF+hLGQEn13HuqIxq9r/BZ0gd6La0FFVif4pCbWrNOu94w3h8ETzHSlbuqSrClD6Za 0brN5SfRclHR3jOLrozJXuEZMfJqqafLTeVhQC2Q5W7eiqRf4u207kud0sFSu0TBIi XlEChsjpem7PA/XnZReH98E1r1CMVc9eajkYJcdGk0EUsyfhJEEwIvOttIOZgW3dLN 5v7ZCMVT3B/hQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Ui-0EqI; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Carvalho Chehab , Jani Nikula Subject: [PATCH 10/15] docs: add a schema to help creating unittests for kernel-doc Date: Tue, 3 Feb 2026 15:55:38 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Instead of hardcoding lots of tests inside a file, let's place them inside a yaml file. Add first a schema to handle it. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/kdoc-test-schema.yaml | 156 ++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 tools/unittests/kdoc-test-schema.yaml diff --git a/tools/unittests/kdoc-test-schema.yaml b/tools/unittests/kdoc-t= est-schema.yaml new file mode 100644 index 000000000000..cf5079711cd8 --- /dev/null +++ b/tools/unittests/kdoc-test-schema.yaml @@ -0,0 +1,156 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . + +# KDoc Test File Schema + +# This schema contains objects and properties needed to run kernel-doc +# self-tests. + +$schema: "http://json-schema.org/draft-07/schema#" + +tests: + type: array + minItems: 1 + description: | + A list of kernel-doc tests. + + properties: + type: object + properties: + name: + type: string + description: | + Test name. Should be an unique identifier within the schema. + Don't prepend it with "test", as the dynamic test creation will + do it. + + description: + type: string + description: | + Test description + + source: + type: string + description: | + C source code that should be parsed by kernel-doc. + + fname: + type: string + description: | + The filename that contains the element. + When placing real testcases, please use here the name of + the C file (or header) from where the source code was picked. + + exports: + type: array + items: { type: string } + description: | + A list of export identifiers that are expected when parsing sour= ce. + + expected: + type: array + minItems: 1 + description: | + A list of expected values. This list consists on objects to check + both kdoc_parser and/or kdoc_output objects. + + items: + type: object + properties: + # + # kdoc_item + # + kdoc_item: + type: object + description: | + Object expected to represent the C source code after parsed + by tools/lib/python/kdoc/kdoc_parser.py KernelDoc class. + See tools/lib/python/kdoc/kdoc_item.py for its contents. + + properties: + name: + type: string + description: | + The name of the identifier (function name, struct name= , etc). + type: + type: string + description: | + Type of the object, as filled by kdoc_parser. can be: + - enum + - typedef + - union + - struct + - var + - function + declaration_start_line: + type: integer + description: | + The line number where the kernel-doc markup started. + The first line of the code is line number 1. + sections: + type: object + additionalProperties: { type: string } + description: | + Sections inside the kernel-doc markups: + - "description" + - "return" + - any other part of the markup that starts with "somet= hing:" + sections_start_lines: + type: object + additionalProperties: { type: integer } + description: | + a list of section names and the starting line of it. + parameterlist: + type: array + items: { type: string } + description: | + Ordered list of parameter names. + + parameterdesc_start_lines: + type: object + additionalProperties: { type: integer } + description: | + Mapping from parameter name to the line where its + description starts. + parameterdescs: + type: object + additionalProperties: { type: string } + description: | + Mapping from parameter name to its description. + + parametertypes: + type: object + additionalProperties: { type: string } + description: | + Mapping from parameter name to its type. + + other_stuff: + type: object + additionalProperties: {} + description: | + Extra properties that will be stored at the item. + Should match what kdoc_output expects. + + required: + - name + - type + - declaration_start_line + + rst: + type: string + description: | + The expected output for RestOutput class. + + man: + type: string + description: | + The expected output for ManOutput class. + + anyOf: + required: kdoc_item + required: source + + required: + - name + - fname + - expected --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7CEC3939C9; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=QD4jTgiTNbqwBbOnMciL7LS+eMygaSLwF4Ce632xEMNu4EoO4YOwvc818AmU8BbllEgddi3ieagzI3cOtizRNaWuspwblY7CQFLzRGw0/kQZ/kjzrrSVUH+pF/jJN+srg0sZF3UGGZPMWHVYhlm0h5qoyigVbu06bdZ9A+soIsw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=AGwtCTrl4lfZZYTzUmeRMZ4rENqFUv/wfcZATfRdNck=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=q1ZP1hWE/i/dZ1mFO5xlwuB0J3FUGTHuE0XtoicAGhLZSHyLj40tbI+PecTY0RERHYxJmxD6vP2iT5DbfCZdTKYwkEivy0wb1t3WwSu1qpWQi6j741BQ0kv6k7JtCIE70uPNTiP8fZJR3mBp7x0FnhBCHtyLg4piRplpV46NCQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ISo8O+IU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ISo8O+IU" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C9AE5C4AF0C; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=AGwtCTrl4lfZZYTzUmeRMZ4rENqFUv/wfcZATfRdNck=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ISo8O+IUFAy5+eNmtUUYRrj8S9p+cIlIDxg8Ps0ftwftq2zRHMG96g6x/170iN6As jU+LuoDbo+Q2pmorcaq9HyD+AbDdlDrPEg8daKk4TWdMTv8Dsa12HPqev+SV2KTF90 SnIZTnTqz3UlNk9TkNQkCBsrOkoBzigd4HkV8r1g2rfdFqCjCSNFZ6z6FFXNFRjiVE iJHeaTTpXncWnrGJZZ3U879f+fM3SlHbQiNCAU11mMacwnE6zd4aKA/z3x0gK5uGKO W9Q0z9+6tMrOsRNuY9pKX7WrhUJ178N4Qo/R7vg8rFggwROK4LAX2UMnCeqyZDdT2+ 5RIxPf5U/dKkw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Um-0LmY; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Carvalho Chehab , Jani Nikula Subject: [PATCH 11/15] docs: add a simple kdoc-test.yaml together with a validation tool Date: Tue, 3 Feb 2026 15:55:39 +0100 Message-ID: <85f4b1c13d5187255b767e5928a6f8383275cc86.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Create a simple kdoc-test.yaml to be used to create unit tests for kernel-doc parser and output classes. For now, all we want is a simple function mapped on a yaml test using the defined schema. To be sure that the schema is followed, add an unittest for the file, which will also validate that the schema is properly parsed. It should be noticed that the .TH definition for the man format contains a timestamp. We'll need to handle that when dealing with the actual implementation for the ManOutput class unit tests. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/kdoc-test.yaml | 154 +++++++++++++++++++++++ tools/unittests/test_kdoc_test_schema.py | 94 ++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 tools/unittests/kdoc-test.yaml create mode 100755 tools/unittests/test_kdoc_test_schema.py diff --git a/tools/unittests/kdoc-test.yaml b/tools/unittests/kdoc-test.yaml new file mode 100644 index 000000000000..97a0fa329f37 --- /dev/null +++ b/tools/unittests/kdoc-test.yaml @@ -0,0 +1,154 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2026: Mauro Carvalho Chehab + +# Test cases for the dynamic tests. +# Useful to test if kernel-doc classes are doing what it is expected. +# + +tests: + - name: func1 + fname: mock_functions.c + description: "Simplest function test: do nothing, just rst output" + + source: | + /** + * func1 - Not exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int func1(char *arg1) { return 0; }; + + + expected: + - rst: | + .. c:function:: int func1 (char *arg1) + + Not exported function + + .. container:: kernelindent + + **Parameters** + + ``char *arg1`` + **arg1** does nothing + + **Description** + + Does nothing + + **Return** + + always return 0. + + # TODO: how to handle timestamps at .TH? + man: | + .TH "func1" 9 "February 2026" "" "Kernel API Manual" + .SH NAME + func1 \- Not exported function + .SH SYNOPSIS + .B "int" func1 + .BI "(char *arg1 " ");" + .SH ARGUMENTS + .IP "arg1" 12 + \fIarg1\fP does nothing + .SH "DESCRIPTION" + Does nothing + .SH "RETURN" + always return 0. + .SH "SEE ALSO" + .PP + Kernel file \fBmock_functions.c\fR + + - name: func2 + fname: func2.c + description: Simple test with exports + + source: | + /** + * func2() - Exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int func2(char *arg1) { return 0; }; + EXPORT_SYMBOL(func2); + + exports: func2 + expected: + - kdoc_item: + name: func2 + type: function + declaration_start_line: 1 + + sections: + Description: | + Does nothing + + Return: | + always return 0. + + sections_start_lines: + Description: 3 + Return: 6 + + parameterdescs: + arg1: | + @arg1 does nothing + parameterlist: + - arg1 + parameterdesc_start_lines: + arg1: 2 + parametertypes: + arg1: char *arg1 + + other_stuff: + func_macro: false + functiontype: int + purpose: "Exported function" + typedef: false + + rst: | + .. c:function:: int func2 (char *arg1) + + Exported function + + .. container:: kernelindent + + **Parameters** + + ``char *arg1`` + **arg1** does nothing + + **Description** + + Does nothing + + **Return** + + always return 0. + + # TODO: how to handle timestamps at .TH? + man: | + .TH "func2" 9 "February 2026" "" "Kernel API Manual" + .SH NAME + func2 \- Exported function + .SH SYNOPSIS + .B "int" func2 + .BI "(char *arg1 " ");" + .SH ARGUMENTS + .IP "arg1" 12 + \fIarg1\fP does nothing + .SH "DESCRIPTION" + Does nothing + .SH "RETURN" + always return 0. + .SH "SEE ALSO" + .PP + Kernel file \fBfunc2.c\fR diff --git a/tools/unittests/test_kdoc_test_schema.py b/tools/unittests/tes= t_kdoc_test_schema.py new file mode 100755 index 000000000000..9eceeba00440 --- /dev/null +++ b/tools/unittests/test_kdoc_test_schema.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +""" +Unit=E2=80=91test driver for kernel=E2=80=91doc YAML tests. + +Two kinds of tests are defined: + +* **Schema=E2=80=91validation tests** =E2=80=93 if ``jsonschema`` is avail= able, the + YAML files in this directory are validated against the JSON=E2=80=91Sche= ma + described in ``kdoc-test-schema.yaml``. When the library is not + present, a warning is emitted and the validation step is simply + skipped =E2=80=93 the dynamic kernel=E2=80=91doc tests still run. + +* **Kernel=E2=80=91doc tests** =E2=80=93 dynamically generate one test met= hod per + scenario in ``kdoc-test.yaml``. Each method simply forwards + the data to ``self.run_test`` =E2=80=93 you only need to implement that + helper in your own code. + +File names are kept as module=E2=80=91level constants so that the +implementation stays completely independent of ``pathlib``. +""" + +import os +import sys +import warnings +import yaml +import unittest +from typing import Any, Dict, List + +SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) + +from unittest_helper import run_unittest + + +# +# Files to read +# +BASE =3D os.path.realpath(os.path.dirname(__file__)) + +SCHEMA_FILE =3D os.path.join(BASE, "kdoc-test-schema.yaml") +TEST_FILE =3D os.path.join(BASE, "kdoc-test.yaml") + +# +# Schema=E2=80=91validation test +# +class TestYAMLSchemaValidation(unittest.TestCase): + """ + Checks if TEST_FILE matches SCHEMA_FILE. + """ + + @classmethod + def setUpClass(cls): + """ + Import jsonschema if available. + """ + + try: + from jsonschema import Draft7Validator + except ImportError: + print("Warning: jsonschema package not available. Skipping sch= ema validation") + cls.validator =3D None + return + + with open(SCHEMA_FILE, encoding=3D"utf-8") as fp: + cls.schema =3D yaml.safe_load(fp) + + cls.validator =3D Draft7Validator(cls.schema) + + def test_kdoc_test_yaml_followsschema(self): + """ + Run jsonschema validation if the validator is available. + If not, emit a warning and return without failing. + """ + if self.validator is None: + return + + with open(TEST_FILE, encoding=3D"utf-8") as fp: + data =3D yaml.safe_load(fp) + + errors =3D self.validator.iter_errors(data) + + msgs =3D [] + for error in errors: + msgs.append(error.message) + + if msgs: + self.fail("Schema validation failed:\n\t" + "\n\t".join(msgs)) + +# -------------------------------------------------------------------- +# Entry point +# -------------------------------------------------------------------- +if __name__ =3D=3D "__main__": + run_unittest(__file__) --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9FB93ACF09; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=R4qsRAQ5xy90G6nLk4EHpTpM5+NXMvjBP8RCSVF4xUnbiifMMWEXYJKqMFRm45W94tyv9+3d/TlSBIFjsRLn/+JI4xakkiO1RHKLAwqljsrUVcs5gWMqi7/FqBGFb8vLj0S5YVglfzQACT+NhKZqoMrjt1XQmE2SJ7b/LYYVU4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=XjB7oEIvMEoEv4pw8CCs+7NJYgNKFnhj4FnMlBDzF5c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=EApG77i05VOYHnUn7H/PO4sMT8z7GobBBlbMPzgwwuK0bj7TnJ8KnupEJIgMNoj2jmgAjqX9+xO77xLXwPYr/Gj0j/dEVSsWOo7/mSlAxgWoM1KejgWwM75vJflNr/MiKDyQbMdSiS+esaKLOIP8/LtsdzXauf/kqsY9+YzgaRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RDQK+h51; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RDQK+h51" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4EAEC2BCB5; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=XjB7oEIvMEoEv4pw8CCs+7NJYgNKFnhj4FnMlBDzF5c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RDQK+h51OR9ODBJJXaZQ4Oc0O5L07u0fvpNbPAgwL1iyHzNuB+CkPqtdgwGNyplGs Q750kc/KI0HnLB8hS5MF7mWBMy9Yby6q5bpQGIK/v1OTL8Ohs4/gwNwgRAZC7uQtW8 4xfqeBptznBRSNBRscaivalBqiMYnmmXLLuBg9kcjv3jz7buIbnGYtLD4w8VjZjG8j ATkghxo561fS9dIa01LRjctXKyIL/PTr+M99oCoWWSu2hTK+l45TyvSROP3X5bfnfW VZt/MyynHW6Mh01jydwKOWIeF+FC1fUc4Il23OOVn9mGNIF5uK2eyvuzJDIV+3nRiq O2FEHC0st2sKQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Uq-0SWE; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 12/15] docs: test_kdoc_parser: add support for dynamic test creation Date: Tue, 3 Feb 2026 15:55:40 +0100 Message-ID: <5518d264bd3e273911d09ba9b07cca20b7cc4bc1.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Use the content of kdoc-test.yaml to generate unittests to verify that kernel-doc internal methods are parsing C code and generating output the expected way. Depending on what is written at the parser file at kdoc-test.yaml, up to 5 tests can be generated from a single test entry inside the YAML file: 1. from source to kdoc_item: test KernelDoc class; 2. from kdoc_item to man: test ManOutput class; 3. from kdoc_item to rst: test RestOutput class; 4. from source to man without checking expected KdocItem; 5. from source to rst without checking expected KdocItem. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_kdoc_parser.py | 342 ++++++++++++++++++++++++++-- 1 file changed, 325 insertions(+), 17 deletions(-) diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdo= c_parser.py index f3ff750ac0e9..dd3d576e1b93 100755 --- a/tools/unittests/test_kdoc_parser.py +++ b/tools/unittests/test_kdoc_parser.py @@ -8,24 +8,40 @@ Unit tests for kernel-doc parser. """ =20 +import logging import os -import unittest import re import sys +import unittest =20 from textwrap import dedent from unittest.mock import patch, MagicMock, mock_open =20 +import yaml + SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) =20 -from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_files import KdocConfig from kdoc.kdoc_item import KdocItem +from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_output import RestFormat, ManFormat + from kdoc.xforms_lists import CTransforms + from unittest_helper import run_unittest =20 + +# +# Test file +# +TEST_FILE =3D os.path.join(SRC_DIR, "kdoc-test.yaml") + +# +# Ancillary logic to clean whitespaces +# #: Regex to help cleaning whitespaces -RE_WHITESPC =3D re.compile(r"\s++") +RE_WHITESPC =3D re.compile(r"([ \t]|\n)++") =20 def clean_whitespc(val, relax_whitespace=3DFalse): """ @@ -46,22 +62,59 @@ def clean_whitespc(val, relax_whitespace=3DFalse): return val =20 # -# Helper class to help mocking with +# Helper classes to help mocking with logger and config # -class KdocParser(unittest.TestCase): +class MockLogging(logging.Handler): + """ + Simple class to store everything on a list + """ + + def __init__(self, level=3Dlogging.NOTSET): + super().__init__(level) + self.messages =3D [] + self.formatter =3D logging.Formatter() + + def emit(self, record: logging.LogRecord) -> None: + """ + Append a formatted record to self.messages. + """ + try: + # The `format` method uses the handler's formatter. + message =3D self.format(record) + self.messages.append(message) + except Exception: + self.handleError(record) + +class MockKdocConfig(KdocConfig): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.log =3D logging.getLogger(__file__) + self.handler =3D MockLogging() + self.log.addHandler(self.handler) + + def warning(self, msg): + """Ancillary routine to output a warning and increment error count= .""" + + self.log.warning(msg) + +# +# Helper class to generate KdocItem and validate its contents +# +# TODO: check self.config.handler.messages content +# +class GenerateKdocItem(unittest.TestCase): """ Base class to run KernelDoc parser class """ =20 DEFAULT =3D vars(KdocItem("", "", "", 0)) =20 + config =3D MockKdocConfig() + xforms =3D CTransforms() + def setUp(self): self.maxDiff =3D None - self.config =3D MagicMock() - self.config.log =3D MagicMock() - self.config.log.debug =3D MagicMock() - self.xforms =3D CTransforms() - =20 def run_test(self, source, __expected_list, exports=3D{}, fname=3D"tes= t.c", relax_whitespace=3DFalse): @@ -75,6 +128,9 @@ class KdocParser(unittest.TestCase): # Ensure that default values will be there expected_list =3D [] for e in __expected_list: + if not isinstance(e, dict): + e =3D vars(e) + new_e =3D self.DEFAULT.copy() new_e["fname"] =3D fname for key, value in e.items(): @@ -111,13 +167,136 @@ class KdocParser(unittest.TestCase): =20 self.assertEqual(result, value, msg=3Df"at {key}") =20 +# +# Ancillary function that replicates kdoc_files way to generate output +# +def gen_output(fname, out_style, symbols, expected, + config=3DNone, relax_whitespace=3DFalse): + """ + Use the output class to return an output content from KdocItem symbols. + """ + + if not config: + config =3D MockKdocConfig() + + out_style.set_config(config) + + msg =3D out_style.output_symbols(fname, symbols) + + result =3D clean_whitespc(msg, relax_whitespace) + expected =3D clean_whitespc(expected, relax_whitespace) + + return result, expected + +# +# Classes to be used by dynamic test generation from YAML +# +class CToKdocItem(GenerateKdocItem): + def setUp(self): + self.maxDiff =3D None + + def run_parser_test(self, source, symbols, exports, fname): + if isinstance(symbols, dict): + symbols =3D [symbols] + + if isinstance(exports, str): + exports=3Dset([exports]) + elif isinstance(exports, list): + exports=3Dset(exports) + + self.run_test(source, symbols, exports=3Dexports, + fname=3Dfname, relax_whitespace=3DTrue) + +class KdocItemToMan(unittest.TestCase): + out_style =3D ManFormat() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, symbols, expected): + """ + Generate output using out_style, + """ + result, expected =3D gen_output(fname, self.out_style, + symbols, expected) + + self.assertEqual(result, expected) + +class KdocItemToRest(unittest.TestCase): + out_style =3D RestFormat() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, symbols, expected): + """ + Generate output using out_style, + """ + result, expected =3D gen_output(fname, self.out_style, symbols, + expected, relax_whitespace=3DTrue) + + self.assertEqual(result, expected) + + +class CToMan(unittest.TestCase): + out_style =3D ManFormat() + config =3D MockKdocConfig() + xforms =3D CTransforms() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, source, expected): + """ + Generate output using out_style, + """ + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + result, expected =3D gen_output(fname, self.out_style, + entries, expected, config=3Dself.con= fig) + + self.assertEqual(result, expected) + + +class CToRest(unittest.TestCase): + out_style =3D RestFormat() + config =3D MockKdocConfig() + xforms =3D CTransforms() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, source, expected): + """ + Generate output using out_style, + """ + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + result, expected =3D gen_output(fname, self.out_style, entries, + expected, relax_whitespace=3DTrue, + config=3Dself.config) + + self.assertEqual(result, expected) + =20 # -# Selttest class +# Selftest class # -class TestSelfValidate(KdocParser): +class TestSelfValidate(GenerateKdocItem): """ - Tests to check if logic inside KdocParser.run_test() is working. + Tests to check if logic inside GenerateKdocItem.run_test() is working. """ =20 SOURCE =3D """ @@ -143,16 +322,23 @@ class TestSelfValidate(KdocParser): 'Description': 'Does nothing\n\n', 'Return': '\nalways return 0.\n' }, + + 'sections_start_lines': { + 'Description': 4, + 'Return': 7, + }, + + 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, + 'parameterlist': ['arg1'], + 'parameterdesc_start_lines': {'arg1': 3}, + 'parametertypes': {'arg1': 'char *arg1'}, + 'other_stuff': { 'func_macro': False, 'functiontype': 'int', 'purpose': 'Exported function', 'typedef': False }, - 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, - 'parameterlist': ['arg1'], - 'parameterdesc_start_lines': {'arg1': 3}, - 'parametertypes': {'arg1': 'char *arg1'}, }] =20 EXPORTS =3D {"function3"} @@ -191,6 +377,128 @@ class TestSelfValidate(KdocParser): """ self.run_test(self.SOURCE, [self.DEFAULT.copy()], self.EXPORTS) =20 +# +# Class and logic to create dynamic tests from YAML +# + +class KernelDocDynamicTests(): + """ + Dynamically create a set of tests from a YAML file. + """ + + @classmethod + def create_parser_test(cls, name, fname, source, symbols, exports): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_parser_test(source, symbols, exports, fname) + + test_method.__name__ =3D f"test_gen_{name}" + + setattr(CToKdocItem, test_method.__name__, test_method) + + @classmethod + def create_out_test(cls, name, fname, symbols, out_type, data): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_out_test(fname, symbols, data) + + test_method.__name__ =3D f"test_{out_type}_{name}" + + if out_type =3D=3D "man": + setattr(KdocItemToMan, test_method.__name__, test_method) + else: + setattr(KdocItemToRest, test_method.__name__, test_method) + + @classmethod + def create_src2out_test(cls, name, fname, source, out_type, data): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_out_test(fname, source, data) + + test_method.__name__ =3D f"test_{out_type}_{name}" + + if out_type =3D=3D "man": + setattr(CToMan, test_method.__name__, test_method) + else: + setattr(CToRest, test_method.__name__, test_method) + + @classmethod + def create_tests(cls): + """ + Iterate over all scenarios and add a method to the class for each. + + The logic in this function assumes a valid test that are compliant + with kdoc-test-schema.yaml. There is an unit test to check that. + As such, it picks mandatory values directly, and uses get() for the + optional ones. + """ + + with open(TEST_FILE, encoding=3D"utf-8") as fp: + testset =3D yaml.safe_load(fp) + + tests =3D testset["tests"] + + for idx, test in enumerate(tests): + name =3D test["name"] + fname =3D test["fname"] + source =3D test["source"] + expected_list =3D test["expected"] + + exports =3D test.get("exports", []) + + # + # The logic below allows setting up to 5 types of test: + # 1. from source to kdoc_item: test KernelDoc class; + # 2. from kdoc_item to man: test ManOutput class; + # 3. from kdoc_item to rst: test RestOutput class; + # 4. from source to man without checking expected KdocItem; + # 5. from source to rst without checking expected KdocItem. + # + for expected in expected_list: + kdoc_item =3D expected.get("kdoc_item") + man =3D expected.get("man", []) + rst =3D expected.get("rst", []) + + if kdoc_item: + if isinstance(kdoc_item, dict): + kdoc_item =3D [kdoc_item] + + symbols =3D [] + + for arg in kdoc_item: + arg["fname"] =3D fname + arg["start_line"] =3D 1 + + symbols.append(KdocItem.from_dict(arg)) + + if source: + cls.create_parser_test(name, fname, source, + symbols, exports) + + if man: + cls.create_out_test(name, fname, symbols, "man", m= an) + + if rst: + cls.create_out_test(name, fname, symbols, "rst", r= st) + + elif source: + if man: + cls.create_src2out_test(name, fname, source, "man"= , man) + + if rst: + cls.create_src2out_test(name, fname, source, "rst"= , rst) + +KernelDocDynamicTests.create_tests() + # # Run all tests # --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7EC33AA1B1; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=EJ4dgntMlDwdRXXm7osQkccapcbYKY5sohTsIQllKPXyMR3HhhQuJYyoB4jGgqBzxxNyBBWPRPX3vsPBpMO//UW2n3Bb5SmsGvnX1Q8cj+IW2ukqMjYmdDCvdLy2NBLxyi3ITpuXQnQergkFxsVsIQ3X7GK+YF0nyGOhjCKIe1c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=+SaofE+64nDEujgy8UkXcEH7IGfc5C5+RP8MKIJLfR8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Vy3r1cXu1gOaEbHq2WRip/PwhN2SDoZn23PMufcbUB80lv6NYSYtfOt+myEuRfNM9vwrKPjxstkoQ1e42gifSGAPYFHFk/T3RQHNEkOJKV9yR0b5I7D9swZKECQ/by0/yoZ4d+X6uJKHjEJK+KGiCo2rkq4t5n15Dto1QSQ1IVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UanuEpKd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UanuEpKd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E7D30C2BCB4; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=+SaofE+64nDEujgy8UkXcEH7IGfc5C5+RP8MKIJLfR8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UanuEpKdMmdSp8GEZW8vmRA7S/qbLqBpu78vo7oHdyO8l3pWFA0T3ALh4a5FFIVPI EYb4Oi5Xq32sxBscdiSUaUKavuDmZdj10KM+iD3s/QZNI5uQLKs+V2zhdt8YoONVhQ 1P2dUM4xfbCAtnXwRLvazTJJqIKY65bQmwNPiMmU28Mzbhy3IyTCmtw9MYefFspTmO vH7U2GID/AthAPN59w1yKjbVniqbTgF5TuBAbXd6vmmUOWYzezr4dKmVeGZNEgSYYs X7eETq8VozD0WTYh3DZO5imzKXvH7ASdfOsfFDofznOTaKLIgA/GjxGnn1wsIimpfN 6btwioFTs1Tkg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Uu-0Zux; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 13/15] docs: add a new file to write kernel-doc output to a YAML file Date: Tue, 3 Feb 2026 15:55:41 +0100 Message-ID: <7e48e3ee16782cf2d0621530aea36d25319e0495.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Storing kernel-doc output is helpful to allow debugging problems on it and to preparate unit tests. Add a class to store such contents at the same format as defined at kdoc-test-schema.yaml. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_yaml_file.py | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 tools/lib/python/kdoc/kdoc_yaml_file.py diff --git a/tools/lib/python/kdoc/kdoc_yaml_file.py b/tools/lib/python/kdo= c/kdoc_yaml_file.py new file mode 100644 index 000000000000..db131503c3f6 --- /dev/null +++ b/tools/lib/python/kdoc/kdoc_yaml_file.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . + +import os + +from kdoc.kdoc_output import ManFormat, RestFormat + + +class KDocTestFile(): + """ + Handles the logic needed to store kernel=E2=80=91doc output inside a Y= AML file. + Useful for unit tests and regression tests. + """ + + def __init__(self, config, yaml_file, yaml_content): + # + # Bail out early if yaml is not available + # + try: + import yaml + except ImportError: + sys.exit("Warning: yaml package not available. Aborting it.") + + self.config =3D config + self.test_file =3D os.path.expanduser(yaml_file) + self.yaml_content =3D yaml_content + + self.tests =3D [] + + out_dir =3D os.path.dirname(self.test_file) + if out_dir and not os.path.isdir(out_dir): + sys.exit(f"Directory {out_dir} doesn't exist.") + + self.out_style =3D [] + + if "man" in self.yaml_content: + out_style =3D ManFormat() + out_style.set_config(self.config) + + self.out_style.append(out_style) + + if "rst" in self.yaml_content: + out_style =3D RestFormat() + out_style.set_config(self.config) + + self.out_style.append(out_style) + + def set_filter(self, export, internal, symbol, nosymbol, + function_table, enable_lineno, no_doc_sections): + """ + Set filters at the output classes. + """ + for out_style in self.out_style: + out_style.set_filter(export, internal, symbol, + nosymbol, function_table, + enable_lineno, no_doc_sections) + + @staticmethod + def get_kdoc_item(arg, start_line=3D1): + + d =3D vars(arg) + + declaration_start_line =3D d.get("declaration_start_line") + if not declaration_start_line: + return d + + d["declaration_start_line"] =3D start_line + + parameterdesc_start_lines =3D d.get("parameterdesc_start_lines") + if parameterdesc_start_lines: + for key in parameterdesc_start_lines: + ln =3D parameterdesc_start_lines[key] + ln +=3D start_line - declaration_start_line + + parameterdesc_start_lines[key] =3D ln + + sections_start_lines =3D d.get("sections_start_lines") + if sections_start_lines: + for key in sections_start_lines: + ln =3D sections_start_lines[key] + ln +=3D start_line - declaration_start_line + + sections_start_lines[key] =3D ln + + return d + + def output_symbols(self, fname, symbols, source): + """ + Store source, symbols and output strings at self.tests. + """ + + # + # KdocItem needs to be converted into dicts + # + kdoc_item =3D [] + expected =3D [] + + if not symbols and not source: + return + + if not source or len(symbols) !=3D len(source): + print(f"Warning: lengths are different. Ignoring {fname}") + + # Folding without line numbers is too hard. + # The right thing to do here to proceed would be to delete + # not-handled source blocks, as len(source) should be bigger + # than len(symbols) + return + + base_name =3D "test_" + fname.replace(".", "_").replace("/", "_") + expected_dict =3D {} + start_line=3D1 + + for i in range(0, len(symbols)): + arg =3D symbols[i] + + if "KdocItem" in self.yaml_content: + msg =3D self.get_kdoc_item(arg) + + expected_dict["kdoc_item"] =3D msg + + for out_style in self.out_style: + if isinstance(out_style, ManFormat): + key =3D "man" + else: + key =3D "rst" + + expected_dict[key]=3D out_style.output_symbols(fname, [arg= ]) + + name =3D f"{base_name}_{i:03d}" + + test =3D { + "name": name, + "description": f"{fname} line {source[i]["ln"]}", + "fname": fname, + "source": source[i]["data"], + "expected": [expected_dict] + } + + self.tests.append(test) + + expected_dict =3D {} + + def write(self): + """ + Output the content of self.tests to self.test_file. + """ + import yaml + + data =3D {"tests": self.tests} + + with open(self.test_file, "w", encoding=3D"utf-8") as fp: + yaml.safe_dump(data, fp, sort_keys=3DFalse, default_style=3D"|= ", + default_flow_style=3DFalse, allow_unicode=3DTru= e) --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7DD43939CE; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=jNwUP3uY2AqaoguYx6f8BCDrKcy4zq8rGWHRcaSuZ9EiFLZlnwStvGShS0UXrBAzGOAfLmEvLnY1lJQ1bWuv22FTO44HSZnolmhQrKbbxplAFSUys9IzuWjw/jQ8QguH+/X/ha8X2f/2OQb/bLBs5CMMRuxJp7TLedCswctknBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=IzvIm7KoDEuXLxlxb1Oy6DEqVh4pIaNIXwZ6aUtWm1Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=g/S/c88y6G6FHVQr83eU6T6SnyGBoBM7oYOHWGrjiNhBWOsxtfFSL6Q4wuMRH74nji0iw7j8B2OYaZQWXWsKDNNkLhOmnozg4iBBapIcy80Naqr2L9byQyUuNrC4TAoq0SPllIlIiosOONTpFkGtH3wgFrAMOhwZe3YSMRfz72s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CTsZsSOa; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CTsZsSOa" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ED8E8C2BCB8; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=IzvIm7KoDEuXLxlxb1Oy6DEqVh4pIaNIXwZ6aUtWm1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CTsZsSOaGF/fZuottrRbnuk83otSF512DPG6umuOL8d2mL+KaELLIYEdgSFUU6Zwk y79nZwiO4TK3eSfiLdWZaN4WkPLEBA1xcth75O9703/ayRIlZQ90iv2zgHRVKytJ0g IPPOD/E5g6nYdVAp14K7qQL5Y32MNh5D+zXdsO2wxIQRBTt7AUa0Dv+kljpQDPVC9D Ls9948p8iFEnsfituIvncukdDrKQ3noh7lfFrFFanBH1myZ31XvDD2Mr/7FYORO5w/ 7FCDcqw2s+/0dzeUnSnFaZSqAxkZG5gwp/m2KROGrQO1ifpmRazkSW6g89UA5r0O6d ehCqeK7QiMoSA== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027Uy-0h97; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Aleksandr Loktionov , Jani Nikula , Mauro Carvalho Chehab , Randy Dunlap , Shuah Khan Subject: [PATCH 14/15] docs: kernel-doc: add support to store output on a YAML file Date: Tue, 3 Feb 2026 15:55:42 +0100 Message-ID: <7648cb5f5a1b501d9ae9a57b4d8dbeb7273d9097.1770128540.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Add a command line parameter and library support to optionally store: - KdocItem intermediate format after parsing; - man pages output; - rst output. inside a YAML file. Signed-off-by: Mauro Carvalho Chehab --- tools/docs/kernel-doc | 48 +++++++++++++++++++++++----- tools/lib/python/kdoc/kdoc_files.py | 47 +++++++++++++++++++++++---- tools/lib/python/kdoc/kdoc_parser.py | 27 +++++++++++++++- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/tools/docs/kernel-doc b/tools/docs/kernel-doc index 3a932f95bdf5..5382d98aaff4 100755 --- a/tools/docs/kernel-doc +++ b/tools/docs/kernel-doc @@ -240,11 +240,9 @@ def main(): help=3DEXPORT_FILE_DESC) =20 # - # Output format mutually-exclusive group + # Output format # - out_group =3D parser.add_argument_group("Output format selection (mutu= ally exclusive)") - - out_fmt =3D out_group.add_mutually_exclusive_group() + out_fmt =3D parser.add_argument_group("Output format selection (mutual= ly exclusive)") =20 out_fmt.add_argument("-m", "-man", "--man", action=3D"store_true", help=3D"Output troff manual page format.") @@ -253,6 +251,12 @@ def main(): out_fmt.add_argument("-N", "-none", "--none", action=3D"store_true", help=3D"Do not output documentation, only warning= s.") =20 + out_fmt.add_argument("-y", "--yaml-file", "--yaml", + help=3D"Stores kernel-doc output on a yaml file.") + out_fmt.add_argument("-k", "--kdoc-item", "--kdoc", action=3D"store_tr= ue", + help=3D"Store KdocItem inside yaml file. Ued toge= ther with --yaml.") + + # # Output selection mutually-exclusive group # @@ -323,14 +327,42 @@ def main(): from kdoc.kdoc_files import KernelFiles # pylint: disable= =3DC0415 from kdoc.kdoc_output import RestFormat, ManFormat # pylint: disable= =3DC0415 =20 - if args.man: - out_style =3D ManFormat(modulename=3Dargs.modulename) - elif args.none: + yaml_content =3D set() + if args.yaml_file: out_style =3D None + + if args.man: + yaml_content |=3D {"man"} + + if args.rst: + yaml_content |=3D {"rst"} + + if args.kdoc_item or not yaml_content: + yaml_content |=3D {"KdocItem"} + else: - out_style =3D RestFormat() + n_outputs =3D 0 + + if args.man: + out_style =3D ManFormat(modulename=3Dargs.modulename) + n_outputs +=3D 1 + + if args.none: + out_style =3D None + n_outputs +=3D 1 + + if args.rst or n_outputs =3D=3D 0: + n_outputs +=3D 1 + out_style =3D RestFormat() + + if n_outputs > 1: + parser.error("Those arguments are muttually exclusive: --man,= --rst, --none, except when generating a YAML file.") + + else: + out_style =3D RestFormat() =20 kfiles =3D KernelFiles(verbose=3Dargs.verbose, + yaml_file=3Dargs.yaml_file, yaml_content=3Dyaml_c= ontent, out_style=3Dout_style, werror=3Dargs.werror, wreturn=3Dargs.wreturn, wshort_desc=3Dargs.wshort= _desc, wcontents_before_sections=3Dargs.wcontents_before= _sections) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 58f4ee08e226..5a299ed44d62 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -16,6 +16,7 @@ import re from kdoc.kdoc_parser import KernelDoc from kdoc.xforms_lists import CTransforms from kdoc.kdoc_output import OutputFormat +from kdoc.kdoc_yaml_file import KDocTestFile =20 =20 class GlobSourceFiles: @@ -152,6 +153,12 @@ class KernelFiles(): =20 If not specified, defaults to use: ``logging.getLogger("kernel-doc= ")`` =20 + ``yaml_file`` + If defined, stores the output inside a YAML file. + + ``yaml_content`` + Defines what will be inside the YAML file. + Note: There are two type of parsers defined here: =20 @@ -181,7 +188,12 @@ class KernelFiles(): if fname in self.files: return =20 - doc =3D KernelDoc(self.config, fname, self.xforms) + if self.test_file: + store_src =3D True + else: + store_src =3D False + + doc =3D KernelDoc(self.config, fname, self.xforms, store_src=3Dsto= re_src) export_table, entries =3D doc.parse_kdoc() =20 self.export_table[fname] =3D export_table @@ -191,6 +203,10 @@ class KernelFiles(): =20 self.results[fname] =3D entries =20 + source =3D doc.get_source() + if source: + self.source[fname] =3D source + def process_export_file(self, fname): """ Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file. @@ -220,7 +236,7 @@ class KernelFiles(): def __init__(self, verbose=3DFalse, out_style=3DNone, xforms=3DNone, werror=3DFalse, wreturn=3DFalse, wshort_desc=3DFalse, wcontents_before_sections=3DFalse, - logger=3DNone): + yaml_file=3DNone, yaml_content=3DNone, logger=3DNone): """ Initialize startup variables and parse all files. """ @@ -259,6 +275,11 @@ class KernelFiles(): # Override log warning, as we want to count errors self.config.warning =3D self.warning =20 + if yaml_file: + self.test_file =3D KDocTestFile(self.config, yaml_file, yaml_c= ontent) + else: + self.test_file =3D None + if xforms: self.xforms =3D xforms else: @@ -273,6 +294,7 @@ class KernelFiles(): =20 self.errors =3D 0 self.results =3D {} + self.source =3D {} =20 self.files =3D set() self.export_files =3D set() @@ -331,16 +353,29 @@ class KernelFiles(): for s in symbol: function_table.add(s) =20 - self.out_style.set_filter(export, internal, symbol, nosymbol, - function_table, enable_lineno, - no_doc_sections) - if fname not in self.results: self.config.log.warning("No kernel-doc for file %s", fname) continue =20 symbols =3D self.results[fname] =20 + if self.test_file: + self.test_file.set_filter(export, internal, symbol, nosymb= ol, + function_table, enable_lineno, + no_doc_sections) + + self.test_file.output_symbols(fname, symbols, + self.source.get(fname)) + + continue + + self.out_style.set_filter(export, internal, symbol, nosymbol, + function_table, enable_lineno, + no_doc_sections) + msg =3D self.out_style.output_symbols(fname, symbols) if msg: yield fname, msg + + if self.test_file: + self.test_file.write() diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/k= doc_parser.py index 940c848d4d80..f6748720d899 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -258,12 +258,13 @@ class KernelDoc: #: String to write when a parameter is not described. undescribed =3D "-- undescribed --" =20 - def __init__(self, config, fname, xforms): + def __init__(self, config, fname, xforms, store_src=3DFalse): """Initialize internal variables""" =20 self.fname =3D fname self.config =3D config self.xforms =3D xforms + self.store_src =3D store_src =20 # Initial state for the state machines self.state =3D state.NORMAL @@ -274,6 +275,9 @@ class KernelDoc: # Place all potential outputs into an array self.entries =3D [] =20 + # When store_src is true, the kernel-doc source content is stored = here + self.source =3D None + # # We need Python 3.7 for its "dicts remember the insertion # order" guarantee @@ -1612,6 +1616,15 @@ class KernelDoc: state.DOCBLOCK: process_docblock, } =20 + def get_source(self): + """ + Return the file content of the lines handled by kernel-doc at the + latest parse_kdoc() run. + + Returns none if KernelDoc() was not initialized with store_src, + """ + return self.source + def parse_kdoc(self): """ Open and process each line of a C source file. @@ -1625,6 +1638,8 @@ class KernelDoc: prev =3D "" prev_ln =3D None export_table =3D set() + self.source =3D [] + self.state =3D state.NORMAL =20 try: with open(self.fname, "r", encoding=3D"utf8", @@ -1651,6 +1666,8 @@ class KernelDoc: ln, state.name[self.state], line) =20 + prev_state =3D self.state + # This is an optimization over the original script. # There, when export_file was used for the same file, # it was read twice. Here, we use the already-existing @@ -1661,6 +1678,14 @@ class KernelDoc: # Hand this line to the appropriate state handler self.state_actions[self.state](self, ln, line) =20 + if self.store_src and prev_state !=3D self.state or se= lf.state !=3D state.NORMAL: + if self.state =3D=3D state.NAME: + # A "/**" was detected. Add a new source eleme= nt + self.source.append({"ln": ln, "data": line + "= \n"}) + else: + # Append to the existing one + self.source[-1]["data"] +=3D line + "\n" + self.emit_unused_warnings() =20 except OSError: --=20 2.52.0 From nobody Sat Feb 7 21:14:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5E963ACF07; Tue, 3 Feb 2026 14:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; cv=none; b=Sw1VT8F8ZQ1SzaKXDbc+rCC14OCkwCgGXLdA0I5TwH2roEURqiJRqbXgcc3wXthn22MYi0WbB2RiwlRcddlXhy+n3c00Ow32JFVQ2f5sYOwNNTJgK6Dd3QsKpBgiycAVbfwdjPtBo8oLcN6Kp60YNbl3FcK5zx7ZT+/KvUEp3ik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770130555; c=relaxed/simple; bh=NqNP2uQYzab+0n+ez3XsP/9cvYv0t7ITDg4PrOql4bg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IPH0/qCsJfV8e3OuBz87Ow3T7qqS2G/pcG26Mhq1C0cCjAJ0KiblTxkOhA3QDjiGltffXZ7X7Qd0pppBZR1uGNSOMX4O2v3b0XXVdtCT3Ykld2kYhHBaKOR8quR22SSEr0VfLytj+uysaI0saA77rHoBUd+mxkwxDvjVK9S+Dhg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=glMRRPhI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="glMRRPhI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB3DCC2BCB6; Tue, 3 Feb 2026 14:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770130555; bh=NqNP2uQYzab+0n+ez3XsP/9cvYv0t7ITDg4PrOql4bg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=glMRRPhI4wniUpAMpVBUd4DoicK+P+oz6OdmU/PVXK+Y1QepLKO1WMlkBTSM2aO8D bw0xxLtcSukrxieg5LgLafwHbsoSovDh7KM/nGaRdyeebyyGa+FKgPPf5en60tJpwg n6en89iK6fbAR+go35SKPlbqOqcr3QzULAZXcbZEP801tZqSxvZxRL8O4sLAkyXhpS QTmQZO5wM9PhEosrQDeLMb6W9/nZwq2qzbtv1HCmr9TAbaSRNPDu8OtA+M5vCQ0oT0 qHl1I/EHvjgH7sbfHrfmNHIduB7qYj1l0bs+z4Li2UluI69itwNuZWxbW+KqYjMMf8 f5m7wLwdCm5pA== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1vnHon-000000027V2-0oK8; Tue, 03 Feb 2026 15:55:53 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Jani Nikula , Mauro Carvalho Chehab Subject: [PATCH 15/15] unittests: test_kdoc_parser: add command line arg to read a YAML file Date: Tue, 3 Feb 2026 15:55:43 +0100 Message-ID: X-Mailer: git-send-email 2.52.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab The test_kdoc_parser.py already supports loading dynamic tests when running unit tests. Add support to read from a different file. This is useful for: - regression tests before/afer some changes; - preparing new unit tests; - test a different yaml before adding its contents at tools/unittests/kdoc-test.yaml. It should be noticed that passing an argument to a unit test is not too trivial, as unittest core will load itself the runner with a separate environment. The best (only?) way to do it is by setting the system environment. This way, when the class is called by the unit test loader, it can pick the var from the environment without relying on a global variable. The unittest_helper has already provision for it, so let's use its support. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_kdoc_parser.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdo= c_parser.py index dd3d576e1b93..eb2225529325 100755 --- a/tools/unittests/test_kdoc_parser.py +++ b/tools/unittests/test_kdoc_parser.py @@ -29,7 +29,7 @@ from kdoc.kdoc_output import RestFormat, ManFormat =20 from kdoc.xforms_lists import CTransforms =20 -from unittest_helper import run_unittest +from unittest_helper import TestUnits =20 =20 # @@ -37,6 +37,10 @@ from unittest_helper import run_unittest # TEST_FILE =3D os.path.join(SRC_DIR, "kdoc-test.yaml") =20 +env =3D { + "yaml_file": TEST_FILE +} + # # Ancillary logic to clean whitespaces # @@ -442,7 +446,9 @@ class KernelDocDynamicTests(): optional ones. """ =20 - with open(TEST_FILE, encoding=3D"utf-8") as fp: + test_file =3D os.environ.get("yaml_file", TEST_FILE) + + with open(test_file, encoding=3D"utf-8") as fp: testset =3D yaml.safe_load(fp) =20 tests =3D testset["tests"] @@ -503,4 +509,15 @@ KernelDocDynamicTests.create_tests() # Run all tests # if __name__ =3D=3D "__main__": - run_unittest(__file__) + runner =3D TestUnits() + parser =3D runner.parse_args() + parser.add_argument("-y", "--yaml-file", "--yaml", + help=3D'Name of the yaml file to load') + + args =3D parser.parse_args() + + if args.yaml_file: + env["yaml_file"] =3D os.path.expanduser(args.yaml_file) + + # Run tests with customized arguments + runner.run(__file__, parser=3Dparser, args=3Dargs, env=3Denv) --=20 2.52.0