From nobody Mon Feb 9 23:00:11 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1768849779; cv=none; d=zohomail.com; s=zohoarc; b=Qg5PzUP1qkWkhf4zICuIE+GnxvKrX9ZBfTCrhZcWSCEwF4djUapkAjePPcHqj9vdTWS97lOHWkYBNK0XErwGQ2Y0xbdQ8TsS66XPg1ULTpoy1bjWcDvJ6jW6l4K7tXY4JIoZsnGW9atje1x4LqVzB+iCeWK1nbj9ewJ9iK9Mpeo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768849779; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=D+Zs1MQT076hrWr8oPohlhJ/KZenoAoXSpTdwuz04yA=; b=jBEJ9HoSvu41HqC00FOCjoneMmsywbEr1a/T82r7m+Wjzxhv35GPVwmwTMvd5zkoLSF2VjLmA9hB28UnhYMmw2IxgbjHyVuLNElgU6SmNWSEP2V8IMo+UNmv8KTQVXI54HWrmWftHklQ2vjzubTMRl7coeLcqcc5/GpuhWYTAvg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1768849779533819.8433407558122; Mon, 19 Jan 2026 11:09:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vhucM-0002DK-No; Mon, 19 Jan 2026 14:08:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vhucE-00027i-7J for qemu-devel@nongnu.org; Mon, 19 Jan 2026 14:08:43 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vhucA-0000ux-If for qemu-devel@nongnu.org; Mon, 19 Jan 2026 14:08:41 -0500 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-33-R9fBAaTRNn2rsdUgqGtSmw-1; Mon, 19 Jan 2026 14:08:34 -0500 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 55E9819560A1; Mon, 19 Jan 2026 19:08:33 +0000 (UTC) Received: from localhost (unknown [10.2.16.150]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EFFF8180049F; Mon, 19 Jan 2026 19:08:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768849717; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D+Zs1MQT076hrWr8oPohlhJ/KZenoAoXSpTdwuz04yA=; b=YO+H4B9FXVi6nRLmloI3PzYc0RuyLAWtBziPcK/HaFhZGHmeBbd26321PTD2gse/v7lmu7 3C32pMZtupw4ZF98fXjf4WL/pADh2wAC7l7wYX+0DbJVOhOzqVBvrpevh8/mi4JJoTq1xQ LMKqYoJYcwN5NwvnLZI6rKjchM3eUO0= X-MC-Unique: R9fBAaTRNn2rsdUgqGtSmw-1 X-Mimecast-MFC-AGG-ID: R9fBAaTRNn2rsdUgqGtSmw_1768849713 From: Stefan Hajnoczi To: qemu-devel@nongnu.org Cc: Cleber Rosa , Stefan Hajnoczi , Mads Ynddal , Richard Henderson , John Snow , Paolo Bonzini Subject: [PULL 4/8] tracetool: add type annotations Date: Mon, 19 Jan 2026 14:08:19 -0500 Message-ID: <20260119190823.867761-5-stefanha@redhat.com> In-Reply-To: <20260119190823.867761-1-stefanha@redhat.com> References: <20260119190823.867761-1-stefanha@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=stefanha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.016, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1768849782119154100 Content-Type: text/plain; charset="utf-8" From: Paolo Bonzini Created with a profiling-based tool, righttyper. I used this script: python -m righttyper --generate-stubs --no-sampling --overwrite -- ./tra= cetool.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-event= s-h; do find . -name '*.pyi*' | xargs rm python -m righttyper --generate-stubs --no-sampling --overwrite ./trace= tool.py \ --format=3D$fmt --backends=3Dust,simple,syslog,ftrace,dtrace,log --gr= oup=3Dtestsuite \ --binary=3Dqemu --probe-prefix=3Dqemu ../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]") [as= signment] tracetool/backend/__init__.py:117: error: Incompatible types in assignmen= t (expression has type Module, variable has type "str") [assignment] tracetool/__init__.py:543: error: Incompatible return value type (got "tu= ple[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]") [ass= ignment] tracetool/format/__init__.py:85: error: Argument 2 to "try_import" has in= compatible 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 Acked-by: Stefan Hajnoczi Message-ID: <20251008063546.376603-5-pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi --- 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 390f1a371b..0688c9cf5f 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -16,6 +16,7 @@ =20 import getopt import sys +from typing import NoReturn =20 import tracetool.backend import tracetool.format @@ -23,7 +24,7 @@ =20 _SCRIPT =3D "" =20 -def error_opt(msg =3D None): +def error_opt(msg: str | None =3D None) -> NoReturn: if msg is not None: error_write("Error: " + msg + "\n") =20 @@ -58,7 +59,7 @@ def error_opt(msg =3D None): else: sys.exit(1) =20 -def main(args): +def main(args: list[str]) -> None: global _SCRIPT _SCRIPT =3D args[0] =20 diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 0316f3f852..f2692de477 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 =20 import tracetool.backend import tracetool.format =20 =20 -def error_write(*lines): +def error_write(*lines) -> None: """Write a set of error lines.""" sys.stderr.writelines("\n".join(lines) + "\n") =20 @@ -48,7 +50,7 @@ def error(*lines): 'MAX': 'j', } =20 -def expand_format_string(c_fmt, prefix=3D""): +def expand_format_string(c_fmt: str, prefix: str=3D"") -> str: def pri_macro_to_fmt(pri_macro): assert pri_macro.startswith("PRI") fmt_type =3D pri_macro[3] # 'd', 'i', 'u', or 'x' @@ -80,12 +82,12 @@ def pri_macro_to_fmt(pri_macro): out_filename =3D '' out_fobj =3D sys.stdout =20 -def out_open(filename): +def out_open(filename: str) -> None: global out_filename, out_fobj out_filename =3D posix_relpath(filename) out_fobj =3D open(filename, 'wt') =20 -def out(*lines, **kwargs): +def out(*lines, **kwargs) -> None: """Write a set of output lines. =20 You can use kwargs as a shorthand for mapping variables when formattin= g all @@ -177,7 +179,7 @@ def out(*lines, **kwargs): "bool", } =20 -def validate_type(name): +def validate_type(name: str) -> None: bits =3D name.split(" ") for bit in bits: bit =3D re.sub(r"\*", "", bit) @@ -192,7 +194,7 @@ def validate_type(name): "other complex pointer types should be " "declared as 'void *'" % name) =20 -def c_type_to_rust(name): +def c_type_to_rust(name: str) -> str: ptr =3D False const =3D False name =3D name.rstrip() @@ -227,7 +229,7 @@ def c_type_to_rust(name): class Arguments: """Event arguments description.""" =20 - 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) =20 @staticmethod - def build(arg_str): + def build(arg_str: str) -> Arguments: """Build and Arguments instance from an argument string. =20 Parameters @@ -275,15 +277,15 @@ def __getitem__(self, index): else: return self._args[index] =20 - def __iter__(self): + def __iter__(self) -> Iterator[tuple[str, str]]: """Iterate over the (type, name) pairs.""" return iter(self._args) =20 - def __len__(self): + def __len__(self) -> int: """Number of arguments.""" return len(self._args) =20 - def __str__(self): + def __str__(self) -> str: """String suitable for declaring function arguments.""" def onearg(t, n): if t[-1] =3D=3D '*': @@ -300,11 +302,11 @@ def __repr__(self): """Evaluable string representation for this object.""" return "Arguments(\"%s\")" % str(self) =20 - def names(self): + def names(self) -> list[str]: """List of argument names.""" return [ name for _, name in self._args ] =20 - def types(self): + def types(self) -> list[str]: """List of argument types.""" return [ type_ for type_, _ in self._args ] =20 @@ -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] =20 - 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)) =20 - def rust_decl(self): + def rust_decl(self) -> str: """Return a Rust argument list for a tracepoint function""" def decl_type(type_): if type_ =3D=3D "const char *": @@ -327,7 +329,7 @@ def decl_type(type_): return ", ".join((f"_{name}: {decl_type(type_)}" for type_, name in self._args)) =20 - def rust_call_extern(self): + def rust_call_extern(self) -> str: """Return a Rust argument list for a call to an extern "C" functio= n""" def rust_cast(name, type_): if type_ =3D=3D "const char *": @@ -336,7 +338,7 @@ def rust_cast(name, type_): =20 return ", ".join((rust_cast(name, type_) for type_, name in self._= args)) =20 - 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_ =3D=3D "const char *": @@ -379,7 +381,7 @@ class Event(object): =20 _VALID_PROPS =3D set(["disable"]) =20 - def __init__(self, name, props, fmt, args, lineno, filename): + def __init__(self, name: str, props: list[str], fmt: str, args: Argume= nts, lineno: int, filename: str) -> None: """ Parameters ---------- @@ -415,7 +417,7 @@ def __init__(self, name, props, fmt, args, lineno, file= name): =20 =20 @staticmethod - def build(line_str, lineno, filename): + def build(line_str: str, lineno: int, filename: str) -> Event: """Build an Event instance from a string. =20 Parameters @@ -457,7 +459,7 @@ def __repr__(self): # arguments with that format, hence the non-greedy version of it. _FMT =3D re.compile(r"(%[\d\.]*\w+|%.*?PRI\S+)") =20 - def formats(self): + def formats(self) -> list[str]: """List conversion specifiers in the argument print format string.= """ return self._FMT.findall(self.fmt) =20 @@ -468,13 +470,13 @@ def formats(self): QEMU_BACKEND_DSTATE =3D "TRACE_%(NAME)s_BACKEND_DSTATE" QEMU_EVENT =3D "_TRACE_%(NAME)s_EVENT" =20 - def api(self, fmt=3DNone): + def api(self, fmt: str|None=3DNone) -> str: if fmt is None: fmt =3D Event.QEMU_TRACE return fmt % {"name": self.name, "NAME": self.name.upper()} =20 =20 -def read_events(fobj, fname): +def read_events(fobj: TextIOWrapper, fname: str) -> list[Event]: """Generate the output for the given (format, backends) pair. =20 Parameters @@ -513,7 +515,7 @@ class TracetoolError (Exception): pass =20 =20 -def try_import(mod_name, attr_name=3DNone, attr_default=3DNone): +def try_import(mod_name: str, attr_name: str | None=3DNone, attr_default: = Any=3DNone) -> tuple[bool, Any]: """Try to import a module and get an attribute from it. =20 Parameters @@ -539,8 +541,8 @@ def try_import(mod_name, attr_name=3DNone, attr_default= =3DNone): return False, None =20 =20 -def generate(events, group, format, backends, - binary=3DNone, probe_prefix=3DNone): +def generate(events: list[Event], group: str, format: str, backends: list[= str], + binary: str|None=3DNone, probe_prefix: str|None=3DNone) -> No= ne: """Generate the output for the given (format, backends) pair. =20 Parameters @@ -580,7 +582,7 @@ def generate(events, group, format, backends, =20 tracetool.format.generate(events, format, backend, group) =20 -def posix_relpath(path, start=3DNone): +def posix_relpath(path: str, start: str|None=3DNone) -> str: try: path =3D os.path.relpath(path, start) except ValueError: diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/back= end/__init__.py index 8cc9c82138..645e78ece0 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -60,11 +60,12 @@ =20 =20 import os +from typing import Any, Iterator =20 import tracetool =20 =20 -def get_list(only_public =3D False): +def get_list(only_public: bool =3D False) -> list[tuple[str, str]]: """Get a list of (name, description) pairs.""" res =3D [("nop", "Tracing disabled.")] modnames =3D [] @@ -93,7 +94,7 @@ def get_list(only_public =3D False): return res =20 =20 -def exists(name): +def exists(name: str) -> bool: """Return whether the given backend exists.""" if len(name) =3D=3D 0: return False @@ -104,7 +105,7 @@ def exists(name): =20 =20 class Wrapper: - def __init__(self, backends, format): + def __init__(self, backends: list[str], format: str) -> None: self._backends =3D [backend.replace("-", "_") for backend in backe= nds] self._format =3D format.replace("-", "_") self.check_trace_event_get_state =3D False @@ -115,13 +116,13 @@ def __init__(self, backends, format): check_trace_event_get_state =3D getattr(backend, "CHECK_TRACE_= EVENT_GET_STATE", False) self.check_trace_event_get_state =3D self.check_trace_event_ge= t_state or check_trace_event_get_state =20 - def backend_modules(self): + def backend_modules(self) -> Iterator[Any]: for backend in self._backends: module =3D tracetool.try_import("tracetool.backend." + backen= d)[1] if module is not None: yield module =20 - def _run_function(self, name, *args, check_trace_event_get_state=3DNon= e, **kwargs): + def _run_function(self, name: str, *args, check_trace_event_get_state:= bool | None=3DNone, **kwargs) -> None: for backend in self.backend_modules(): func =3D getattr(backend, name % self._format, None) if func is not None and \ @@ -129,14 +130,14 @@ def _run_function(self, name, *args, check_trace_even= t_get_state=3DNone, **kwargs) check_trace_event_get_state =3D=3D getattr(backend, 'CHEC= K_TRACE_EVENT_GET_STATE', False)): func(*args, **kwargs) =20 - 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) =20 - def generate(self, event, group, check_trace_event_get_state=3DNone): + def generate(self, event: tracetool.Event, group: str, check_trace_eve= nt_get_state: bool | None=3DNone) -> None: self._run_function("generate_%s", event, group, check_trace_event_= get_state=3Dcheck_trace_event_get_state) =20 - 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) =20 - def generate_end(self, events, group): + def generate_end(self, events: list[tracetool.Event], group: str) -> N= one: self._run_function("generate_%s_end", events, group) diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backen= d/dtrace.py index c21a04c653..2ad607c551 100644 --- a/scripts/tracetool/backend/dtrace.py +++ b/scripts/tracetool/backend/dtrace.py @@ -14,28 +14,28 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out =20 PUBLIC =3D True =20 =20 -PROBEPREFIX =3D None +PROBEPREFIX: str|None =3D None =20 -def probeprefix(): +def probeprefix() -> str: if PROBEPREFIX is None: raise ValueError("you must set PROBEPREFIX") return PROBEPREFIX =20 =20 -BINARY =3D None +BINARY: str|None =3D None =20 -def binary(): +def binary() -> str: if BINARY is None: raise ValueError("you must set BINARY") return BINARY =20 =20 -def generate_h_begin(events, group): +def generate_h_begin(events: list[Event], group: str) -> None: if group =3D=3D "root": header =3D "trace-dtrace-root.h" else: @@ -62,13 +62,13 @@ def generate_h_begin(events, group): '#endif', uppername=3De.name.upper()) =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: out(' QEMU_%(uppername)s(%(argnames)s);', uppername=3Devent.name.upper(), argnames=3D", ".join(event.args.names())) =20 =20 -def generate_h_backend_dstate(event, group): +def generate_h_backend_dstate(event: Event, group: str) -> None: out(' QEMU_%(uppername)s_ENABLED() || \\', uppername=3Devent.name.upper()) =20 diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backen= d/ftrace.py index 40bb323f5e..fa4a40d44a 100644 --- a/scripts/tracetool/backend/ftrace.py +++ b/scripts/tracetool/backend/ftrace.py @@ -14,18 +14,18 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import expand_format_string, out +from tracetool import Event, expand_format_string, out =20 PUBLIC =3D True CHECK_TRACE_EVENT_GET_STATE =3D True =20 =20 -def generate_h_begin(events, group): +def generate_h_begin(events: list[Event], group: str) -> None: out('#include "trace/ftrace.h"', '') =20 =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: argnames =3D ", ".join(event.args.names()) if len(event.args) > 0: argnames =3D ", " + argnames @@ -41,11 +41,11 @@ def generate_h(event, group): argnames=3Dargnames) =20 =20 -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=3D"TRACE_" + event.name.upper()) =20 -def generate_rs(event, group): +def generate_rs(event: Event, group: str) -> None: out(' let format_string =3D c"%(fmt)s";', ' unsafe {bindings::ftrace_write(format_string.as_ptr() as = *const c_char, %(args)s);}', fmt=3Dexpand_format_string(event.fmt), diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/l= og.py index d346a19e40..39d777218b 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -14,18 +14,18 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import expand_format_string, out +from tracetool import Event, expand_format_string, out =20 PUBLIC =3D True CHECK_TRACE_EVENT_GET_STATE =3D True =20 =20 -def generate_h_begin(events, group): +def generate_h_begin(events: list[Event], group: str) -> None: out('#include "qemu/log-for-trace.h"', '') =20 =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: argnames =3D ", ".join(event.args.names()) if len(event.args) > 0: argnames =3D ", " + argnames @@ -42,11 +42,11 @@ def generate_h(event, group): argnames=3Dargnames) =20 =20 -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=3D"TRACE_" + event.name.upper()) =20 -def generate_rs(event, group): +def generate_rs(event: Event, group: str) -> None: out(' let format_string =3D c"%(fmt)s\\n";', ' if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TR= ACE) !=3D 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/backen= d/simple.py index 9c691dc231..519f7a09e5 100644 --- a/scripts/tracetool/backend/simple.py +++ b/scripts/tracetool/backend/simple.py @@ -14,13 +14,13 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out =20 PUBLIC =3D True CHECK_TRACE_EVENT_GET_STATE =3D True =20 =20 -def is_string(arg): +def is_string(arg: str) -> bool: strtype =3D ('const char*', 'char*', 'const char *', 'char *') arg_strip =3D arg.lstrip() if arg_strip.startswith(strtype) and arg_strip.count('*') =3D=3D 1: @@ -29,7 +29,7 @@ def is_string(arg): return False =20 =20 -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=3Devent.api(), @@ -37,25 +37,25 @@ def generate_h_begin(events, group): out('') =20 =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: out(' _simple_%(api)s(%(args)s);', api=3Devent.api(), args=3D", ".join(event.args.names())) =20 =20 -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=3D"TRACE_" + event.name.upper()) =20 =20 -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"', '') =20 =20 -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): '}', '') =20 -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=3Devent.api(), diff --git a/scripts/tracetool/backend/syslog.py b/scripts/tracetool/backen= d/syslog.py index 9311453c5a..dd39df6af6 100644 --- a/scripts/tracetool/backend/syslog.py +++ b/scripts/tracetool/backend/syslog.py @@ -14,18 +14,18 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import expand_format_string, out +from tracetool import Event, expand_format_string, out =20 PUBLIC =3D True CHECK_TRACE_EVENT_GET_STATE =3D True =20 =20 -def generate_h_begin(events, group): +def generate_h_begin(events: list[Event], group: str) -> None: out('#include ', '') =20 =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: argnames =3D ", ".join(event.args.names()) if len(event.args) > 0: argnames =3D ", " + argnames @@ -39,12 +39,12 @@ def generate_h(event, group): fmt=3Devent.fmt.rstrip("\n"), argnames=3Dargnames) =20 -def generate_rs(event, group): +def generate_rs(event: Event, group: str) -> None: out(' let format_string =3D c"%(fmt)s";', ' unsafe {::trace::syslog(::trace::LOG_INFO, format_string.= as_ptr() as *const c_char, %(args)s);}', fmt=3Dexpand_format_string(event.fmt), args=3Devent.args.rust_call_varargs()) =20 -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=3D"TRACE_" + event.name.upper()) diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/u= st.py index f227072512..a26cd7ace6 100644 --- a/scripts/tracetool/backend/ust.py +++ b/scripts/tracetool/backend/ust.py @@ -14,12 +14,12 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out =20 PUBLIC =3D True =20 =20 -def generate_h_begin(events, group): +def generate_h_begin(events: list[Event], group: str) -> None: header =3D 'trace-ust-' + group + '.h' out('#include ', '#include "%s"' % header, @@ -31,7 +31,7 @@ def generate_h_begin(events, group): '') =20 =20 -def generate_h(event, group): +def generate_h(event: Event, group: str) -> None: argnames =3D ", ".join(event.args.names()) if len(event.args) > 0: argnames =3D ", " + argnames @@ -41,6 +41,6 @@ def generate_h(event, group): tp_args=3Dargnames) =20 =20 -def generate_h_backend_dstate(event, group): +def generate_h_backend_dstate(event: Event, group: str) -> None: out(' tracepoint_enabled(qemu, %(name)s) || \\', name=3Devent.name) diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/forma= t/__init__.py index 4c606d5757..c287e93ed3 100644 --- a/scripts/tracetool/format/__init__.py +++ b/scripts/tracetool/format/__init__.py @@ -40,9 +40,10 @@ import os =20 import tracetool +from tracetool.backend import Wrapper =20 =20 -def get_list(): +def get_list() -> list[tuple[str, str]]: """Get a list of (name, description) pairs.""" res =3D [] modnames =3D [] @@ -67,7 +68,7 @@ def get_list(): return res =20 =20 -def exists(name): +def exists(name: str) -> bool: """Return whether the given format exists.""" if len(name) =3D=3D 0: return False @@ -75,7 +76,7 @@ def exists(name): return tracetool.try_import("tracetool.format." + name)[0] =20 =20 -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 =3D format.replace("-", "_") diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py index 5b3459f2be..e8848c5105 100644 --- a/scripts/tracetool/format/c.py +++ b/scripts/tracetool/format/c.py @@ -14,10 +14,11 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: active_events =3D [e for e in events if "disable" not in e.properties] =20 diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py index dda80eeb76..2abf8bc24b 100644 --- a/scripts/tracetool/format/d.py +++ b/scripts/tracetool/format/d.py @@ -16,7 +16,8 @@ =20 from sys import platform =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 # Reserved keywords from # https://wikis.oracle.com/display/DTrace/Types,+Operators+and+Expressions @@ -31,7 +32,7 @@ ) =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: events =3D [e for e in events if "disable" not in e.properties] =20 diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index d04cabc63e..2324234dd2 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -14,10 +14,11 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: header =3D "trace/control.h" =20 out('/* This file is autogenerated by tracetool, do not edit. */', diff --git a/scripts/tracetool/format/log_stap.py b/scripts/tracetool/forma= t/log_stap.py index 6551444203..d7ad0bb6a7 100644 --- a/scripts/tracetool/format/log_stap.py +++ b/scripts/tracetool/format/log_stap.py @@ -15,7 +15,8 @@ =20 import re =20 -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): =20 raise Exception("Unhandled macro '%s'" % macro) =20 -def c_fmt_to_stap(fmt): +def c_fmt_to_stap(fmt: str) -> str: state =3D 0 bits =3D [] literal =3D "" @@ -85,7 +86,7 @@ def c_fmt_to_stap(fmt): fmt =3D re.sub(r"%(\d*)(l+|z)(x|u|d)", r"%\1\3", "".join(bits)) return fmt =20 -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 1dc43a3b34..41e4636d97 100644 --- a/scripts/tracetool/format/rs.py +++ b/scripts/tracetool/format/rs.py @@ -14,10 +14,11 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 =20 -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/traceto= ol/format/simpletrace_stap.py index eb58b4b959..c76cf42685 100644 --- a/scripts/tracetool/format/simpletrace_stap.py +++ b/scripts/tracetool/format/simpletrace_stap.py @@ -14,13 +14,14 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -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 =20 =20 -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/st= ap.py index 808fb478b5..af98f3c44a 100644 --- a/scripts/tracetool/format/stap.py +++ b/scripts/tracetool/format/stap.py @@ -14,7 +14,8 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper from tracetool.backend.dtrace import binary, probeprefix =20 # Technically 'self' is not used by systemtap yet, but @@ -27,14 +28,14 @@ ) =20 =20 -def stap_escape(identifier): +def stap_escape(identifier: str) -> str: # Append underscore to reserved keywords if identifier in RESERVED_WORDS: return identifier + '_' return identifier =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: events =3D [e for e in events if "disable" not in e.properties] =20 diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/f= ormat/ust_events_c.py index fa7d543798..2c8256ed7a 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -14,10 +14,11 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: events =3D [e for e in events if "disabled" not in e.properties] =20 diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/f= ormat/ust_events_h.py index 1057d02577..f0ffcae694 100644 --- a/scripts/tracetool/format/ust_events_h.py +++ b/scripts/tracetool/format/ust_events_h.py @@ -14,10 +14,11 @@ __email__ =3D "stefanha@redhat.com" =20 =20 -from tracetool import out +from tracetool import Event, out +from tracetool.backend import Wrapper =20 =20 -def generate(events, backend, group): +def generate(events: list[Event], backend: Wrapper, group: str) -> None: events =3D [e for e in events if "disabled" not in e.properties] =20 --=20 2.52.0