pytest-codspeed 5.0.1__tar.gz → 5.0.2__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 (34) hide show
  1. {pytest_codspeed-5.0.1/src/pytest_codspeed.egg-info → pytest_codspeed-5.0.2}/PKG-INFO +1 -1
  2. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/pyproject.toml +1 -1
  3. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/__init__.py +2 -2
  4. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/__init__.py +48 -0
  5. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument_hooks_module.c +19 -0
  6. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2/src/pytest_codspeed.egg-info}/PKG-INFO +1 -1
  7. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/LICENSE +0 -0
  8. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/README.md +0 -0
  9. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/setup.cfg +0 -0
  10. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/setup.py +0 -0
  11. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/config.py +0 -0
  12. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/__init__.py +0 -0
  13. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/analysis.py +0 -0
  14. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/dist/core.c +0 -0
  15. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/includes/callgrind.h +0 -0
  16. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/includes/compat.h +0 -0
  17. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/includes/core.h +0 -0
  18. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/includes/valgrind.h +0 -0
  19. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/includes/zig.h +0 -0
  20. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/hooks/instrument-hooks/scripts/release.py +0 -0
  21. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/instruments/walltime.py +0 -0
  22. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/plugin.py +0 -0
  23. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/py.typed +0 -0
  24. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed/utils.py +0 -0
  25. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed.egg-info/SOURCES.txt +0 -0
  26. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed.egg-info/dependency_links.txt +0 -0
  27. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed.egg-info/entry_points.txt +0 -0
  28. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed.egg-info/requires.txt +0 -0
  29. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/src/pytest_codspeed.egg-info/top_level.txt +0 -0
  30. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/tests/test_format_time.py +0 -0
  31. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/tests/test_pytest_plugin.py +0 -0
  32. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/tests/test_pytest_plugin_cpu_instrumentation.py +0 -0
  33. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/tests/test_pytest_plugin_walltime.py +0 -0
  34. {pytest_codspeed-5.0.1 → pytest_codspeed-5.0.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-codspeed
3
- Version: 5.0.1
3
+ Version: 5.0.2
4
4
  Summary: Pytest plugin to create CodSpeed benchmarks
5
5
  Author-email: Arthur Pastel <arthur@codspeed.io>
6
6
  License: The MIT License (MIT)
@@ -82,7 +82,7 @@ version = { attr = "pytest_codspeed.__version__" }
82
82
 
83
83
 
84
84
  [tool.bumpver]
85
- current_version = "5.0.1"
85
+ current_version = "5.0.2"
86
86
  version_pattern = "MAJOR.MINOR.PATCH[-TAG[NUM]]"
87
87
  commit_message = "Release v{new_version} 🚀"
88
88
  tag_message = "Release v{new_version} 🚀"
@@ -1,6 +1,6 @@
1
- __version__ = "5.0.1"
1
+ __version__ = "5.0.2"
2
2
  # We also have the semver version since __version__ is not semver compliant
3
- __semver_version__ = "5.0.1"
3
+ __semver_version__ = "5.0.2"
4
4
 
5
5
  from .plugin import BenchmarkFixture
6
6
 
@@ -50,6 +50,10 @@ class InstrumentHooks:
50
50
  if SUPPORTS_PERF_TRAMPOLINE and not sys.is_stack_trampoline_active():
51
51
  sys.activate_stack_trampoline("perf") # type: ignore
52
52
 
53
+ # Ignore libpython and python executable frames in callgrind so they
54
+ # don't obfuscate the flamegraph.
55
+ callgrind_skip_python_runtime()
56
+
53
57
  def __del__(self):
54
58
  # Don't manually deinit - let the capsule destructor handle it
55
59
  pass
@@ -223,3 +227,47 @@ class InstrumentHooks:
223
227
  self.set_environment_list(section, "config", config_items)
224
228
 
225
229
  self.write_environment()
230
+
231
+
232
+ def callgrind_add_obj_skip(path: str) -> None:
233
+ """Tell callgrind to skip the given object file (and its realpath).
234
+
235
+ The actual Valgrind client-request trapdoor lives in the C extension; this
236
+ just resolves the realpath so callgrind's strcmp matches either form.
237
+ """
238
+ if not path or not os.path.exists(path):
239
+ return
240
+ try:
241
+ from . import dist_instrument_hooks # type: ignore
242
+ except ImportError:
243
+ return
244
+
245
+ dist_instrument_hooks.callgrind_add_obj_skip(path.encode())
246
+
247
+ # The dynamic loader maps the realpath (e.g. libpython3.12.so.1.0), and
248
+ # callgrind stores that in obj_node->name. Skip both so the exact strcmp
249
+ # matches regardless of which path callgrind sees.
250
+ real = os.path.realpath(path)
251
+ if real != path:
252
+ dist_instrument_hooks.callgrind_add_obj_skip(real.encode())
253
+
254
+
255
+ def callgrind_skip_python_runtime() -> None:
256
+ """Skip libpython and the python executable from callgrind measurement."""
257
+ ldlibrary = sysconfig.get_config_var("LDLIBRARY")
258
+ libdir = sysconfig.get_config_var("LIBDIR")
259
+ libpython = next(
260
+ (
261
+ p
262
+ for p in (
263
+ os.path.join(libdir, ldlibrary) if ldlibrary and libdir else None,
264
+ os.path.join(sys.prefix, "lib", ldlibrary) if ldlibrary else None,
265
+ )
266
+ if p and os.path.exists(p)
267
+ ),
268
+ None,
269
+ )
270
+ if libpython:
271
+ callgrind_add_obj_skip(libpython)
272
+
273
+ callgrind_add_obj_skip(sys.executable)
@@ -1,6 +1,12 @@
1
1
  #define PY_SSIZE_T_CLEAN
2
2
  #include <Python.h>
3
3
  #include "core.h"
4
+ #include "valgrind.h"
5
+
6
+ /* CodSpeed-specific Valgrind client request: tell callgrind to skip an
7
+ * object file by path. Not present in upstream callgrind.h. */
8
+ // TODO(COD-2654): Move this to instrument-hooks and just call it here
9
+ #define VG_USERREQ__ADD_OBJ_SKIP 0x43540006
4
10
 
5
11
  /* Capsule destructor for InstrumentHooks pointer */
6
12
  static void instrument_hooks_capsule_destructor(PyObject *capsule) {
@@ -242,6 +248,17 @@ static PyObject *py_instrument_hooks_write_environment(PyObject *self, PyObject
242
248
  return PyLong_FromLong(result);
243
249
  }
244
250
 
251
+ /* callgrind_add_obj_skip(path: bytes) -> None
252
+ * Outside Valgrind this expands to a nop, so it's safe on bare metal. */
253
+ static PyObject *py_callgrind_add_obj_skip(PyObject *self, PyObject *args) {
254
+ const char *path;
255
+ if (!PyArg_ParseTuple(args, "y", &path)) {
256
+ return NULL;
257
+ }
258
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_OBJ_SKIP, path, 0, 0, 0, 0);
259
+ Py_RETURN_NONE;
260
+ }
261
+
245
262
  /* Method definitions */
246
263
  static PyMethodDef InstrumentHooksMethods[] = {
247
264
  {"instrument_hooks_init", py_instrument_hooks_init, METH_NOARGS,
@@ -272,6 +289,8 @@ static PyMethodDef InstrumentHooksMethods[] = {
272
289
  "Register a list of values under a named section for environment collection."},
273
290
  {"instrument_hooks_write_environment", py_instrument_hooks_write_environment, METH_VARARGS,
274
291
  "Flush all registered environment sections to disk."},
292
+ {"callgrind_add_obj_skip", py_callgrind_add_obj_skip, METH_VARARGS,
293
+ "Tell callgrind to skip the given object file path."},
275
294
  {NULL, NULL, 0, NULL}
276
295
  };
277
296
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-codspeed
3
- Version: 5.0.1
3
+ Version: 5.0.2
4
4
  Summary: Pytest plugin to create CodSpeed benchmarks
5
5
  Author-email: Arthur Pastel <arthur@codspeed.io>
6
6
  License: The MIT License (MIT)
File without changes