Python 3.15 Brings Lazy Imports and JIT Compiler: What Changes for Developers
Hello HaWkers, Python continues its impressive evolution. Version 3.15, currently in alpha phase, brings changes that can significantly transform performance and the development experience. Lazy imports, a more mature JIT compiler, and UTF-8 as default are just some of the new features.
Let's explore what's coming and how you can start testing these features.
Lazy Imports: On-Demand Loading (PEP 810)
One of the most anticipated additions in Python 3.15 is lazy imports, defined in PEP 810. This feature allows modules to be loaded only when actually used, drastically reducing application startup time.
The Problem Lazy Imports Solve
Currently, when you import a module in Python, it's completely loaded into memory, even if you only use a small part of it:
# Current behavior (Python <= 3.14)
import pandas as pd # Loads ALL of pandas immediately
import numpy as np # Loads ALL of numpy immediately
import tensorflow as tf # Can take several seconds!
# Even if you only use one function...
result = pd.read_csv('data.csv')In projects with many dependencies, this can result in startup times of 10+ seconds.
How Lazy Imports Work
With Python 3.15, you can use lazy imports that only load when needed:
# Python 3.15+ with lazy imports
# Method 1: Using the new lazyimport module
from lazyimport import lazy_import
pd = lazy_import('pandas')
np = lazy_import('numpy')
tf = lazy_import('tensorflow')
# At this point, NO module has actually been loaded!
print("Application started") # Executes instantly
# Only now is pandas loaded
df = pd.read_csv('data.csv')# Method 2: Using the __future__ import
from __future__ import lazy_imports
import pandas as pd # Still doesn't load!
import numpy as np # Still doesn't load!
# Loading happens on first use
result = pd.DataFrame({'a': [1, 2, 3]})
Practical Benefits
Startup time:
- CLI applications: from 5-10s to < 1s
- Simple scripts: from 2-3s to < 0.5s
- Web services: much faster cold start
Memory usage:
- Unused modules don't occupy RAM
- Ideal for CLIs with many commands
- Better for serverless/FaaS
JIT Compiler: Native Performance
Python 3.15 brings significant improvements to the experimental JIT (Just-In-Time) compiler that was introduced in Python 3.13.
Real Performance Gains
Benchmarks show consistent gains of 20% or more for specific workloads:
# Code that benefits from JIT
def calculate_fibonacci(n: int) -> int:
"""Intensive calculation that JIT optimizes well."""
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
# With JIT enabled, this type of loop
# can be 20% faster
result = calculate_fibonacci(1000000)Enabling JIT
# Run Python with JIT enabled
python -X jit script.py
# Or via environment variable
PYTHON_JIT=1 python script.pyWhen JIT Helps (and When It Doesn't)
Scenarios with significant gains:
- Intensive numeric loops
- Data processing in pure Python
- Mathematical algorithms
- Text parsing and transformation
Scenarios with little impact:
- Code already using NumPy/Pandas (already optimized in C)
- I/O bound (waiting for network/disk)
- Typical web applications
UTF-8 as Default (PEP 686)
Finally! Python 3.15 adopts UTF-8 as the default encoding for I/O operations.
The Previous Problem
# Python <= 3.14 on Windows
# Could use cp1252 or another system encoding
with open('file.txt') as f:
text = f.read() # Encoding depended on the system!
# Different result on Windows vs Linux vs macOSThe New Behavior
# Python 3.15+
# UTF-8 is ALWAYS the default, on any system
with open('file.txt') as f:
text = f.read() # Always UTF-8!
# Consistent on Windows, Linux, macOS
# No longer need to specify encoding='utf-8'Safe Migration
If your code depended on system encoding, you can keep the old behavior:
# Keep old behavior if necessary
import locale
# Get system encoding
system_encoding = locale.getpreferredencoding(False)
with open('file.txt', encoding=system_encoding) as f:
text = f.read()Template Strings (t-strings) - PEP 750
A new way to create processable strings:
# Python 3.15+ t-strings
from string import Template
# t-strings work like f-strings but are processable
name = "Maria"
age = 25
# Traditional f-string (result is final string)
message_f = f"Hello, {name}! You are {age} years old."
# t-string (result is processable Template object)
message_t = t"Hello, {name}! You are {age} years old."
# You can inspect and modify before rendering
print(message_t.args) # {'name': 'Maria', 'age': 25}
print(message_t.template) # "Hello, {name}! You are {age} years old."Use Cases
Security in SQL/HTML:
# t-strings allow automatic sanitization
def html_escape(template):
"""Escapes dangerous values automatically."""
from html import escape
args = {k: escape(str(v)) for k, v in template.args.items()}
return template.template.format(**args)
user_input = "<script>alert('xss')</script>"
safe_html = html_escape(t"<div>{user_input}</div>")
# Result: <div><script>alert('xss')</script></div>
Free-Threaded Python (PEP 779)
Python 3.15 marks the version where free-threaded mode (no GIL) is officially supported:
# Python 3.15+ with free-threading
import threading
# Now Python threads can truly execute in parallel!
def heavy_work(n):
total = 0
for i in range(n):
total += i * i
return total
# Create threads that actually execute in parallel
threads = []
for _ in range(4):
t = threading.Thread(target=heavy_work, args=(10_000_000,))
threads.append(t)
t.start()
for t in threads:
t.join()
# In Python 3.15 free-threaded, this uses 4 cores!How to Enable
# Install Python with free-threaded support
# (special build required)
# Check if enabled
python -c "import sys; print(sys.flags.nogil)"New High-Performance Profiler (PEP 799)
Python 3.15 includes a new low-overhead profiler:
# Using the new profiler
import _profiler
# Low-impact statistical profiler
with _profiler.profile() as p:
# Your code here
result = complex_function()
# Analyze results
stats = p.get_stats()
for func, time in stats.most_common(10):
print(f"{func}: {time:.2f}ms")Advantages Over cProfile
Comparison:
- cProfile: 30-50% overhead
- New profiler: < 5% overhead
- Ideal for production profiling
Native Zstandard Compression (PEP 784)
Native support for Zstandard, a modern compression algorithm:
# Python 3.15+
import compression.zstd as zstd
# Compress data
data = b"data to compress" * 1000
compressed = zstd.compress(data)
print(f"Original: {len(data)} bytes")
print(f"Compressed: {len(compressed)} bytes")
print(f"Ratio: {len(compressed) / len(data):.2%}")
# Decompress
original = zstd.decompress(compressed)
assert original == dataWhy Zstandard?
Algorithm comparison:
- gzip: good compression, medium speed
- lz4: ok compression, very fast
- zstd: great compression, very fast (best of both worlds)
When Will Python 3.15 Be Released
Official Timeline
Alpha Phase (current):
- 3.15.0a1: October 2025
- 3.15.0a3: December 2025 (current)
- 3.15.0a7: April 2026
Beta Phase:
- 3.15.0b1: May 2026
- Features frozen
Release Candidate:
- 3.15.0rc1: July 2026
Final Release:
- 3.15.0: October 2026
Conclusion
Python 3.15 represents a significant evolution of the language, with focus on performance and developer experience. Lazy imports and the mature JIT compiler may finally address historical complaints about Python's speed.
If you work with Python, it's worth following these changes and starting to test alpha versions in experimental projects.
If you're interested in performance in programming languages, I recommend checking out another article: Microsoft Wants to Eliminate All C and C++ Code by 2030 Using Rust and AI where you'll discover how big companies are rethinking their language choices.

