My narrative of EuroPython 2025 in Prague
- Link to the website: EuroPython 2025
Course material: https://github.com/Lenormju/python-royal/tree/english_translation
Mostly the tech stack we use at WSP: uv, ruff, mypy, pytest, pre-commit, ...
Got to play with streamlit a bit, which was fun.
- pydoit for task management and cli automation
- uv custom ca certificates for possible certificate problems
Course material: https://learn.nvidia.com/dli-event
See the jupyter notebooks: no_gil_gpu.ipynb
See the use of NVidia's nvic in nvic.py
Many tips and tricks on ThreadPoolExecutor and ProcessPoolExecutor both with and without the GIL. Also how to use the GPU with CUDA and Python.
Course material: mighty_dot.zip
Very very interesting and well presented workshop by Mike Müller.
- A deep dive into properties and descriptors, also alternative ways to implement them.
- How and when to use them? What are the pitfalls?
- There is a WeakKeyDictionary in the
weakrefmodule to store weak references to objects, which can be useful for caching. Definitely something to look into.
Course material: Presentation
An interesting workshop on how to prepare a talk for EuroPython or any other conference, lots of tips and tricks.
Also prepared and presented a lightning talk for the first time, which was a fun experience.
Keynote: You don’t have to be a compiler engineer to work on Python by Savannah Bailey
- Slides
- Youtube
- The home of Python’s code. Follow issues, submit PRs, or just watch the repo to learn.
- Docs proposing/explaining major Python changes — how and why things work the way they do.
- Where high-level discussion happens on features, governance, packaging, and ideas.
- Everything you need to start contributing: setup, tools, triage process, testing, and more.
- Once self-taught developer, now a core python developer.
- Triaging issues is a great way to contribute:
- Reproducing issues
- Finding minimum reproducers
- Helping categorize issues
- Suggesting potential fixes
- Updating docs and improving test coverage is also a great way to contribute.
- Do it scared ✨
Keynote: Why it took 4 years to get a lock files specification by Brett Cannon
- Slides
- Youtube
- PEP 751 – A file format to record Python dependencies for installation reproducibility
- pylock.toml standard
- Source distribution (sdist) is the source code of your project. Its format is: {project-name}-{version}.tar.gz
- Wheel distribution (wheel) also contains the source code, but bunch of metadata and compiled files. It's a zip file that gets copied "as is" to the environment. Its format is: {project-name}-{version}-{python-tag}-{abi-tag}-{platform-tag}.whl
- Please, please, please always include wheel distribution in your releases when pushing to PyPI.
- pyproject.toml should at least contain:
- [project] section with:
- name
- version
- [build-system] section with:
- requires
- build-backend
- [project] section with:
- Don't do upperbounds on your dependencies in pyproject.toml, unless you have a very good reason to do so.
- Use environment markers to specify dependencies for different environments (e.g. for older Python versions).
- You can have pylock.*.toml file for different purposes, e.g. one for all the newest versions of your dependencies and one for all the oldest versions of your dependencies.
- uv can both create and install from pylock.toml files.
Keynote: Behind the scenes of FastAPI and friends for developers and builders by Sebastián Ramírez
This is a must watch! Every minute of it is gold 🪙
- Focus on solving a problem rather than building stuff.
- Value of newbies (juniors) is great, when it comes to testing, documentation, and user experience.
- Reduce ambiguity in your code, API, and documentation.
- Write good documentation (Documentation Driven Development).
- Premature abstraction is as dangerous as premature optimization.
- Cake vs. Puppy PR: Cake PR is one-time review effort, Puppy PR is an ongoing maintenance effort.
- Your attention is valuable, Not everything deserves your attention.
Here are some of the interesting talks I attended:
- Slides
- The culture map book: Decoding How People Think, Lead, and Get Things Done Across Cultures.
- Nonviolent communication: Life-Changing Tools for Healthy Relationships
- On measuring software development productivity
- On feedback cycles
- What does good teamwork mean to you?
- Softwate development is a team sport.
- Skilfully pass the ball and set the next person up for success.
- Put principles above processes.
- Ball passing in software development:
- Pull requests: make a PR skilfully!
- Code reviews: give feedback skilfully!
- Apply feedback skilfully!
- Ask for help skilfully!
- Receive help skilfully!
- Share status regularly!
- To err is human!
- To grow is human!
- Good teamwork is good business.
- Google’s Project Aristotle found that psychological safety is the most important factor for high-performing teams. Definitely read the article!
- Slides
- Burn out by Emily & Amelia Nagoski
- Why zebras don't get ulcers by Robert Sapolsky
- The social contract of open source by Brett Cannon
- Understand the types of toxic feedback:
- Entitlement: "Why is my problem not solved?"
- Frustration: "Thanks for nothing!"
- Attack: "🤬 U"
- Coping strategy:
- Do not engage hot-headedly.
- Go through your stress respoonse cycle:
- Cool down
- Open source = No one owes you anything.
- Boundaries:
- You deserve respect and decency.
- Have a Code of Conduct and enforce it.
- Don't accept abuse.
- Slides
- Blog post by the speaker
- PyCon US 2025 version of the talk
- The rising sea (by Mathew Drury) / The harbor coding problem
- Two pieces of code are coupled if they can only be understood by looking at both.
- Testable code is better code.
- The shape of your code should NOT be determined by the shape of your data.
- In software projects, you often have:
- Database schemas (e.g. SQL tables)
- API schemas (e.g. what your API sends/receives)
- Business logic types (e.g. what your app actually works with in memory)
- ORM models (e.g. how your code talks to the database)
- These may look similar, but they serve different purposes and have different flexibility needs.
- If you force everything to use the same type (a “franken-type”), the rigid parts (e.g. the database) will limit flexibility everywhere.
- Some parts (like the database) are harder to change.
- Others (like your internal app logic) should be easy to change.
- It's better to define separate types in each layer.
- Then, explicitly map between them (e.g. convert a DB object to an API response).
- Yes, it’s a bit more work, but it keeps each part clean, flexible, and easy to maintain.
- Start with the
Domain modelbased on your business logic:- This is the core logic of your app, independent of any external systems.
- It should be clean, flexible, and easy to change.
- Complexity is not about how many keys I have to press – it’s about how difficult it is to reason about the consequences of what I’m doing.
- Performance matters, because:
- Cost savings
- Sustainability
- User experience and adoption
- Competitive advantage
Below we handle a series of cases with the same question: Which one is faster?
-
➕ First case, sum(generator) vs len(list comprehension):
-
sum(1 for x in arr if x % 2 == 0)
-
len([x for x in arr if x % 2 == 0])
-
Answer: Context switching between the generator and the list comprehension takes time, so the list comprehension is faster. It uses however much more memory (x10_000).
-
-
🔡 Second case, concatanating strings with .join() or with +:
-
''.join(strings)
-
for s in strings: concatanated += s
-
Answer: While using +=, the string is copied into a new larger string instance every time, which is very inefficient. So .join() is much faster. Join pre-allocates the full string size and copies each string once.
-
Built-in functions are usually well optimized, so use them whenever possible.
-
-
🗝️ Third case, list comprehension vs map():
-
[x * 2 for x in data]
-
list(map(lambda x: x * 2, data))
-
Answer: map() requires a context switch in each iteration to the lambda function (setup, pass arguments and teardown). So eventhough map() is well optimized in C, This operation is faster with list comprehension.
-
-
🔁 Fourth case, calculating factorial with recursion vs stack appraoch:
-
def factorial_recursive(n): if n == 0: return 1 return n * factorial_recursive(n - 1)
-
def factorial_stack(n): stack = [] result = 1 while n > 0: stack.append(n) n -= 1 while stack: result *= stack.pop() return result
-
Answer: The recursive approach has a lot of overhead due to function calls (pushing frames) and context switching, so the stack approach is faster.
-
-
🦀 Fifth case, getting x squared in python vs a Rust function:
-
x * x
-
calling rust_square(x) using Rust import from pyo3
-
Answer: This is a real simple operation and Python is very fast at it, so the Rust function is not faster.
-
The overhead of calling the Rust function and converting the types is too high.
-
-
🦀 Sixth case, Rust fibonacci vs python fibonacci:
- Answer: in Rust, this runs as a native cpu code, purely algorithmic. It is also faster that CPython interpreter bytecode execution. So the Rust version is much faster.
-
🦀 Seventh case, Binary search in Python vs. Rust:
-
in both cases, a list of 10_000 sorted random integers is passed.
-
Answer: Transforming a python list to Rust's Vec is an O(n) operation, while the binary search is O(log n). So the Rust version becomes slower slower and as the list size increases.
-
-
🦀 Eighth case, Binary search in Python vs. Rust:
-
Now, we pass a pyo3 list to the Rust function and only access log(n) elements in the list directly from memory (so no conversion to Vec).
-
Answer: This is much faster, because we avoid the O(n) conversion to Vec and only access the elements directly from memory. So the Rust version is much faster.
-
- p99 a free performance analysis tool in the browser.
Interesting talk about processing geographic data.
- Open street map OpenStreetMap (abbreviated OSM) is a free, open map database updated and maintained by a community of volunteers via open collaboration.
- PostGIS PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL.
- GeoAlchemy 2 GeoAlchemy 2 is an extension of SQLAlchemy for working with spatial databases.
- gpxpy A Python library for parsing and manipulating GPX files. GPX (GPS Exchange Format) is an XML schema designed for transferring GPS data between applications and web services on the internet.
- Folium Folium is a Python library used for visualizing geospatial data. It builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js library.
Nice talk about the pros and cons of threading vs async in the context of free threaded Python.
- Use sync when:
- One CPU is enough
- Responsiveness doesn't matter
- Use Async when:
- One CPU is enough
- Responsiveness matters
- Use Threading when:
- One CPU core is not enough and the GIL is disabled
- Or when you have blocking I/O tasks
Talk: Performance improvements in 3.14 and maybe 3.15 by Mark Shannon
Advanced talk on the performance improvements in Python 3.14 and 3.15.
Resources:
- Areas of improvement (See the Benchmark here):
- Interpreter: 20%
- JIT: 9%
- Memory allocation/deallocation: 12%
- Cycle GC: 12%
- Lookup and dynamic: 15%
- Other: 32%
Interesting talk about the importance of documentation, different types of documentation, and how to write and maintain good documentation.
- Why document?
- People forget things
- People leave
- People join
- People change roles
- Different types of documentation:
- Goal oriented approach: How to guides
- Learning oriented approach: Tutorials
- Understanding oriented approach: Explanations
- Information oriented approach: References
- Tip: Make updating the documentation part of your workflow on CI/CD.
Eye opening talk about performance myths in Python.
- Intuition is often wrong. Imaginary knowledge leads to imaginary improvements.
- Measure, don't guess. Act on data, not on hunches.
- We could rely on known datastructures for performance (e.g. dict, list, set), but even then we should measure.
- Being aware of the impact of the code being optimized on the overall performance is crucial. Do not try to solve a micro problem that would lead to a micro benefit.
- Useful tools to profile the code or the tests:
- cProfile:
python -m cProfile -o output.prof $(which pytest) tests/test_module.py - timeit:
python -m timeit -s "import test_module" "test_module.some_function()" - snakeviz:
snakeviz output.prof - pyinstrument:
pyinstrument -r html tests/test_module.pyplus some additions to the test code.
- cProfile:
__slots__ are a double-edged sword. While they promise a leaner memory footprint and faster attribute access, they can silently backfire, creating performance pitfalls in your code.
- While Python classes without
__slots__have a__dict__to store attributes, in classes with__slots__attributes live in a pre-allocated fixed array attached to the object, determined at class creation time. There are no__dict__when using__slots__. - This affects the size of the object in memory, and also how attributes are accessed. The impact is more pronounced in large collections of objects.
- Since Python 3.11, the memory saving benefit is reduced.
- Pitfalls:
- unused (and duplicate) slots still take memory.
- inheritance can lead to unexpected memory bloat. Inheriting from a class with
__slots__adds its slots to the child class, even if they are not used.
- Broken
__slots__:- Defining
__slots__in a class that inherits from a class without__slots__adds a__dict__to the child class, negating the memory savings. Solution: add__slots__ = ()to the parent class. - To check the slots of a class manually, use
MyClass.__dict__["__slots__"].
- Defining
- Pro tip:
- Use
slotscheckto find broken__slots__in your codebase.pip install slotscheckand thenslotscheck -m path/to/your/code.
- Use
Amazing talk about organizing (open source) projects, governance, and communication.
Amazing talk about automation with CI/CD and Python.
Interesting talk by a fun speaker, Rodrigo Girão Serrão.
Talk: What does = do?
A deep dive into what really happens when we use an = in our code.
A critical look at the current state of Rust in the Python ecosystem and what could be the next big thing.
- Rule#1: Don't say "Yes" unless it's been 24 hours since the request.
- Rule#2: Estimate the time, energy and the cost. Then multiply it by 4. Alternatively: make an optimistic estimate, make a pessimistic estimate, then sum them up!
- Rule#3: Future you is gonna be at least as busy as present you.
- Rule#4: Tell your loved one(s) that you are going to say "No" to them by saying "Yes" to the oppurtunity.
- Rule#5: The "honor to be asked" is a trap. Don't fall for it.
- It's Py (Pie) P (Pee) I (Eye) 😋
Session: AI discussion panel
- AI is a tool, not a replacement for human creativity.
- No AI expert can predict the future. Stop forecasting and definitely stop panicking.
Session: CPython Core Development Panel
- During a request for features to steal from other languages, a member of the audience suggested virtual threads from Java. Mark Shannon responded that he thinks this feature could work well in Python and mentioned that the core team might be "poking at it" in August to see what it would look like.
- The host asked Hugo van Kemenade, the release manager for Python 3.14, about potentially changing Python's versioning scheme to a year/month basis. Hugo confirmed that the proposal "was rejected," and the next version is 3.15. Emily Morehouse elaborated, saying the decision was a "plus zero minus zero" kind of thing, noting that one concern was the obscured link between the release year and the end-of-life date, as patches released the next year (e.g., 3.26.1) would still reference the previous release year (3.26).
- Brett Cannon shared a rejected PEP that he and Pablo had worked on, which they ultimately withdrew, aiming to get rid of the bare except statement (except:). Brett explained that they proposed this because the bare accept is a "foot gun" that catches BaseException instead of just Exception, but they withdrew the proposal after people got "too scared and upset" about the resulting breaking change.
- A user asked about plans for supporting the newly landed t-strings (template strings) in the standard library (such as gettext and logging). The host (Pablo) explained that there is no centralized roadmap, suggesting that whenever a user identifies a place where t-string support is useful, they should let the core developers know. Brett Cannon supported this, mentioning that the adoption of pathlike objects previously happened successfully when someone wrote a PEP defining the standard, and then people implemented it across the standard library.
- When asked how to improve the slow PEP discussion process, Brett Cannon offered a "snarky answer," wishing that everyone who comments would actually read the PEPs before offering feedback, as people often comment after only reading the summary, which wastes time. Savannah Bailey added that the Steering Council is still figuring out the process, suggesting that having more regular public discussions (not just asynchronous ones on the internet) might help, drawing inspiration from TC39 (the governing body for JavaScript).
- Regarding the fragmentation concerns surrounding different Python types (async, typed, free-threaded), Hugo van Kemenade noted that the free threaded build removed its experimental label in 3.14, urging people to start using and testing it because the current default build will eventually be replaced. The host (Pablo) provided a detail, explaining that the GIL (Global Interpreter Lock) will remain and be reintroduced if a C extension that doesn't claim to be free-threaded is loaded.
- A user questioned whether Python should specialize for enterprise or data science. Emily Morehouse argued that Python's success is due to its ability to serve all different groups of folks and that they do not want to specialize it, ensuring it remains accessible for education, music making, and complex software like space rockets. Brett Cannon summarized the community's goal by saying that Python should strive to be the "second best at everything," continually ensuring they serve the whole community.
- When asked about the feature they introduced that broke the most things, Brett Cannon recalled adding the message attribute to exceptions in 2007, which caused massive breakage because users were already writing that attribute themselves. However, Mark Shannon was declared the "winner" after confessing that his work on the incremental garbage collector introduced an N-squared assert in the debug build, which was misidentified as a major performance regression and resulted in Python 3.13 being delayed for a week.
- Following discussions about large breaking changes, a question was asked if the Steering Council had reconsidered introducing Python 4.0. The host (Pablo) responded that they likely don't want a Python 4 because they prefer gradually implementing deprecations rather than having a massive breaking leap. Emily Morehouse agreed, suggesting they are all "just kind of sitting around at the it's going to be three forever".
- When asked about their favorite 3.14 feature, Savannah Bailey and Mark Shannon both championed t-strings (template strings), with Mark noting they will "unlock a lot of different ways to use strings". The host (Pablo) selected the fact that Z standard is now in the standard library. Ukash (Lukasz Langa) mentioned adding a new optional parameter to argument parser objects called suggest on error, which is his first non-C feature.
This is the story of the world's most beloved programming language: Python. What began as a side project in Amsterdam during the 1990s became the software powering artificial intelligence, data science and some of the world’s biggest companies. But Python's future wasn't certain; at one point it almost disappeared.
This 90-minute documentary features Guido van Rossum, Travis Oliphant, Barry Warsaw, and many more, and they tell the story of Python’s rise, its community-driven evolution, the conflicts that almost tore it apart, and the language’s impact on... well… everything.
Resources:
- Transition from Python 2 to Python 3 was very painful: This illustrates the importance of understanding the current ecosystem and the impact of changes on existing users in all digital transitions. Tansition can mean discarding a lot of legacy tools which were made with huge effort and now suddenly are obsolete.
- The importance of inclusivity and community: Python's success is largely due to its welcoming and inclusive community. This highlights the importance of fostering a positive and supportive environment in any community or organization.