-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
PEP 799: A dedicated profilers module for organizing Python profiling tools #4504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
a864bba
PEP 795: A dedicated profilers module for organizing python profiling…
pablogsal 45e5a9d
Move to 799
AA-Turner 9bfd205
Apply suggestions from code review
pablogsal c056581
Several improvements
pablogsal 0b23605
Fix documents
pablogsal 74aaf71
Remove pep 795 file
pablogsal 7a360ce
Fix documents
pablogsal 038dc73
Fix documents
pablogsal 342787c
Fix documents
pablogsal 8d77f1d
Fix documents
pablogsal e3ba117
Update peps/pep-0799.rst
pablogsal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
PEP: 799 | ||
Title: A dedicated ``profilers`` package for organizing Python profiling tools | ||
Author: Pablo Galindo <pablogsal@python.org>, | ||
László Kiss Kollár <kiss.kollar.laszlo@gmail.com>, | ||
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. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.