Memray
Co-creator, with Matt Wozniski at Bloomberg
A memory profiler for Python. It tracks every allocation in Python code, in native extension modules and in the interpreter.
memray run my_script.py pablo.occupation: works on the CPython parser and error messages; writes profilers and debuggers for Python; co-hosts the core.py podcast.
SCHWARZSCHILD · i --.-° · φ ---.-° · ------ RAYS/FRAME · -- FPS
Point at the image to trace one ray. Click to launch rays from that point.
Traceback (most recent call last):
File "~/granada/phd/geodesics.py", line 2014, in regularize
orbit = mcgehee(spherically_symmetric_spacetime)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/cpython/Doc/howto/logging-cookbook.rst", line 2017, in first_pr
fix(ZeroMQSocketHandler) # bpo-31294
^^^^^^^^^^^^^^^^^^^
File "~/cpython/Parser/parser.c", line 2020, in replace_the_parser
parser = PEG(grammar) # PEP 617
^^^^^^^^^^^^
File "~/cpython/Python/pythonrun.c", line 2021, in print_exception
print('Did you mean: ...?')
^^^^^^^^^^^^^^^^^^^^
File "~/cpython/Python/sysmodule.c", line 2025, in sys_remote_exec
sys.remote_exec(pid, script) # PEP 768
^^^
Most days I work on the Python interpreter. I work on the parts you see when something goes wrong: the parser, the error messages and the tracebacks. I also work on the code that lets debuggers and profilers look inside a running process.
I came to software from theoretical physics. My PhD was on general relativity and black holes. I learned Python to glue together C simulation code. Later, Python itself became more interesting to me than the simulations.
I have been a CPython core developer since 2018. I have been on the Python Steering Council every term since 2021. I was the release manager for Python 3.10 and 3.11.
I work on the Python team at Hudson River Trading, in London.
I became a CPython core developer in June 2018. This section lists my roles, my PEPs and my changes to each release since 3.8.
Counts from GitHub, queried 24 September 2026.
One square is 20 pull requests, by year opened. 2026 is not complete.
My name is on 15 PEPs. Eleven are final. Two are the release schedules for 3.10 and 3.11. One is rejected and one is withdrawn.
PEP 617 3.9
Guido, Lysandros and I replaced the old LL(1) parser with a PEG parser.
PEP 657 3.11
Tracebacks mark the exact expression that failed with ^^^^^.
PEP 701 3.12
f-strings are part of the grammar. You can reuse quotes inside them.
PEP 768 3.14
Debuggers can attach to a running process. pdb -p PID uses it.
PEP 799 3.15
profiling package for organizing Python profiling tools A new profiling package. It includes Tachyon, a sampling profiler.
PEP 810 3.15
lazy import json loads the module only when you first use it.
except and except* expressions without parentheses Final These are the changes I wrote or co-wrote in each release. Each one links to What's New and to the issue.
Tachyon (profiling.sampling) is a high-frequency sampling profiler. It can attach to running processes. cProfile moves to profiling.tracing. László Kiss Kollár and I built Tachyon.
The new lazy import statement. Dino Viehland and I implemented it.
CPython builds with frame pointers by default. Native profilers and debuggers can then walk through Python frames.
Native debuggers can unwind through JIT-compiled frames. Before, they stopped at the generated code. Diego Russo and I did this work.
sys.remote_exec() and python -m pdb -p PID let you attach to a live Python process and debug it without restarting.
Run them against a running process to see which tasks wait on which. I also added asyncio.capture_call_graph() and print_call_graph().
I was one of the people who implemented t-strings (PEP 750). I worked mainly on the parser.
You can write except A, B: without parentheses.
Łukasz, Lysandros and I built the new default REPL, based on the PyPy REPL. I also made tracebacks colored by default.
New C API hooks that report when objects are created and destroyed. Memory profilers can use them.
f-strings are now part of the grammar. The tokenize module also became up to 64% faster.
I designed and wrote support for the Linux perf profiler (-X perf). With it, Python function names show up in native profiles. 3.13 added -X perf_jit, which works without frame pointers.
You can now install a tracer or profiler on every thread at once.
Tracebacks underline the exact expression that failed. Before 3.11, they showed only the line.
Mark Shannon and I made Python-to-Python calls stop using the C stack. Simple recursive code became about 1.7x faster.
In 3.10 I rewrote many SyntaxErrors, for example "expected ':'", "Perhaps you forgot a comma?" and unclosed brackets. I also added "Did you mean" suggestions for NameError and AttributeError. I improve them in every release. 3.12 added import suggestions. 3.14 added keyword typo suggestions like "Did you mean 'while'?".
With the new parser, multi-line with (a() as x, b() as y): became official syntax.
Yury Selivanov and I added a per-opcode cache. It made attribute access about 36% faster (44% for slots).
The new PEG parser became the default in 3.9. We deleted the old LL(1) parser in 3.10.
I wrote the graphlib module (topological sorting) with Tim Peters and Larry Hastings. I wrote ast.unparse() with Batuhan Taskaya.
I implemented the / syntax for positional-only parameters.
I added math.prod() and gc.get_objects(generation=...). I also helped make namedtuple field lookups and class variable writes faster.
I worked on the garbage collector from 3.8 to 3.12. 3.8 got gc.get_objects(generation). 3.9 got correct handling of resurrected objects and gc.is_finalized. 3.10 got GC audit hooks. In 3.12, GC runs moved from object allocation to the eval breaker.
$ python3.11 area.py
Traceback (most recent call last):
File "/tmp/area.py", line 4, in <module>
area({"width": 4, "height": None})
File "/tmp/area.py", line 2, in area
return shape["width"] * shape["height"]
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' I build tools that inspect running Python processes. They read the memory, the call stacks and the native frames of the process.
Co-creator, with Matt Wozniski at Bloomberg
A memory profiler for Python. It tracks every allocation in Python code, in native extension modules and in the interpreter.
memray run my_script.py profiling.sampling · Co-author, PEP 799
The sampling profiler in the Python 3.15 standard library. It reads the call stack from the memory of a running process.
python -m profiling.sampling attach --live 12345 Co-creator, with Matt Wozniski at Bloomberg
Prints the stack of a running Python process or a core dump. It shows the Python frames and the native frames together.
pystack remote 12345 Maintainer
A pytest plugin for Memray. It reports the allocations of each test and fails a test that goes over its memory limit.
pytest --memray tests/ Co-author, PEP 617
The PEG parser generator that builds the CPython parser. This standalone version works with your own grammars.
python -m pegen my_grammar.gram -o parser.py Stars as of Sep 2026
Strange Python snippets, with an explanation of how each one works.
PythonMakes a fast laptop behave like an overloaded CI runner, to reproduce failures that only happen in CI.
ShellMemory benchmarks for CPython, tracked across commits and build configurations.
PythonA Rust library for Linux profilers on perf_event. It resolves native, Python, JIT and kernel frames.
RustUnwinds the native stack with GNU backtrace, libunwind and libdw, so you can compare them.
CShows pointers as emoji in GDB, so you can tell them apart.
Python Shadow-stack unwinding. It is a drop-in replacement for unw_backtrace().
A Rust reader, writer and ELF/DWARF converter for the LLVM GSYM symbol format.
RustA native stack unwinder for profilers, built on a vendored libunwind.
RustRenames dynamic symbols in extension modules and their shared libraries to fix symbol clashes.
Pythonpatchelf, rewritten as a compiler pass. It lifts the ELF file into a typed IR, then checks and changes it.
Rust Undoes part of auditwheel repair. It points an extension module back at the system library.
Writes a core dump for the debugger when a program stops on an uncaught exception. It has no cost until then.
PythonA CUDA raytracer for the Kerr spacetime. It shows how light moves around a spinning black hole.
CUDAcore.py is a podcast about CPython internals. Łukasz Langa and I host it. We talk about what changes in each release and why.
31 episodes, 49 hours, since 2023
A short live episode from EuroPython 2026. We interview Guido van Rossum about the Grail web browser, Rietveld, aesthetics in code, and music.
0:00 / 42:47
I have given 60 talks since 2015, in English and Spanish. Most of them are about CPython internals.
The first keynote in Spanish at PyCon US, with live English captions and audio. It is about how a large group of people builds Python, and what AI-generated contributions mean for the core team.
EuroPython 2026
PyCon Greece 2025
PyCon Portugal 2025
EuroPython 2021
PyConES 2019
60 talks
Lazy imports and the art of interpreter procrastination
How PEP 810 brought explicit lazy imports to Python 3.15. We follow them from the bytecode to the proxy objects that load a module on first use. With Noah Kim.
Core.py live with Guido van Rossum
Łukasz Langa and I recorded an episode of the core.py podcast live on the EuroPython main stage. Guido van Rossum was our guest. With Łukasz Langa and Guido van Rossum.
One namespace to namespacing them all
I proposed to move the standard library into its own top-level namespace, apart from PyPI packages. I asked if the multi-year migration is worth it.
The 2026 Python Steering Council answers questions about the state of Python, CPython governance and the core team. With Barry Warsaw, Donghee Na, Savannah Ostrowski and Thomas Wouters.
Tachyon: Python 3.15's sampling profiler is faster than your code
Tachyon is the sampling profiler in Python 3.15. It reads the memory of a running process without stopping it and decodes the interpreter state from outside. With László Kiss Kollár.
Horizonte de sucesos / Event Horizon
The first keynote in Spanish at PyCon US, with live English captions and audio. It is about how a large group of people builds Python, and what AI-generated contributions mean for the core team.
Maintaining OSS in the age of AI
AI-generated pull requests are fast to submit and slow to review. We talk about what this does to open source maintainers. With David Hewitt.
Cómo todo va a cambiar para los debuggers en Python 3.14
PEP 768 lets debuggers attach safely to a running Python 3.14 process, at no performance cost. I explain why we needed it and how it works, with pdb attached live.
The talk compares a crab doing pull-ups, Python and PEG parsers. Each one tries ordered alternatives, backtracks when needed and commits to what works.
A new safe external debugger interface for CPython
PEP 768 is a safe interface in Python 3.14 that lets debuggers and profilers attach to live processes with no overhead. It replaces unsafe tricks that can crash the interpreter.
CPython Core Development Panel co-host
Łukasz Langa and I hosted a panel of core developers. They talked about Python 3.14 and later versions, and how people can contribute. With Łukasz Langa, Emily Morehouse-Valcarcel, Savannah Bailey, Brett Cannon, Mark Shannon and Hugo van Kemenade.
The 2025 Python Steering Council answers questions from the audience. With Barry Warsaw, Donghee Na and Gregory P. Smith.
A new safe external debugger interface for CPython
PEP 768 is a safe way for debuggers and profilers to attach to running CPython processes, with no overhead. It is new in Python 3.14. With Ivona Stojanovic.
Zoom, Enhance: Asyncio's New Introspection Powers
Python 3.14 can inspect a running asyncio program from another process. You can debug and profile async code in production with no overhead. We show how it works. With Yury Selivanov.
Let's benchmark memory as well lightning talk
I said that CPython does not measure its memory use. We should track memory together with speed, with memory benchmarks and the infrastructure to run them.
Cómo estamos eliminando el GIL en CPython
How we remove the GIL from CPython, starting in Python 3.13, without breaking compatibility or single-thread speed. I explain what changes for programmers and extension authors.
Tales from the abyss: some of the most obscure CPython bugs
Some of the strangest bugs we found in CPython, and how we fixed them. I also show debugging tricks that you can use in your own code.
CPython Core Development Panel
Core developers talk about Python 3.13 and later versions, and how people can contribute.
The 2024 Python Steering Council answers questions from the audience.
A Fireside Chat With the Hosts of the Core.py Podcast
A live chat with Łukasz Langa and invited core developers about the new features in Python 3.13. With Łukasz Langa.
Profiling at the speed of light
Python 3.12 supports the Linux perf profiler with a small JIT compiler. I show how it works and how to profile Python and native code together.
Python's security model after the xz-utils backdoor
I asked how the CPython contribution and release process would resist a social-engineering attack like the xz-utils backdoor.
PyREPL: New default REPL written in Python
We presented a new interactive REPL written in Python, based on the pyrepl of PyPy. It became the default REPL in Python 3.13. With Łukasz Langa and Lysandros Nikolaou.
Making asserts cooler in 3.14 lightning talk
A 90-second demo of a plan to make a failing assert statement show the values in it.
How Python keeps its identity while it changes. I talk about new ideas and compatibility, language design, and a larger and more varied group of users.
Profiling a la velocidad de la luz
Python 3.12 supports the Linux perf profiler with a small JIT compiler. I show how it works and how to profile Python and native code together.
How Python keeps its identity while it changes. I talk about new ideas and compatibility, language design, and a larger and more varied group of users.
f"yeah!" - How we are supercharging f-strings in Python 3.12
PEP 701 moved f-string parsing into the PEG grammar in Python 3.12. We explain how, which old limits it removed, and what f-strings can do now. With Marta Gómez Macías.
Core developers talk about recent and future changes in CPython, and how to get involved.
How memory profilers such as Memray track allocations in Python and native code. I show how to use them to find leaks and high memory use.
Python Steering Council Keynote
The Python Steering Council keynote panel, about the state of the language and how it is governed.
Python & Bloomberg: An Open Source Duo sponsor session
A Bloomberg sponsor session with several speakers, about the open source Python work of Bloomberg. It includes Memray and PyStack.
Faster CPython project: Cómo estamos haciendo Python 3.11 más rápido
Python 3.11 is between 10% and 60% faster. I explain the interpreter that specializes and adapts itself to the program that it runs.
Making Python better one error message at a time
The story of the better error messages in Python 3.10 and 3.11. I show how the parser and the interpreter make them, and what makes a good error message.
Core developers talk about the state and future of CPython, and how to contribute.
Making Python better one error message at a time
The story of the better error messages in Python 3.10 and 3.11, and how they help both new learners and experienced developers.
Python Steering Council Keynote
The Python Steering Council keynote panel.
Panel: Typing-sig and Python Core Dev
Members of typing-sig and core developers talk about how typing features are designed and how they get into the language. With Guido van Rossum, Thomas Wouters, Jelle Zijlstra, Pradeep Kumar Srinivasan and Matthew Rahtz. The video is the full summit. The panel starts at 2:50:44.
I proposed to move f-string parsing out of about 1,400 lines of hand-written C and into the PEG grammar. This became PEP 701.
Nobody expects the Spanish inquisition
Stories of how CPython is made: who works on it, how we develop it, and our fights with some of the most obscure bugs.
Python Steering Council Keynote
The Python Steering Council keynote panel. With Carol Willing, Thomas Wouters, Brett Cannon and Barry Warsaw.
PEP 657: Fine-grained error locations in tracebacks
We proposed to store column information for bytecode, so that tracebacks can point at the exact expression that failed. It shipped in Python 3.11. With Batuhan Taskaya.
Un nuevo PEG parser para Python
An online talk for Python Madrid about the new PEG parser in CPython (PEP 617).
Replacing CPython's parser with a PEG-based parser
We presented pegen and PEP 617, the plan to replace the LL(1) parser of CPython with a PEG parser. With Guido van Rossum and Lysandros Nikolaou.
The soul of the beast: Everything about Python's grammar
What makes Python easy to learn and read. I show how the grammar and the parser are built, and why it is hard to design new syntax.
Inside Python: through the eyes of a core developer
How CPython is developed, seen from the inside by a core developer.
Python Core Developer Q&A moderator
I organized and moderated a Q&A with core developers after the core dev sprint at Bloomberg London. With Guido van Rossum, Carol Willing, Michael Foord, Steve Dower, Emily Morehouse and Brett Cannon.
Everything about the grammar of Python: how the parser is generated, how it works, and what makes Python easy to read.
The soul of the beast: Everything about Python's grammar
What makes Python easy to learn and read. I show how the Python grammar and parser are generated and how they work.
Time to take out the rubbish: garbage collector
How CPython manages memory with reference counting and a cyclic garbage collector, and why this matters for your programs.
The Night's Watch is fixing the CIs in the darkness for you lightning talk
About the work of keeping the CPython CI and buildbots green, and the problems that flaky tests cause.
Hora de sacar la basura: garbage collector
How CPython manages the memory of your objects: reference counting and the cyclic garbage collector. With Víctor Terrón.
¡Oh vosotros los que entráis, abandonad toda esperanza!
How Python works on the inside, from the source code to its execution in the interpreter.
Metaclases: exactamente qué y (sobre todo) por qué
What metaclasses are and, more importantly, why they exist, with examples that are easy to follow. With Víctor Terrón.
Parallel and non parallel stuff
A workshop on parallel and asynchronous programming in Python from the start: threads, processes, the GIL and asyncio.
Los closures que emocionaron a Spielberg
An explanation of closures in Python. With Víctor Terrón.
Agujeros negros y optimización de código en Python
I built a relativistic ray tracer in Python that draws black holes like the ones in Interstellar. Then I made the code as fast as I could.
No talks match these filters.
I also talk about CPython on other people's shows. These are the recordings that I know about, newest first.
21 recordings on 14 shows since 2020. Two are in Spanish. I was on Talk Python To Me four times, Python Discord three times, The Real Python Podcast three times and The Stack Overflow Podcast two times.
Recorded live at EuroPython 2025 in Prague. Three CPython release managers talk about how a release works, our best and worst releases, and our release rituals. We also talk about how to pay for open source.
With Łukasz Langa and Hugo van Kemenade. Host: Mia Bajić. Video.
Before Python 3.13 came out, Łukasz and I talked about the free-threaded build, the new JIT, the yearly release cycle and iOS support.
With Łukasz Langa. Host: Jerod Santo.
Just before Python 3.12, I talk about core development, the Steering Council, release management and Memray.
Host: Mike Driscoll.
Matt Wozniski and I explain Memray, the tracing memory profiler for Python and native extensions that we wrote at Bloomberg.
With Matt Wozniski. Host: Michael Kennedy. Video.
Part two. We talk about how Python changes for AI and data science, how we design the language, the GIL and the Faster CPython work.
Host: Ben Popper and Kyle Mitofsky.
Part one. I went from a PhD on rotating black holes to CPython, and from typo fixes to core developer. Then we talk about the Steering Council.
Host: Ben Popper and Kyle Mitofsky.
Matt Wozniski and I show how PyStack inspects hung processes and core dumps, with mixed Python and C++ stacks and local variables.
With Matt Wozniski. Host: Michael Kennedy. Video.
A rerun: the same recording as Talk Python To Me #388.
I was the 3.11 release manager. Four core developers talk about the release process, the Faster CPython work, the better error messages and exception groups.
With Irit Katriel, Mark Shannon and Brandt Bucher. Host: Michael Kennedy. Video.
I talk about the Python Guild, the internal Python community at Bloomberg. Then I talk about how I manage the Python 3.11 release.
Host: Christopher Bailey.
I come back to talk about Memray, a tracing memory profiler, and what a profile can tell you about a codebase.
Host: Christopher Bailey.
How the PEG parser helps to find the location of a syntax error. Also, the work behind the better error messages in Python 3.10 and 3.11.
Host: Christopher Bailey.
The 2021 Steering Council looks back at the decisions of the year, at governance and at release management.
With Barry Warsaw, Carol Willing, Brett Cannon and Thomas Wouters. Host: Michael Kennedy.
In Spanish. How I went from physics to CPython, how Python gets its money and what a core developer does each day. We also talk about the PEP process and new features.
Host: Andros Fenollosa. Apple Podcasts.
Lysandros, Guido van Rossum and I replaced the LL(1) parser of CPython with a PEG parser in Python 3.9. We explain how, and what it makes possible, such as pattern matching.
With Lysandros Nikolaou. Host: Tobias Macey.
Esferas Invisibles is a science podcast in Spanish. Braulio Valdivielso and I host it. Topics include black holes, the abc conjecture, leap seconds, mantis shrimp and AI girlfriends.
“Esferas Invisibles es como deambular por wikipedia, pero en audio.” (Esferas Invisibles is like a walk through Wikipedia, but in audio.)
Apple Podcasts Spotify RSS feed