From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
linux-perf-users@vger.kernel.org
Subject: [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py
Date: Fri, 25 Sep 2026 22:47:29 +0200 [thread overview]
Message-ID: <arbd4TJm4s9MVjN-@x2> (raw)
perf's build still accepts Python 3.6: Makefile.config only rejects
interpreters older than 3.6 and jevents.py keeps its own removesuffix()
shim for it, but two recently added constructs are evaluated when the
module or the function is defined and only work on newer interpreters.
PEP 585's list[...] became subscriptable in Python 3.9, so the module
level annotations in jevents.py make Kbuild die at import time:
TypeError: 'type' object is not subscriptable
make[3]: *** [pmu-events/Build:176: .../test-empty-pmu-events.c] Error 1
as seen on almalinux:8 with its python3.6.8, and the list[str]
parameters of util/setup.py's functions fail the same way when the
python binding is built.
ProcessPoolExecutor(initializer=, initargs=) was added in Python 3.7,
so generating pmu-events.c dies when the pool is created.
Use the typing generics that exist on every supported interpreter and
only pass initializer/initargs when the interpreter has them: on 3.6
the default fork start method already leaves the worker processes with
the parent's _arch_std_events, which is what _init_worker() sets up
for spawn semantics.
Tested with Python 3.6.15: make -C tools/perf completes, generating
pmu-events.c and the python binding.
Fixes: cda907c2c3f99 ("perf jevents: Add python type annotations")
Fixes: 1fa8d81be1eb ("perf python: Clean up and restructure setup.py")
Fixes: eaab2eb09dc2 ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/pmu-events/jevents.py | 24 +++++++++++++++---------
tools/perf/util/setup.py | 5 +++--
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 074daae5308b110b..bdc89ec197680c1b 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -8,19 +8,19 @@ import json
import metric
import os
import sys
-from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
+from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple)
import collections
# Global command line arguments.
_args = None
# List of regular event tables.
-_event_tables: list[str] = []
+_event_tables: List[str] = []
# List of event tables generated from "/sys" directories.
-_sys_event_tables: list[str] = []
+_sys_event_tables: List[str] = []
# List of regular metric tables.
-_metric_tables: list[str] = []
+_metric_tables: List[str] = []
# List of metric tables generated from "/sys" directories.
-_sys_metric_tables: list[str] = []
+_sys_metric_tables: List[str] = []
# Mapping between sys event table names and sys metric table names.
_sys_event_table_to_metric_table_mapping = {}
# Map from an event name to an architecture standard
@@ -28,11 +28,11 @@ _sys_event_table_to_metric_table_mapping = {}
# f'{_args.starting_dir}/{_args.arch}' directory.
_arch_std_events: Dict[str, "JsonEvent"] = {}
# Events to write out when the table is closed
-_pending_events: list["JsonEvent"] = []
+_pending_events: List["JsonEvent"] = []
# Name of events table to be written out
_pending_events_tblname: Optional[str] = None
# Metrics to write out when the table is closed
-_pending_metrics: list["JsonEvent"] = []
+_pending_metrics: List["JsonEvent"] = []
# Name of metrics table to be written out
_pending_metrics_tblname: Optional[str] = None
# Global BigCString shared by all structures.
@@ -1556,9 +1556,15 @@ struct pmu_table_entry {
preprocess_arch_std_files(arch_path)
ftw(arch_path, [], collect_json)
+ # ProcessPoolExecutor's initializer/initargs need Python 3.7, on 3.6 the
+ # fork start method already leaves the workers with the parent's
+ # _arch_std_events, i.e. what _init_worker would set up.
+ executor_kwargs: Dict[str, Any] = {}
+ if sys.version_info >= (3, 7):
+ executor_kwargs = dict(initializer=_init_worker,
+ initargs=(_arch_std_events,))
with concurrent.futures.ProcessPoolExecutor(max_workers=_parallel_worker_count(len(tasks)),
- initializer=_init_worker,
- initargs=(_arch_std_events,)) as executor:
+ **executor_kwargs) as executor:
for path, topic, events in executor.map(_parallel_read_json_events, tasks):
_json_cache[(path, topic)] = events
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 8380980ade4c486f..ad904b374ec6eaba 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -11,13 +11,14 @@ import shlex
import shutil
import subprocess
import sysconfig
+from typing import List
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools.command.install_lib import install_lib as _install_lib
-def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option: str) -> bool:
+def clang_has_option(cc: str, cc_args: List[str], src_feature_tests: str, option: str) -> bool:
"""Check if clang supports a specific option.
Args:
@@ -47,7 +48,7 @@ def clang_has_option(cc: str, cc_args: list[str], src_feature_tests: str, option
return not any(any(error in line for error in error_substrings) for line in cc_output)
-def filter_clang_options(cc: str, cc_args: list[str], src_feature_tests: str) -> None:
+def filter_clang_options(cc: str, cc_args: List[str], src_feature_tests: str) -> None:
"""Filter out unsupported clang options from sysconfig CFLAGS and OPT.
Args:
--
2.55.0
next reply other threads:[~2026-09-25 20:47 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 20:47 Arnaldo Carvalho de Melo [this message]
2026-09-25 20:54 ` [PATCH 1/1] perf: Fix Python 3.6 build breakage in jevents.py and util/setup.py sashiko-bot
2026-09-25 20:57 ` Ian Rogers
2026-09-25 21:14 ` Arnaldo Carvalho de Melo
2026-09-25 21:29 ` Ian Rogers
2026-09-25 21:52 ` Arnaldo Carvalho de Melo
2026-09-25 22:20 ` Ian Rogers
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=arbd4TJm4s9MVjN-@x2 \
--to=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=namhyung@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.