diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b6673bf281a..89404412f8e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -674,6 +674,7 @@ peps/pep-0792.rst @dstufft peps/pep-0793.rst @encukou peps/pep-0794.rst @brettcannon peps/pep-0798.rst @JelleZijlstra +peps/pep-0799.rst @pablogsal # ... peps/pep-0800.rst @JelleZijlstra peps/pep-0801.rst @warsaw diff --git a/peps/pep-0799.rst b/peps/pep-0799.rst new file mode 100644 index 00000000000..5fef874dac8 --- /dev/null +++ b/peps/pep-0799.rst @@ -0,0 +1,148 @@ +PEP: 799 +Title: A dedicated ``profilers`` package for organizing Python profiling tools +Author: Pablo Galindo , + László Kiss Kollár , +Discussions-To: Pending +Status: Draft +Type: Standards Track +Created: 21-Jul-2025 +Python-Version: 3.15 +Post-History: + +Abstract +======== + +This PEP proposes the creation of a new standard library module named +:mod:`!profilers` to organize Python's built-in profiling tools under a single, +coherent namespace. + +This PEP also proposes the deprecation of the :mod:`profile` module, a legacy +pure-Python tracing profiler. + +Motivation +========== + +Python currently ships with two tracing profilers: ``profile`` and ``cProfile``. The +``profile`` module is implemented in pure Python and is largely educational or useful for +subclassing, but too slow for realistic use. ``cProfile``, by contrast, is implemented +in C and more suitable for practical profiling scenarios, although it is not a drop-in +replacement for ``profile`` due to some behavioral differences. + +Both of these are tracing profilers, meaning they instrument every function call and return. +This methodology introduces significant runtime overhead and can disable certain interpreter +optimizations, such as those introduced by :pep:`659`. Moreover, ``cProfile`` only observes the +main thread, making it less useful in modern concurrent Python programs. Confusingly, the naming +of these modules implies that ``profile`` is canonical, when in fact it is largely obsolete. + +With Python 3.15, a new sampling profiler was introduced under ``profile.sample``. Known as +**tachyon**, this tool uses statistical sampling to infer performance characteristics, which +introduces much lower overhead and works better with the modern Python interpreter. It also supports +multiple threads, async functions, and attaching to running processes. Despite these strengths, +the placement of tachyon under ``profile.sample`` is misleading and obscures its importance. + +Currently, the organization of profiling tools lacks a consistent, discoverable structure. +The proposed reorganization is meant to guide users more effectively toward appropriate tools, +clarify methodological distinctions between profilers, and lay the groundwork for future extensions. + +Rationale +========= + +This reorganization addresses several long-standing issues with Python’s profiling tools. + +First, it improves **discoverability** by collecting all built-in profilers +under a single, clearly named namespace. Currently, profiling tools are +scattered across modules with inconsistent naming and unclear relationships. By +introducing the ``profilers`` module, users will have a well-defined and +intuitive location to explore and access profiling functionality. + +Second, the proposal enhances **clarity** by naming the submodules according to +their underlying methodology -- ``profilers.tracing`` for deterministic tracing +profilers and ``profilers.sampling`` for statistical sampling profilers. This +explicit categorization makes it easier to understand the behavior and +limitations of each tool and aligns the API with the mental model users are +encouraged to adopt. + +Third, it provides **guidance** to developers by making the recommended tools +easier to find and use. The current structure can mislead users into relying on +outdated or less performant modules like ``profile``, simply because of naming +precedence. With the ``profilers`` namespace and its clearer semantics, users +are more likely to choose the appropriate profiler for their specific use case, +whether it involves low-overhead sampling or detailed tracing. + +Finally, this structure promotes **extensibility**. By consolidating profiling +tools under a unified namespace, it becomes straightforward to introduce future +profiling capabilities -- such as memory profilers, I/O profilers, or hybrid +tools -- without overloading unrelated modules or adding redundant top-level names. +The ``profilers`` module provides a natural home for this. + +Specification +============= + +New Module Structure +-------------------- + +This PEP introduces a new ``profilers`` module containing: + +- ``profilers.tracing``: an alias for ``cProfile``, providing deterministic function-call tracing. +- ``profilers.sampling``: an alias for ``profilers.tachyon``, improving visibility and semantic clarity. + +Additionally the **code** for the ``tachyon`` profiler will be also relocated to +the module as ``profilers.tachyon``. + +Deprecation of ``profile`` +-------------------------- + +The ``profile`` module will be deprecated starting in Python 3.15. + +- In Python 3.15: importing ``profile`` emits a ``DeprecationWarning``. +- In Python 3.16: all uses of ``profile`` emit a ``DeprecationWarning``. +- In Python 3.17: the module will be removed from the standard library. + +From Python 3.15, :mod:`!profilers.tracing` will be preferred to :mod:`!cProfile` & :mod:`!profile`. + +The code that as the time of writing this is in :mod:`!profile.sampling` +module no longer exist and will only exist in the :mod:`!profilers` package. + +Documentation +============= + +The Python documentation will use the new :mod:`!profilers` module as the canonical +entry point for profiling functionality. It will also describe the distinction between +tracing and sampling profilers, and include guidance on when each type is most appropriate. + +Documentation for ``cProfile`` and ``profile.sample`` will remain available but will link to +the new ``profilers`` equivalents. + +Backwards Compatibility +======================= + +The only backwards incompatible aspect of this PEP is the future removal of the ``profile`` module +but this will be made following the :pep:`387` procedure. + +Security Implications +===================== + +None. + +Rejected Alternatives +===================== + +Renaming ``cProfile`` +--------------------- + +Renaming ``cProfile`` to ``profile.tracing`` was considered, but this change would impact a +large amount of existing code. Maintaining the original name while aliasing it under +``profilers.tracing`` strikes a balance between compatibility and clarity. + +Top-Level ``tachyon`` Module +---------------------------- + +Introducing ``import tachyon`` as a new top-level module was rejected. Grouping tachyon under +``profilers`` helps establish a logical structure and prevents proliferation of top-level modules +and also minimizes the usage of global namespace as requested by the Python Steering council + +Copyright +========= + +This document is placed in the public domain or under the CC0-1.0-Universal +license, whichever is more permissive.