pyperf 2.6.2__tar.gz → 2.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {pyperf-2.6.2/pyperf.egg-info → pyperf-2.7.0}/PKG-INFO +1 -1
  2. {pyperf-2.6.2 → pyperf-2.7.0}/doc/analyze.rst +12 -6
  3. {pyperf-2.6.2 → pyperf-2.7.0}/doc/api.rst +1 -1
  4. {pyperf-2.6.2 → pyperf-2.7.0}/doc/changelog.rst +22 -1
  5. {pyperf-2.6.2 → pyperf-2.7.0}/doc/conf.py +8 -9
  6. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples.rst +3 -2
  7. {pyperf-2.6.2 → pyperf-2.7.0}/doc/index.rst +1 -1
  8. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/__init__.py +1 -1
  9. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_bench.py +5 -5
  10. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_cli.py +2 -2
  11. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_collect_metadata.py +14 -8
  12. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_compare.py +1 -1
  13. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_cpu_utils.py +13 -5
  14. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_linux_memory.py +1 -1
  15. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_manager.py +1 -1
  16. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_metadata.py +1 -1
  17. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_psutil_memory.py +5 -1
  18. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_runner.py +2 -2
  19. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_system.py +18 -13
  20. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_utils.py +10 -5
  21. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_worker.py +1 -1
  22. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/__init__.py +1 -1
  23. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/replay.py +1 -1
  24. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_metadata.py +2 -2
  25. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_perf_cli.py +1 -1
  26. {pyperf-2.6.2 → pyperf-2.7.0/pyperf.egg-info}/PKG-INFO +1 -1
  27. {pyperf-2.6.2 → pyperf-2.7.0}/pyproject.toml +7 -0
  28. {pyperf-2.6.2 → pyperf-2.7.0}/tox.ini +3 -9
  29. {pyperf-2.6.2 → pyperf-2.7.0}/COPYING +0 -0
  30. {pyperf-2.6.2 → pyperf-2.7.0}/MANIFEST.in +0 -0
  31. {pyperf-2.6.2 → pyperf-2.7.0}/README.rst +0 -0
  32. {pyperf-2.6.2 → pyperf-2.7.0}/TODO.rst +0 -0
  33. {pyperf-2.6.2 → pyperf-2.7.0}/doc/Makefile +0 -0
  34. {pyperf-2.6.2 → pyperf-2.7.0}/doc/cli.rst +0 -0
  35. {pyperf-2.6.2 → pyperf-2.7.0}/doc/developer_guide.rst +0 -0
  36. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_async_func.py +0 -0
  37. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_async_func_with_loop_factory.py +0 -0
  38. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_command.py +0 -0
  39. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_func.py +0 -0
  40. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_time_func.py +0 -0
  41. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/bench_timeit.py +0 -0
  42. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/export_csv.py +0 -0
  43. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/hist_scipy.py +0 -0
  44. {pyperf-2.6.2 → pyperf-2.7.0}/doc/examples/plot.py +0 -0
  45. {pyperf-2.6.2 → pyperf-2.7.0}/doc/hist_scipy_telco.png +0 -0
  46. {pyperf-2.6.2 → pyperf-2.7.0}/doc/make.bat +0 -0
  47. {pyperf-2.6.2 → pyperf-2.7.0}/doc/outliers.json.gz +0 -0
  48. {pyperf-2.6.2 → pyperf-2.7.0}/doc/py2.json.gz +0 -0
  49. {pyperf-2.6.2 → pyperf-2.7.0}/doc/py3.json.gz +0 -0
  50. {pyperf-2.6.2 → pyperf-2.7.0}/doc/run_benchmark.rst +0 -0
  51. {pyperf-2.6.2 → pyperf-2.7.0}/doc/runner.rst +0 -0
  52. {pyperf-2.6.2 → pyperf-2.7.0}/doc/system.rst +0 -0
  53. {pyperf-2.6.2 → pyperf-2.7.0}/doc/timeit_strip.json.gz +0 -0
  54. {pyperf-2.6.2 → pyperf-2.7.0}/doc/user_guide.rst +0 -0
  55. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/__main__.py +0 -0
  56. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_command.py +0 -0
  57. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_formatter.py +0 -0
  58. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_process_time.py +0 -0
  59. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_timeit.py +0 -0
  60. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_timeit_cli.py +0 -0
  61. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/_win_memory.py +0 -0
  62. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_bench.py +0 -0
  63. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_py36.json +0 -0
  64. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_py36_tags.json +0 -0
  65. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_py37.json +0 -0
  66. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_py37_tags.json +0 -0
  67. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/mult_list_py38.json +0 -0
  68. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/telco.json +0 -0
  69. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_bench.py +0 -0
  70. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_cli.py +0 -0
  71. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_examples.py +0 -0
  72. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_misc.py +0 -0
  73. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_runner.py +0 -0
  74. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_system.py +0 -0
  75. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_timeit.py +0 -0
  76. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/test_utils.py +0 -0
  77. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf/tests/track_memory.json +0 -0
  78. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf.egg-info/SOURCES.txt +0 -0
  79. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf.egg-info/dependency_links.txt +0 -0
  80. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf.egg-info/entry_points.txt +0 -0
  81. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf.egg-info/requires.txt +0 -0
  82. {pyperf-2.6.2 → pyperf-2.7.0}/pyperf.egg-info/top_level.txt +0 -0
  83. {pyperf-2.6.2 → pyperf-2.7.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyperf
3
- Version: 2.6.2
3
+ Version: 2.7.0
4
4
  Summary: Python module to run and analyze benchmarks
5
5
  Author-email: Victor Stinner <vstinner@redhat.com>
6
6
  Maintainer-email: Dong-hee Na <donghee.na@python.org>
@@ -223,9 +223,15 @@ two-sample, two-tailed t-test
223
223
 
224
224
  Render a table using ``--table`` option::
225
225
 
226
- $ python3 -m pyperf compare_to py36.json py38.json --table
227
- +-----------+---------+------------------------------+
228
- | Benchmark | py36 | py38 |
229
- +===========+=========+==============================+
230
- | timeit | 4.70 us | 4.22 us: 1.11x faster (-10%) |
231
- +-----------+---------+------------------------------+
226
+ $ python3 -m pyperf compare_to mult_list_py36.json mult_list_py38.json --table
227
+ +----------------+----------------+-----------------------+
228
+ | Benchmark | mult_list_py36 | mult_list_py38 |
229
+ +================+================+=======================+
230
+ | [1,2]*1000 | 3.70 us | 3.18 us: 1.16x faster |
231
+ +----------------+----------------+-----------------------+
232
+ | [1,2,3]*1000 | 4.61 us | 4.17 us: 1.11x faster |
233
+ +----------------+----------------+-----------------------+
234
+ | Geometric mean | (ref) | 1.09x faster |
235
+ +----------------+----------------+-----------------------+
236
+
237
+ Benchmark hidden because not significant (1): [1]*1000
@@ -679,7 +679,7 @@ Benchmark:
679
679
  * ``inner_loops`` (``int >= 1``): number of inner-loops of the benchmark (``int``)
680
680
  * ``timer``: Implementation of ``time.perf_counter()``, and also resolution if
681
681
  available
682
- * ``tags``: (list of str, optional): A list of tags associated with the benchmark. If provided, the results output will be aggreggated by each tag.
682
+ * ``tags``: (list of str, optional): A list of tags associated with the benchmark. If provided, the results output will be aggregated by each tag.
683
683
 
684
684
  Python metadata:
685
685
 
@@ -1,6 +1,27 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ Version 2.7.0 (2024-05-18)
5
+ ---------------------------
6
+
7
+ * Fix logic in MSR availability test.
8
+ Patch by Mike Droettboom.
9
+ * Disable tuning TurboBoost setting on non-Intel device.
10
+ Patch by Mike Droettboom.
11
+ * Include CONFIG_ARGS in Metadata.
12
+ Patch by Jeff Glass.
13
+ * Support environment variables PYTHON_GIL / PYTHON_CPU_COUNT.
14
+ Patch by Donghee Na.
15
+
16
+ Version 2.6.3 (2024-03-05)
17
+ ---------------------------
18
+
19
+ * Support Free-threading CPython (PEP-703) by disabling psutil related features.
20
+ Relevant issue: https://github.com/python/cpython/issues/116024.
21
+ Patch by Donghee Na.
22
+ * Fix mem_max_rss measurement on macOS.
23
+ Patch by Mike Droettboom.
24
+
4
25
  Version 2.6.2 (2023-11-02)
5
26
  ---------------------------
6
27
 
@@ -79,7 +100,7 @@ Version 2.1.0 (2021-01-14)
79
100
  * The :ref:`compare_to command <compare_to_cmd>` no longer displays
80
101
  percentages: display less numbers to make the output easier to read. Also,
81
102
  percentage were almost the same values than the xxx faster or xxx slower
82
- values, but rounded differenly which introduced confusion.
103
+ values, but rounded differently which introduced confusion.
83
104
  * Project moved to https://github.com/psf/pyperf/
84
105
  * system command now only emits a warning rather than failing with a hard error
85
106
  if it fails to get or set the frequency of a CPU.
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  #
3
2
  # pyperf documentation build configuration file, created by
4
3
  # sphinx-quickstart on Wed Jun 1 15:28:03 2016.
@@ -42,16 +41,16 @@ source_suffix = '.rst'
42
41
  master_doc = 'index'
43
42
 
44
43
  # General information about the project.
45
- project = u'pyperf'
46
- copyright = u'2016, Victor Stinner'
47
- author = u'Victor Stinner'
44
+ project = 'pyperf'
45
+ copyright = '2016, Victor Stinner'
46
+ author = 'Victor Stinner'
48
47
 
49
48
  # The version info for the project you're documenting, acts as replacement for
50
49
  # |version| and |release|, also used in various other places throughout the
51
50
  # built documents.
52
51
  #
53
52
  # The short X.Y version.
54
- version = release = '2.6.2'
53
+ version = release = '2.7.0'
55
54
 
56
55
  # The language for content autogenerated by Sphinx. Refer to documentation
57
56
  # for a list of supported languages.
@@ -216,8 +215,8 @@ latex_elements = {
216
215
  # (source start file, target name, title,
217
216
  # author, documentclass [howto, manual, or own class]).
218
217
  latex_documents = [
219
- (master_doc, 'pyperf.tex', u'pyperf Documentation',
220
- u'Victor Stinner', 'manual'),
218
+ (master_doc, 'pyperf.tex', 'pyperf Documentation',
219
+ 'Victor Stinner', 'manual'),
221
220
  ]
222
221
 
223
222
  # The name of an image file (relative to this directory) to place at the top of
@@ -246,7 +245,7 @@ latex_documents = [
246
245
  # One entry per manual page. List of tuples
247
246
  # (source start file, name, description, authors, manual section).
248
247
  man_pages = [
249
- (master_doc, 'pyperf', u'pyperf Documentation',
248
+ (master_doc, 'pyperf', 'pyperf Documentation',
250
249
  [author], 1)
251
250
  ]
252
251
 
@@ -260,7 +259,7 @@ man_pages = [
260
259
  # (source start file, target name, title, author,
261
260
  # dir menu entry, description, category)
262
261
  texinfo_documents = [
263
- (master_doc, 'pyperf', u'pyperf Documentation',
262
+ (master_doc, 'pyperf', 'pyperf Documentation',
264
263
  author, 'pyperf', 'One line description of project.',
265
264
  'Miscellaneous'),
266
265
  ]
@@ -31,8 +31,9 @@ bench_async_func() method
31
31
  timeit() method
32
32
  ---------------
33
33
 
34
- Benchmark using the :meth:`Runner.timeit` method to performance of sorting a
35
- sorted list of 1000 numbers using a ``key`` function (which does nothing):
34
+ Benchmark using the :meth:`Runner.timeit` method to measure the performance of
35
+ sorting a sorted list of 1000 numbers using a ``key`` function (which does
36
+ nothing):
36
37
 
37
38
  .. literalinclude:: examples/bench_timeit.py
38
39
 
@@ -4,7 +4,7 @@ Python pyperf module
4
4
 
5
5
  The Python ``pyperf`` module is a toolkit to write, run and analyze benchmarks.
6
6
 
7
- Documenation:
7
+ Documentation:
8
8
 
9
9
  .. toctree::
10
10
  :maxdepth: 2
@@ -1,6 +1,6 @@
1
1
  from time import perf_counter
2
2
 
3
- VERSION = (2, 6, 2)
3
+ VERSION = (2, 7, 0)
4
4
  __version__ = '.'.join(map(str, VERSION))
5
5
 
6
6
  # Export pyperf.perf_counter for backward compatibility with pyperf 1.7
@@ -86,7 +86,7 @@ def _cached_attr(func):
86
86
  return method
87
87
 
88
88
 
89
- class Run(object):
89
+ class Run:
90
90
  # Run is immutable, so it can be shared/exchanged between two benchmarks
91
91
 
92
92
  __slots__ = ('_warmups', '_values', '_metadata')
@@ -319,7 +319,7 @@ class Run(object):
319
319
  return self._replace(metadata=metadata2)
320
320
 
321
321
 
322
- class Benchmark(object):
322
+ class Benchmark:
323
323
  def __init__(self, runs):
324
324
  self._runs = [] # list of Run objects
325
325
  self._clear_runs_cache()
@@ -627,7 +627,7 @@ class Benchmark(object):
627
627
  self._replace_runs(new_runs)
628
628
 
629
629
 
630
- class BenchmarkSuite(object):
630
+ class BenchmarkSuite:
631
631
  def __init__(self, benchmarks, filename=None):
632
632
  if not benchmarks:
633
633
  raise ValueError("benchmarks must be a non-empty "
@@ -727,7 +727,7 @@ class BenchmarkSuite(object):
727
727
  if isinstance(filename, bytes):
728
728
  suffix = b'.gz'
729
729
  else:
730
- suffix = u'.gz'
730
+ suffix = '.gz'
731
731
 
732
732
  if filename.endswith(suffix):
733
733
  # Use lazy import to limit imports on 'import pyperf'
@@ -770,7 +770,7 @@ class BenchmarkSuite(object):
770
770
  if isinstance(filename, bytes):
771
771
  suffix = b'.gz'
772
772
  else:
773
- suffix = u'.gz'
773
+ suffix = '.gz'
774
774
 
775
775
  if not replace and os.path.exists(filename):
776
776
  raise OSError(errno.EEXIST, "File already exists")
@@ -604,7 +604,7 @@ def catch_broken_pipe_error(file=None):
604
604
  # was closed by the consumer
605
605
  for file in files:
606
606
  file.flush()
607
- except IOError as exc:
607
+ except OSError as exc:
608
608
  if exc.errno != errno.EPIPE:
609
609
  raise
610
610
  # got a broken pipe error: ignore it
@@ -615,5 +615,5 @@ def catch_broken_pipe_error(file=None):
615
615
  for file in files:
616
616
  try:
617
617
  file.close()
618
- except IOError:
618
+ except OSError:
619
619
  pass
@@ -11,8 +11,11 @@ except ImportError:
11
11
  resource = None
12
12
 
13
13
  try:
14
- # Optional dependency
15
- import psutil
14
+ from pyperf._utils import USE_PSUTIL
15
+ if not USE_PSUTIL:
16
+ psutil = None
17
+ else:
18
+ import psutil
16
19
  except ImportError:
17
20
  psutil = None
18
21
 
@@ -23,6 +26,7 @@ from pyperf._cpu_utils import (format_cpu_list,
23
26
  get_logical_cpu_count, format_cpu_infos,
24
27
  set_cpu_affinity)
25
28
  from pyperf._formatter import format_timedelta, format_datetime
29
+ from pyperf._process_time import get_max_rss
26
30
  from pyperf._utils import (MS_WINDOWS,
27
31
  open_text, read_first_line, sysfs_path, proc_path)
28
32
  if MS_WINDOWS:
@@ -107,6 +111,11 @@ def collect_python_metadata(metadata):
107
111
  cflags = normalize_text(cflags)
108
112
  metadata['python_cflags'] = cflags
109
113
 
114
+ config_args = sysconfig.get_config_var('CONFIG_ARGS')
115
+ if config_args:
116
+ config_args = normalize_text(config_args)
117
+ metadata['python_config_args'] = config_args
118
+
110
119
  # GC disabled?
111
120
  try:
112
121
  import gc
@@ -127,7 +136,7 @@ def read_proc(path):
127
136
  with open_text(path) as fp:
128
137
  for line in fp:
129
138
  yield line.rstrip()
130
- except (OSError, IOError):
139
+ except OSError:
131
140
  return
132
141
 
133
142
 
@@ -199,10 +208,7 @@ def collect_system_metadata(metadata):
199
208
 
200
209
  def collect_memory_metadata(metadata):
201
210
  if resource is not None:
202
- usage = resource.getrusage(resource.RUSAGE_SELF)
203
- max_rss = usage.ru_maxrss
204
- if max_rss:
205
- metadata['mem_max_rss'] = max_rss * 1024
211
+ metadata["mem_max_rss"] = get_max_rss()
206
212
 
207
213
  # Note: Don't collect VmPeak of /proc/self/status on Linux because it is
208
214
  # not accurate. See pyperf._linux_memory for more accurate memory metrics.
@@ -326,7 +332,7 @@ def get_cpu_temperature(path, cpu_temp):
326
332
 
327
333
  try:
328
334
  temp_label = read_first_line(template % 'label', error=True)
329
- except IOError:
335
+ except OSError:
330
336
  break
331
337
 
332
338
  temp_input = read_first_line(template % 'input', error=True)
@@ -53,7 +53,7 @@ def get_tags_for_result(result):
53
53
  return result.ref.benchmark.get_metadata().get("tags", [])
54
54
 
55
55
 
56
- class CompareResult(object):
56
+ class CompareResult:
57
57
  def __init__(self, ref, changed, min_speed=None):
58
58
  # CompareData object
59
59
  self.ref = ref
@@ -2,11 +2,13 @@ import collections
2
2
  import os
3
3
  import re
4
4
 
5
- from pyperf._utils import sysfs_path, proc_path, read_first_line
5
+ from pyperf._utils import sysfs_path, proc_path, read_first_line, USE_PSUTIL
6
6
 
7
7
  try:
8
- # Optional dependency
9
- import psutil
8
+ if not USE_PSUTIL:
9
+ psutil = None
10
+ else:
11
+ import psutil
10
12
  except ImportError:
11
13
  psutil = None
12
14
 
@@ -152,7 +154,10 @@ def set_cpu_affinity(cpus):
152
154
  return True
153
155
 
154
156
  try:
155
- import psutil
157
+ if not USE_PSUTIL:
158
+ return
159
+ else:
160
+ import psutil
156
161
  except ImportError:
157
162
  return
158
163
 
@@ -166,7 +171,10 @@ def set_cpu_affinity(cpus):
166
171
 
167
172
  def set_highest_priority():
168
173
  try:
169
- import psutil
174
+ if not USE_PSUTIL:
175
+ return
176
+ else:
177
+ import psutil
170
178
  except ImportError:
171
179
  return
172
180
 
@@ -54,7 +54,7 @@ def check_tracking_memory():
54
54
  mem_thread = PeakMemoryUsageThread()
55
55
  try:
56
56
  mem_thread.get()
57
- except IOError as exc:
57
+ except OSError as exc:
58
58
  path = proc_path("self/smaps")
59
59
  return "unable to read %s: %s" % (path, exc)
60
60
 
@@ -12,7 +12,7 @@ from pyperf._utils import MS_WINDOWS, create_environ, create_pipe, popen_killer
12
12
  MAX_CALIBRATION = 5
13
13
 
14
14
 
15
- class Manager(object):
15
+ class Manager:
16
16
  """
17
17
  Manager process which spawns worker processes to:
18
18
  - calibrate warmups
@@ -137,7 +137,7 @@ def format_metadata(name, value):
137
137
  return info.formatter(value)
138
138
 
139
139
 
140
- class Metadata(object):
140
+ class Metadata:
141
141
  def __init__(self, name, value):
142
142
  self._name = name
143
143
  self._value = value
@@ -1,6 +1,10 @@
1
1
  import os
2
2
  try:
3
- import psutil
3
+ from pyperf._utils import USE_PSUTIL
4
+ if not USE_PSUTIL:
5
+ raise ImportError
6
+ else:
7
+ import psutil
4
8
  except ImportError:
5
9
  raise ImportError('psutil is not installed')
6
10
  import threading
@@ -69,7 +69,7 @@ class CLIError(Exception):
69
69
  class Runner:
70
70
  _created = set()
71
71
 
72
- # Default parameters are chosen to have approximatively a run of 0.5 second
72
+ # Default parameters are chosen to have approximately a run of 0.5 second
73
73
  # and so a total duration of 5 seconds by default
74
74
  def __init__(self, values=None, processes=None,
75
75
  loops=0, min_time=0.1, metadata=None,
@@ -85,7 +85,7 @@ class Runner:
85
85
  pass
86
86
 
87
87
  # Watchdog: ensure that only once instance of Runner (or a Runner
88
- # subclass) is created per process to prevent bad suprises
88
+ # subclass) is created per process to prevent bad surprises
89
89
  cls = self.__class__
90
90
  key = id(cls)
91
91
  if key in cls._created:
@@ -1,5 +1,6 @@
1
1
  import errno
2
2
  import os.path
3
+ import platform
3
4
  import re
4
5
  import struct
5
6
  import subprocess
@@ -74,7 +75,7 @@ def use_intel_pstate():
74
75
  return (scaling_driver == 'intel_pstate')
75
76
 
76
77
 
77
- class Operation(object):
78
+ class Operation:
78
79
  @staticmethod
79
80
  def available():
80
81
  return True
@@ -107,7 +108,7 @@ class Operation(object):
107
108
  def read_first_line(self, path):
108
109
  try:
109
110
  return read_first_line(path, error=True)
110
- except IOError as exc:
111
+ except OSError as exc:
111
112
  self.check_permission_error(exc)
112
113
  return ''
113
114
 
@@ -125,7 +126,11 @@ class TurboBoostMSR(Operation):
125
126
 
126
127
  @staticmethod
127
128
  def available():
128
- return (OS_LINUX and not use_intel_pstate())
129
+ return (
130
+ OS_LINUX and
131
+ not use_intel_pstate() and
132
+ platform.machine() in ('x86', 'x86_64', 'amd64')
133
+ )
129
134
 
130
135
  def __init__(self, system):
131
136
  Operation.__init__(self, 'Turbo Boost (MSR)', system)
@@ -219,7 +224,7 @@ class TurboBoostMSR(Operation):
219
224
  os.write(fd, data)
220
225
  finally:
221
226
  os.close(fd)
222
- except IOError as exc:
227
+ except OSError as exc:
223
228
  self.check_permission_error(exc)
224
229
  self.error("Failed to write %#x into MSR %#x using %s: %s"
225
230
  % (value, reg_num, path, exc))
@@ -308,7 +313,7 @@ class TurboBoostIntelPstate(Operation):
308
313
  content = '0' if enable else '1'
309
314
  try:
310
315
  write_text(self.path, content)
311
- except IOError as exc:
316
+ except OSError as exc:
312
317
  # don't log a permission error if the user is root: permission
313
318
  # error as root means that Turbo Boost is disabled in the BIOS
314
319
  if not is_root():
@@ -376,7 +381,7 @@ class CPUGovernorIntelPstate(Operation):
376
381
  return
377
382
  try:
378
383
  write_text(self.path, new_governor)
379
- except IOError as exc:
384
+ except OSError as exc:
380
385
  self.error("Failed to set the CPU scaling governor: %s" % exc)
381
386
  else:
382
387
  self.log_action("CPU scaling governor set to %s" % new_governor)
@@ -384,7 +389,7 @@ class CPUGovernorIntelPstate(Operation):
384
389
 
385
390
  class LinuxScheduler(Operation):
386
391
  """
387
- Check isolcpus=cpus and rcu_nocbs=cpus paramaters of the Linux kernel
392
+ Check isolcpus=cpus and rcu_nocbs=cpus parameters of the Linux kernel
388
393
  command line.
389
394
  """
390
395
 
@@ -495,7 +500,7 @@ class ASLR(Operation):
495
500
 
496
501
  try:
497
502
  write_text(self.path, new_value)
498
- except IOError as exc:
503
+ except OSError as exc:
499
504
  self.check_permission_error(exc)
500
505
  self.error("Failed to write into %s: %s" % (self.path, exc))
501
506
  else:
@@ -552,7 +557,7 @@ class CPUFrequency(Operation):
552
557
  try:
553
558
  with open(filename, "rb") as fp:
554
559
  return fp.readline()
555
- except IOError as exc:
560
+ except OSError as exc:
556
561
  self.check_permission_error(exc)
557
562
  return None
558
563
 
@@ -579,7 +584,7 @@ class CPUFrequency(Operation):
579
584
  filename = os.path.join(cpu_path, "scaling_min_freq")
580
585
  try:
581
586
  return self.write_freq(filename, freq)
582
- except IOError as exc:
587
+ except OSError as exc:
583
588
  self.check_permission_error(exc)
584
589
  self.error("Unable to write scaling_max_freq of CPU %s: %s"
585
590
  % (cpu, exc))
@@ -768,7 +773,7 @@ class IRQAffinity(Operation):
768
773
  mask = format_cpus_as_mask(new_affinity)
769
774
  try:
770
775
  write_text(self.default_affinity_path, mask)
771
- except IOError as exc:
776
+ except OSError as exc:
772
777
  self.check_permission_error(exc)
773
778
  self.error("Failed to write %r into %s: %s"
774
779
  % (mask, self.default_affinity_path, exc))
@@ -782,7 +787,7 @@ class IRQAffinity(Operation):
782
787
  try:
783
788
  write_text(path, mask)
784
789
  return True
785
- except IOError as exc:
790
+ except OSError as exc:
786
791
  self.check_permission_error(exc)
787
792
  # EIO means that the IRQ doesn't support SMP affinity:
788
793
  # ignore the error
@@ -937,7 +942,7 @@ class PerfEvent(Operation):
937
942
 
938
943
  try:
939
944
  write_text(self.path, str(new_rate))
940
- except IOError as exc:
945
+ except OSError as exc:
941
946
  self.check_permission_error(exc)
942
947
  self.error("Failed to write into %s: %s" % (self.path, exc))
943
948
  else:
@@ -3,10 +3,14 @@ import math
3
3
  import os
4
4
  import statistics
5
5
  import sys
6
+ import sysconfig
6
7
  from shlex import quote as shell_quote # noqa
7
8
  from shutil import which
8
9
 
9
-
10
+ # Currently there is a packaging issue for PEP-703,
11
+ # Until then psutil is disabled as a workaround.
12
+ # See: https://github.com/python/cpython/issues/116024
13
+ USE_PSUTIL = not bool(sysconfig.get_config_var('Py_GIL_DISABLED'))
10
14
  MS_WINDOWS = (sys.platform == 'win32')
11
15
  MAC_OS = (sys.platform == 'darwin')
12
16
 
@@ -151,7 +155,7 @@ def read_first_line(path, error=False):
151
155
  with open_text(path) as fp:
152
156
  line = fp.readline()
153
157
  return line.rstrip()
154
- except IOError:
158
+ except OSError:
155
159
  if error:
156
160
  raise
157
161
  else:
@@ -262,8 +266,9 @@ def create_environ(inherit_environ, locale, copy_all):
262
266
  if copy_all:
263
267
  return os.environ
264
268
  env = {}
265
-
266
- copy_env = ["PATH", "PYTHONPATH", "HOME", "TEMP", "COMSPEC", "SystemRoot", "SystemDrive"]
269
+ copy_env = ["PATH", "HOME", "TEMP", "COMSPEC", "SystemRoot", "SystemDrive",
270
+ # Python specific variables
271
+ "PYTHONPATH", "PYTHON_CPU_COUNT", "PYTHON_GIL"]
267
272
  if locale:
268
273
  copy_env.extend(('LANG', 'LC_ADDRESS', 'LC_ALL', 'LC_COLLATE',
269
274
  'LC_CTYPE', 'LC_IDENTIFICATION', 'LC_MEASUREMENT',
@@ -278,7 +283,7 @@ def create_environ(inherit_environ, locale, copy_all):
278
283
  return env
279
284
 
280
285
 
281
- class _Pipe(object):
286
+ class _Pipe:
282
287
  _OPEN_MODE = "r"
283
288
 
284
289
  def __init__(self, fd):
@@ -288,7 +288,7 @@ class WorkerTask:
288
288
  else:
289
289
  self.compute_warmups_values()
290
290
 
291
- # collect metatadata
291
+ # collect metadata
292
292
  metadata2 = self.collect_metadata()
293
293
  metadata2.update(self.metadata)
294
294
  self.metadata = metadata2
@@ -55,7 +55,7 @@ def temporary_directory():
55
55
  def benchmark_as_json(benchmark, compact=True):
56
56
  with temporary_file() as tmp_name:
57
57
  benchmark.dump(tmp_name, compact=compact)
58
- with io.open(tmp_name, 'r', encoding='utf-8') as tmp:
58
+ with open(tmp_name, 'r', encoding='utf-8') as tmp:
59
59
  return tmp.read()
60
60
 
61
61
 
@@ -14,7 +14,7 @@ def get_raw_values(filename, run_id):
14
14
  return (run, raw_values)
15
15
 
16
16
 
17
- class Replay(object):
17
+ class Replay:
18
18
  def __init__(self, runner, filename):
19
19
  self.runner = runner
20
20
  self.args = runner.args
@@ -159,7 +159,7 @@ class CpuFunctionsTests(unittest.TestCase):
159
159
  elif filename.startswith('/sys/devices/system/cpu/nohz_full'):
160
160
  data = nohz_full
161
161
  elif filename.startswith('/sys/devices/system/cpu/cpu2'):
162
- raise IOError
162
+ raise OSError
163
163
  elif filename == '/sys/devices/system/cpu/cpuidle/current_driver':
164
164
  data = 'IDLE_DRV\n'
165
165
  else:
@@ -194,7 +194,7 @@ class CpuFunctionsTests(unittest.TestCase):
194
194
  elif filename == '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor':
195
195
  data = 'GOVERNOR\n'
196
196
  elif filename.startswith('/sys/devices/system/cpu/cpu2'):
197
- raise IOError
197
+ raise OSError
198
198
  else:
199
199
  raise ValueError("unexpect open: %r" % filename)
200
200
  return io.StringIO(data)
@@ -11,7 +11,7 @@ TESTDIR = os.path.dirname(__file__)
11
11
  TELCO = os.path.join(TESTDIR, 'telco.json')
12
12
 
13
13
 
14
- class BaseTestCase(object):
14
+ class BaseTestCase:
15
15
  maxDiff = 100 * 80
16
16
 
17
17
  def create_bench(self, values, metadata=None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyperf
3
- Version: 2.6.2
3
+ Version: 2.7.0
4
4
  Summary: Python module to run and analyze benchmarks
5
5
  Author-email: Victor Stinner <vstinner@redhat.com>
6
6
  Maintainer-email: Dong-hee Na <donghee.na@python.org>
@@ -61,3 +61,10 @@ packages = ["pyperf", "pyperf.tests"]
61
61
 
62
62
  [tool.setuptools.dynamic]
63
63
  version = {attr = "pyperf.__version__"}
64
+
65
+ [tool.ruff.lint]
66
+ extend-select = ["C90", "UP"]
67
+ extend-ignore = ["UP015", "UP031"]
68
+
69
+ [tool.ruff.lint.mccabe]
70
+ max-complexity = 31
@@ -13,18 +13,12 @@ basepython = python3
13
13
  [testenv:doc]
14
14
  basepython = python3
15
15
  deps = sphinx
16
- whitelist_externals = make
16
+ allowlist_externals = make
17
17
  commands=
18
18
  make -C doc html
19
19
 
20
20
  [testenv:pep8]
21
21
  basepython = python3
22
- deps = flake8
22
+ deps = ruff
23
23
  commands =
24
- flake8 pyperf setup.py doc/examples/
25
-
26
- [flake8]
27
- # E501 line too long (88 > 79 characters)
28
- # F812 list comprehension redefines 'loops' from line 56
29
- # W503 line break before binary operator
30
- ignore = E501,F812,W503
24
+ ruff check
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes