From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"John Snow" <jsnow@redhat.com>, "Kevin Wolf" <kwolf@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Mads Ynddal" <mads@ynddal.dk>
Subject: [PATCH 4/6] tracetool: add type annotations
Date: Wed, 8 Oct 2025 08:35:43 +0200 [thread overview]
Message-ID: <20251008063546.376603-5-pbonzini@redhat.com> (raw)
In-Reply-To: <20251008063546.376603-1-pbonzini@redhat.com>
Created with a profiling-based tool, righttyper. I used this script:
python -m righttyper --generate-stubs --no-sampling --overwrite -- ./tracetool.py --help
find . -name "*.pyi" | while read fname; do
merge-pyi --in-place -b bak.$fmt ${fname%i} $fname
done
for fmt in c h rs d log-stap simpletrace-stap stap ust-events-c ust-events-h; do
find . -name '*.pyi*' | xargs rm
python -m righttyper --generate-stubs --no-sampling --overwrite ./tracetool.py \
--format=$fmt --backends=ust,simple,syslog,ftrace,dtrace,log --group=testsuite \
--binary=qemu --probe-prefix=qemu ../tests/tracetool/trace-events outfile.$fmt
find . -name "*.pyi" | while read fname; do
merge-pyi --in-place -b bak.$fmt ${fname%i} $fname
done
done
python -m isort $(find tracetool -name "*.py")
Running the script took about 5 minutes. The errors were mostly
due to misunderstanding the "try_import" function:
tracetool/backend/__init__.py:83: error: Incompatible types in assignment (expression has type Module, variable has type "tuple[bool, Module]") [assignment]
tracetool/backend/__init__.py:117: error: Incompatible types in assignment (expression has type Module, variable has type "str") [assignment]
tracetool/__init__.py:543: error: Incompatible return value type (got "tuple[bool, None]", expected "tuple[bool, Module]") [return-value]
tracetool/format/__init__.py:60: error: Incompatible types in assignment (expression has type Module, variable has type "tuple[bool, Module]") [assignment]
tracetool/format/__init__.py:85: error: Argument 2 to "try_import" has incompatible type "str"; expected "None" [arg-type]
tracetool/format/__init__.py:88: error: Module not callable [operator]
On top of this I fixed a little weirdness, while leaving the unannotated
functions unchanged. Being profiling-based, righttyper did not annotate
anything not covered by the check-tracetool testsuite:
- error cases
- PRIxxx macros
It also reported list[Never] for always-empty lists, which is incorrect.
Righttyper also has a few limitations: it does not annotate nested functions
(there were only four of them), or "*args" argument lists. These are fixed
in the next patch.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/tracetool.py | 5 +-
scripts/tracetool/__init__.py | 54 ++++++++++----------
scripts/tracetool/backend/__init__.py | 19 +++----
scripts/tracetool/backend/dtrace.py | 16 +++---
scripts/tracetool/backend/ftrace.py | 10 ++--
scripts/tracetool/backend/log.py | 10 ++--
scripts/tracetool/backend/simple.py | 16 +++---
scripts/tracetool/backend/syslog.py | 10 ++--
scripts/tracetool/backend/ust.py | 8 +--
scripts/tracetool/format/__init__.py | 7 +--
scripts/tracetool/format/c.py | 5 +-
scripts/tracetool/format/d.py | 5 +-
scripts/tracetool/format/h.py | 5 +-
scripts/tracetool/format/log_stap.py | 7 +--
scripts/tracetool/format/rs.py | 5 +-
scripts/tracetool/format/simpletrace_stap.py | 5 +-
scripts/tracetool/format/stap.py | 7 +--
scripts/tracetool/format/ust_events_c.py | 5 +-
scripts/tracetool/format/ust_events_h.py | 5 +-
19 files changed, 109 insertions(+), 95 deletions(-)
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 390f1a371bf..0688c9cf5f4 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -16,6 +16,7 @@
import getopt
import sys
+from typing import NoReturn
import tracetool.backend
import tracetool.format
@@ -23,7 +24,7 @@
_SCRIPT = ""
-def error_opt(msg = None):
+def error_opt(msg: str | None = None) -> NoReturn:
if msg is not None:
error_write("Error: " + msg + "\n")
@@ -58,7 +59,7 @@ def error_opt(msg = None):
else:
sys.exit(1)
-def main(args):
+def main(args: list[str]) -> None:
global _SCRIPT
_SCRIPT = args[0]
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 09ff6da6612..62895261a0d 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -17,13 +17,15 @@
import os
import re
import sys
+from io import TextIOWrapper
from pathlib import PurePath
+from typing import Any, Iterator
import tracetool.backend
import tracetool.format
-def error_write(*lines):
+def error_write(*lines) -> None:
"""Write a set of error lines."""
sys.stderr.writelines("\n".join(lines) + "\n")
@@ -48,7 +50,7 @@ def error(*lines):
'MAX': 'j',
}
-def expand_format_string(c_fmt, prefix=""):
+def expand_format_string(c_fmt: str, prefix: str="") -> str:
def pri_macro_to_fmt(pri_macro):
assert pri_macro.startswith("PRI")
fmt_type = pri_macro[3] # 'd', 'i', 'u', or 'x'
@@ -80,12 +82,12 @@ def pri_macro_to_fmt(pri_macro):
out_filename = '<none>'
out_fobj = sys.stdout
-def out_open(filename):
+def out_open(filename: str) -> None:
global out_filename, out_fobj
out_filename = posix_relpath(filename)
out_fobj = open(filename, 'wt')
-def out(*lines, **kwargs):
+def out(*lines, **kwargs) -> None:
"""Write a set of output lines.
You can use kwargs as a shorthand for mapping variables when formatting all
@@ -177,7 +179,7 @@ def out(*lines, **kwargs):
"bool",
}
-def validate_type(name):
+def validate_type(name: str) -> None:
bits = name.split(" ")
for bit in bits:
bit = re.sub(r"\*", "", bit)
@@ -192,7 +194,7 @@ def validate_type(name):
"other complex pointer types should be "
"declared as 'void *'" % name)
-def c_type_to_rust(name):
+def c_type_to_rust(name: str) -> str:
ptr = False
const = False
name = name.rstrip()
@@ -227,7 +229,7 @@ def c_type_to_rust(name):
class Arguments:
"""Event arguments description."""
- def __init__(self, args):
+ def __init__(self, args: list[tuple[str, str]]) -> None:
"""
Parameters
----------
@@ -242,7 +244,7 @@ def __init__(self, args):
self._args.append(arg)
@staticmethod
- def build(arg_str):
+ def build(arg_str: str) -> Arguments:
"""Build and Arguments instance from an argument string.
Parameters
@@ -275,15 +277,15 @@ def __getitem__(self, index):
else:
return self._args[index]
- def __iter__(self):
+ def __iter__(self) -> Iterator[tuple[str, str]]:
"""Iterate over the (type, name) pairs."""
return iter(self._args)
- def __len__(self):
+ def __len__(self) -> int:
"""Number of arguments."""
return len(self._args)
- def __str__(self):
+ def __str__(self) -> str:
"""String suitable for declaring function arguments."""
def onearg(t, n):
if t[-1] == '*':
@@ -300,11 +302,11 @@ def __repr__(self):
"""Evaluable string representation for this object."""
return "Arguments(\"%s\")" % str(self)
- def names(self):
+ def names(self) -> list[str]:
"""List of argument names."""
return [ name for _, name in self._args ]
- def types(self):
+ def types(self) -> list[str]:
"""List of argument types."""
return [ type_ for type_, _ in self._args ]
@@ -312,12 +314,12 @@ def casted(self):
"""List of argument names casted to their type."""
return ["(%s)%s" % (type_, name) for type_, name in self._args]
- def rust_decl_extern(self):
+ def rust_decl_extern(self) -> str:
"""Return a Rust argument list for an extern "C" function"""
return ", ".join((f"_{name}: {c_type_to_rust(type_)}"
for type_, name in self._args))
- def rust_decl(self):
+ def rust_decl(self) -> str:
"""Return a Rust argument list for a tracepoint function"""
def decl_type(type_):
if type_ == "const char *":
@@ -327,7 +329,7 @@ def decl_type(type_):
return ", ".join((f"_{name}: {decl_type(type_)}"
for type_, name in self._args))
- def rust_call_extern(self):
+ def rust_call_extern(self) -> str:
"""Return a Rust argument list for a call to an extern "C" function"""
def rust_cast(name, type_):
if type_ == "const char *":
@@ -336,7 +338,7 @@ def rust_cast(name, type_):
return ", ".join((rust_cast(name, type_) for type_, name in self._args))
- def rust_call_varargs(self):
+ def rust_call_varargs(self) -> str:
"""Return a Rust argument list for a call to a C varargs function"""
def rust_cast(name, type_):
if type_ == "const char *":
@@ -379,7 +381,7 @@ class Event(object):
_VALID_PROPS = set(["disable"])
- def __init__(self, name, props, fmt, args, lineno, filename):
+ def __init__(self, name: str, props: list[str], fmt: str, args: Arguments, lineno: int, filename: str) -> None:
"""
Parameters
----------
@@ -415,7 +417,7 @@ def __init__(self, name, props, fmt, args, lineno, filename):
@staticmethod
- def build(line_str, lineno, filename):
+ def build(line_str: str, lineno: int, filename: str) -> Event:
"""Build an Event instance from a string.
Parameters
@@ -457,7 +459,7 @@ def __repr__(self):
# arguments with that format, hence the non-greedy version of it.
_FMT = re.compile(r"(%[\d\.]*\w+|%.*?PRI\S+)")
- def formats(self):
+ def formats(self) -> list[str]:
"""List conversion specifiers in the argument print format string."""
return self._FMT.findall(self.fmt)
@@ -467,13 +469,13 @@ def formats(self):
QEMU_BACKEND_DSTATE = "TRACE_%(NAME)s_BACKEND_DSTATE"
QEMU_EVENT = "_TRACE_%(NAME)s_EVENT"
- def api(self, fmt=None):
+ def api(self, fmt: str|None=None) -> str:
if fmt is None:
fmt = Event.QEMU_TRACE
return fmt % {"name": self.name, "NAME": self.name.upper()}
-def read_events(fobj, fname):
+def read_events(fobj: TextIOWrapper, fname: str) -> list[Event]:
"""Generate the output for the given (format, backends) pair.
Parameters
@@ -512,7 +514,7 @@ class TracetoolError (Exception):
pass
-def try_import(mod_name, attr_name=None, attr_default=None):
+def try_import(mod_name: str, attr_name: str | None=None, attr_default: Any=None) -> tuple[bool, Any]:
"""Try to import a module and get an attribute from it.
Parameters
@@ -538,8 +540,8 @@ def try_import(mod_name, attr_name=None, attr_default=None):
return False, None
-def generate(events, group, format, backends,
- binary=None, probe_prefix=None):
+def generate(events: list[Event], group: str, format: str, backends: list[str],
+ binary: str|None=None, probe_prefix: str|None=None) -> None:
"""Generate the output for the given (format, backends) pair.
Parameters
@@ -579,7 +581,7 @@ def generate(events, group, format, backends,
tracetool.format.generate(events, format, backend, group)
-def posix_relpath(path, start=None):
+def posix_relpath(path: str, start: str|None=None) -> str:
try:
path = os.path.relpath(path, start)
except ValueError:
diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
index 8cc9c821382..645e78ece06 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -60,11 +60,12 @@
import os
+from typing import Any, Iterator
import tracetool
-def get_list(only_public = False):
+def get_list(only_public: bool = False) -> list[tuple[str, str]]:
"""Get a list of (name, description) pairs."""
res = [("nop", "Tracing disabled.")]
modnames = []
@@ -93,7 +94,7 @@ def get_list(only_public = False):
return res
-def exists(name):
+def exists(name: str) -> bool:
"""Return whether the given backend exists."""
if len(name) == 0:
return False
@@ -104,7 +105,7 @@ def exists(name):
class Wrapper:
- def __init__(self, backends, format):
+ def __init__(self, backends: list[str], format: str) -> None:
self._backends = [backend.replace("-", "_") for backend in backends]
self._format = format.replace("-", "_")
self.check_trace_event_get_state = False
@@ -115,13 +116,13 @@ def __init__(self, backends, format):
check_trace_event_get_state = getattr(backend, "CHECK_TRACE_EVENT_GET_STATE", False)
self.check_trace_event_get_state = self.check_trace_event_get_state or check_trace_event_get_state
- def backend_modules(self):
+ def backend_modules(self) -> Iterator[Any]:
for backend in self._backends:
module = tracetool.try_import("tracetool.backend." + backend)[1]
if module is not None:
yield module
- def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs):
+ def _run_function(self, name: str, *args, check_trace_event_get_state: bool | None=None, **kwargs) -> None:
for backend in self.backend_modules():
func = getattr(backend, name % self._format, None)
if func is not None and \
@@ -129,14 +130,14 @@ def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs)
check_trace_event_get_state == getattr(backend, 'CHECK_TRACE_EVENT_GET_STATE', False)):
func(*args, **kwargs)
- def generate_begin(self, events, group):
+ def generate_begin(self, events: list[tracetool.Event], group: str) -> None:
self._run_function("generate_%s_begin", events, group)
- def generate(self, event, group, check_trace_event_get_state=None):
+ def generate(self, event: tracetool.Event, group: str, check_trace_event_get_state: bool | None=None) -> None:
self._run_function("generate_%s", event, group, check_trace_event_get_state=check_trace_event_get_state)
- def generate_backend_dstate(self, event, group):
+ def generate_backend_dstate(self, event: tracetool.Event, group: str) -> None:
self._run_function("generate_%s_backend_dstate", event, group)
- def generate_end(self, events, group):
+ def generate_end(self, events: list[tracetool.Event], group: str) -> None:
self._run_function("generate_%s_end", events, group)
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index fa941b2ff5c..d9f4b8f09c8 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -14,28 +14,28 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
PUBLIC = True
-PROBEPREFIX = None
+PROBEPREFIX: str|None = None
-def probeprefix():
+def probeprefix() -> str:
if PROBEPREFIX is None:
raise ValueError("you must set PROBEPREFIX")
return PROBEPREFIX
-BINARY = None
+BINARY: str|None = None
-def binary():
+def binary() -> str:
if BINARY is None:
raise ValueError("you must set BINARY")
return BINARY
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
if group == "root":
header = "trace-dtrace-root.h"
else:
@@ -62,12 +62,12 @@ def generate_h_begin(events, group):
'#endif',
uppername=e.name.upper())
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
out(' QEMU_%(uppername)s(%(argnames)s);',
uppername=event.name.upper(),
argnames=", ".join(event.args.names()))
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' QEMU_%(uppername)s_ENABLED() || \\',
uppername=event.name.upper())
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index 40bb323f5e6..fa4a40d44a8 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -14,18 +14,18 @@
__email__ = "stefanha@redhat.com"
-from tracetool import expand_format_string, out
+from tracetool import Event, expand_format_string, out
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
out('#include "trace/ftrace.h"',
'')
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
@@ -41,11 +41,11 @@ def generate_h(event, group):
argnames=argnames)
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
-def generate_rs(event, group):
+def generate_rs(event: Event, group: str) -> None:
out(' let format_string = c"%(fmt)s";',
' unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, %(args)s);}',
fmt=expand_format_string(event.fmt),
diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py
index d346a19e40f..39d777218be 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -14,18 +14,18 @@
__email__ = "stefanha@redhat.com"
-from tracetool import expand_format_string, out
+from tracetool import Event, expand_format_string, out
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
out('#include "qemu/log-for-trace.h"',
'')
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
@@ -42,11 +42,11 @@ def generate_h(event, group):
argnames=argnames)
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
-def generate_rs(event, group):
+def generate_rs(event: Event, group: str) -> None:
out(' let format_string = c"%(fmt)s\\n";',
' if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {',
' unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, %(args)s);}',
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 9c691dc231b..519f7a09e5c 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -14,13 +14,13 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
-def is_string(arg):
+def is_string(arg: str) -> bool:
strtype = ('const char*', 'char*', 'const char *', 'char *')
arg_strip = arg.lstrip()
if arg_strip.startswith(strtype) and arg_strip.count('*') == 1:
@@ -29,7 +29,7 @@ def is_string(arg):
return False
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
for event in events:
out('void _simple_%(api)s(%(args)s);',
api=event.api(),
@@ -37,25 +37,25 @@ def generate_h_begin(events, group):
out('')
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
out(' _simple_%(api)s(%(args)s);',
api=event.api(),
args=", ".join(event.args.names()))
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
-def generate_c_begin(events, group):
+def generate_c_begin(events: list[Event], group: str) -> None:
out('#include "qemu/osdep.h"',
'#include "trace/control.h"',
'#include "trace/simple.h"',
'')
-def generate_c(event, group):
+def generate_c(event: Event, group: str) -> None:
out('void _simple_%(api)s(%(args)s)',
'{',
' TraceBufferRecord rec;',
@@ -100,7 +100,7 @@ def generate_c(event, group):
'}',
'')
-def generate_rs(event, group):
+def generate_rs(event: Event, group: str) -> None:
out(' extern "C" { fn _simple_%(api)s(%(rust_args)s); }',
' unsafe { _simple_%(api)s(%(args)s); }',
api=event.api(),
diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backend/syslog.py
index 9311453c5a7..dd39df6af6f 100644
--- a/scripts/tracetool/backend/syslog.py
+++ b/scripts/tracetool/backend/syslog.py
@@ -14,18 +14,18 @@
__email__ = "stefanha@redhat.com"
-from tracetool import expand_format_string, out
+from tracetool import Event, expand_format_string, out
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
out('#include <syslog.h>',
'')
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
@@ -39,12 +39,12 @@ def generate_h(event, group):
fmt=event.fmt.rstrip("\n"),
argnames=argnames)
-def generate_rs(event, group):
+def generate_rs(event: Event, group: str) -> None:
out(' let format_string = c"%(fmt)s";',
' unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, %(args)s);}',
fmt=expand_format_string(event.fmt),
args=event.args.rust_call_varargs())
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index f2270725128..a26cd7ace61 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -14,12 +14,12 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
PUBLIC = True
-def generate_h_begin(events, group):
+def generate_h_begin(events: list[Event], group: str) -> None:
header = 'trace-ust-' + group + '.h'
out('#include <lttng/tracepoint.h>',
'#include "%s"' % header,
@@ -31,7 +31,7 @@ def generate_h_begin(events, group):
'')
-def generate_h(event, group):
+def generate_h(event: Event, group: str) -> None:
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
@@ -41,6 +41,6 @@ def generate_h(event, group):
tp_args=argnames)
-def generate_h_backend_dstate(event, group):
+def generate_h_backend_dstate(event: Event, group: str) -> None:
out(' tracepoint_enabled(qemu, %(name)s) || \\',
name=event.name)
diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
index 4c606d57579..c287e93ed30 100644
--- a/scripts/tracetool/format/__init__.py
+++ b/scripts/tracetool/format/__init__.py
@@ -40,9 +40,10 @@
import os
import tracetool
+from tracetool.backend import Wrapper
-def get_list():
+def get_list() -> list[tuple[str, str]]:
"""Get a list of (name, description) pairs."""
res = []
modnames = []
@@ -67,7 +68,7 @@ def get_list():
return res
-def exists(name):
+def exists(name: str) -> bool:
"""Return whether the given format exists."""
if len(name) == 0:
return False
@@ -75,7 +76,7 @@ def exists(name):
return tracetool.try_import("tracetool.format." + name)[0]
-def generate(events, format, backend, group):
+def generate(events: list[tracetool.Event], format: str, backend: Wrapper, group: str) -> None:
if not exists(format):
raise ValueError("unknown format: %s" % format)
format = format.replace("-", "_")
diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py
index 5b3459f2beb..e8848c51051 100644
--- a/scripts/tracetool/format/c.py
+++ b/scripts/tracetool/format/c.py
@@ -14,10 +14,11 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
active_events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
index dda80eeb766..2abf8bc24ba 100644
--- a/scripts/tracetool/format/d.py
+++ b/scripts/tracetool/format/d.py
@@ -16,7 +16,8 @@
from sys import platform
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
# Reserved keywords from
# https://wikis.oracle.com/display/DTrace/Types,+Operators+and+Expressions
@@ -31,7 +32,7 @@
)
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index d04cabc63e8..2324234dd24 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -14,10 +14,11 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
header = "trace/control.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
diff --git a/scripts/tracetool/format/log_stap.py b/scripts/tracetool/format/log_stap.py
index 65514442030..d7ad0bb6a72 100644
--- a/scripts/tracetool/format/log_stap.py
+++ b/scripts/tracetool/format/log_stap.py
@@ -15,7 +15,8 @@
import re
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
from tracetool.backend.dtrace import binary, probeprefix
from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape
@@ -30,7 +31,7 @@ def c_macro_to_format(macro):
raise Exception("Unhandled macro '%s'" % macro)
-def c_fmt_to_stap(fmt):
+def c_fmt_to_stap(fmt: str) -> str:
state = 0
bits = []
literal = ""
@@ -85,7 +86,7 @@ def c_fmt_to_stap(fmt):
fmt = re.sub(r"%(\d*)(l+|z)(x|u|d)", r"%\1\3", "".join(bits))
return fmt
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
diff --git a/scripts/tracetool/format/rs.py b/scripts/tracetool/format/rs.py
index 71b847cb7bc..27a4025e3d6 100644
--- a/scripts/tracetool/format/rs.py
+++ b/scripts/tracetool/format/rs.py
@@ -14,10 +14,11 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
out('// SPDX-License-Identifier: GPL-2.0-or-later',
'// This file is @generated by tracetool, do not edit.',
'',
diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py
index eb58b4b9592..c76cf426853 100644
--- a/scripts/tracetool/format/simpletrace_stap.py
+++ b/scripts/tracetool/format/simpletrace_stap.py
@@ -14,13 +14,14 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
from tracetool.backend.dtrace import probeprefix
from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
index 808fb478b5f..af98f3c44a3 100644
--- a/scripts/tracetool/format/stap.py
+++ b/scripts/tracetool/format/stap.py
@@ -14,7 +14,8 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
from tracetool.backend.dtrace import binary, probeprefix
# Technically 'self' is not used by systemtap yet, but
@@ -27,14 +28,14 @@
)
-def stap_escape(identifier):
+def stap_escape(identifier: str) -> str:
# Append underscore to reserved keywords
if identifier in RESERVED_WORDS:
return identifier + '_'
return identifier
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
events = [e for e in events
if "disable" not in e.properties]
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
index fa7d5437984..2c8256ed7a8 100644
--- a/scripts/tracetool/format/ust_events_c.py
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -14,10 +14,11 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
events = [e for e in events
if "disabled" not in e.properties]
diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py
index 1057d02577e..f0ffcae6941 100644
--- a/scripts/tracetool/format/ust_events_h.py
+++ b/scripts/tracetool/format/ust_events_h.py
@@ -14,10 +14,11 @@
__email__ = "stefanha@redhat.com"
-from tracetool import out
+from tracetool import Event, out
+from tracetool.backend import Wrapper
-def generate(events, backend, group):
+def generate(events: list[Event], backend: Wrapper, group: str) -> None:
events = [e for e in events
if "disabled" not in e.properties]
--
2.51.0
next prev parent reply other threads:[~2025-10-08 6:36 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-08 6:35 [PATCH 0/6] tracetool: add mypy --strict checking [AI discussion ahead!] Paolo Bonzini
2025-10-08 6:35 ` [PATCH 1/6] tracetool: rename variable with conflicting types Paolo Bonzini
2025-10-08 9:27 ` Daniel P. Berrangé
2025-10-08 18:06 ` Stefan Hajnoczi
2025-10-08 6:35 ` [PATCH 2/6] tracetool: apply isort and add check Paolo Bonzini
2025-10-08 9:29 ` Daniel P. Berrangé
2025-10-08 17:58 ` Stefan Hajnoczi
2025-10-09 7:52 ` Daniel P. Berrangé
2025-10-09 8:22 ` Paolo Bonzini
2025-10-09 8:58 ` Daniel P. Berrangé
2025-10-09 11:26 ` Paolo Bonzini
2025-10-09 12:05 ` Daniel P. Berrangé
2025-10-09 7:58 ` Paolo Bonzini
2025-10-08 6:35 ` [PATCH 3/6] tracetool: "import annotations" Paolo Bonzini
2025-10-08 9:31 ` Daniel P. Berrangé
2025-10-08 18:06 ` Stefan Hajnoczi
2025-10-08 6:35 ` Paolo Bonzini [this message]
2025-10-08 18:09 ` [PATCH 4/6] tracetool: add type annotations Stefan Hajnoczi
2025-10-08 6:35 ` [PATCH 5/6] tracetool: complete typing annotations Paolo Bonzini
2025-10-08 18:10 ` Stefan Hajnoczi
2025-10-08 6:35 ` [PATCH 6/6] tracetool: add typing checks to "make -C python check" Paolo Bonzini
2025-10-08 9:32 ` Daniel P. Berrangé
2025-10-08 18:12 ` Stefan Hajnoczi
2025-10-08 7:18 ` [PATCH 0/6] tracetool: add mypy --strict checking [AI discussion ahead!] Markus Armbruster
2025-10-08 10:34 ` Daniel P. Berrangé
2025-10-10 12:38 ` Markus Armbruster
2025-10-10 13:49 ` Paolo Bonzini
2025-10-10 17:41 ` Markus Armbruster
2025-10-08 10:40 ` Daniel P. Berrangé
2025-10-08 17:23 ` Stefan Hajnoczi
2025-10-08 17:41 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251008063546.376603-5-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=jsnow@redhat.com \
--cc=kwolf@redhat.com \
--cc=mads@ynddal.dk \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).