Python 3.15: Sampling Profiler, UTF-8 Default, AsyncPaginator e Miglioramenti
Esplora Python 3.15: statistical sampling profiler ad alta frequenza, UTF-8 encoding di default, AsyncPaginator, miglioramenti AttributeError e math.isnormal().

Python 3.15 introduce un sampling profiler statistico ad alta frequenza per performance analysis in produzione, UTF-8 come encoding di default, AsyncPaginator per paginazione asincrona, miglioramenti ai messaggi di errore AttributeError e nuove funzioni math. Questa release migliora debugging, internazionalizzazione e developer experience.
🎯 Novità Principali
Statistical Sampling Profiler (PEP 799)
Profiling production con zero overhead:
# ✅ Python 3.15 - Sampling profiler
# Profile processo in esecuzione
python -m profiling.sampling 1234
# Con opzioni custom
python -m profiling.sampling \
-i 50 \ # 50μs interval
-d 30 \ # 30 secondi duration
-o profile.stats \ # Output file
1234 # Process ID
# Generate flamegraph data
python -m profiling.sampling --collapsed 1234
# Profile all threads
python -m profiling.sampling -a --sort-tottime 1234
Real-time statistics:
# ✅ Output esempio
# Real-time sampling stats:
# Mean: 100261.5Hz (9.97µs)
# Min: 86333.4Hz (11.58µs)
# Max: 118807.2Hz (8.42µs)
# Samples: 400001
# Captured 498841 samples in 5.00 seconds
# Sample rate: 99768.04 samples/sec
# Error rate: 0.72%
# Profile Stats:
# nsamples sample% tottime cumul% cumtime filename:lineno(function)
# 158562 33.3% 1.586s 33.3% 1.586s test_compile.py:725(check_limit)
# 129553 27.2% 1.296s 27.2% 1.296s ast.py:46(parse)
# 22361 4.7% 0.224s 4.7% 0.224s test_compile.py:1368(test_big_dict)
Key features:
# ✅ Caratteristiche profiler
# Zero overhead: attach senza impact performance
# No code modification: profila app esistenti
# Real-time stats: monitora qualità sampling
# Multiple formats: stats dettagliati + flamegraph
# Thread-aware: profila main thread o tutti
# Sampling rates: fino a 1,000,000 Hz!
# Il profiler più veloce per Python
Programmatic usage:
# ✅ API Python
from profiling.sampling import SamplingProfiler
# Profila funzione
profiler = SamplingProfiler(interval_us=100)
profiler.start()
# Codice da profilare
result = expensive_function()
profiler.stop()
stats = profiler.get_stats()
# Analizza hot spots
for func, samples in stats.items():
print(f"{func}: {samples.direct_samples} samples")
# Identifica bottlenecks automaticamente
hot_spots = stats.get_hot_spots()
for spot in hot_spots:
print(f"Hot spot: {spot.function} - {spot.percentage}%")
Production debugging:
# ✅ Debug performance in produzione
# 1. Attach al processo
# python -m profiling.sampling --duration=60 <PID>
# 2. Profiler identifica bottleneck
# Hot spot: data_processing.py:42(transform_data) - 45%
# 3. Analizza pattern
# High call magnification: 12267x
# Molte chiamate indirette da poche chiamate dirette
# 4. Fix problema senza restart!
# Ideale per:
# - Production debugging
# - Performance regression
# - Unexpected slowdowns
# - CPU profiling
UTF-8 Default Encoding
UTF-8 indipendente da sistema:
# ❌ Prima: encoding dipendeva da locale
# Windows (locale CP1252):
with open('file.txt', 'w') as f:
f.write('Hello 世界') # Errore su caratteri non-ASCII
# Linux (locale UTF-8):
with open('file.txt', 'w') as f:
f.write('Hello 世界') # OK
# Comportamento inconsistente!
# ✅ Python 3.15 - UTF-8 di default
# Su qualsiasi sistema operativo:
with open('file.txt', 'w') as f:
f.write('Hello 世界 🌍') # OK ovunque!
# UTF-8 standard:
# - ~99% del web
# - Standard de facto
# - Supporto Unicode completo
# Encoding esplicito ancora possibile:
with open('file.txt', 'w', encoding='latin-1') as f:
f.write('Data')
# encoding='locale' per vecchio comportamento
with open('file.txt', 'w', encoding='locale') as f:
f.write('Data')
Opt-out se necessario:
# ✅ Disable UTF-8 mode
# Environment variable
PYTHONUTF8=0 python app.py
# Command-line
python -X utf8=0 app.py
# Encoding warning per compatibilità
python -X warn_default_encoding app.py
# Identifica codice che potrebbe essere affetto
Migration guide:
# ✅ Best practices per compatibilità
# SEMPRE specifica encoding per compatibilità versioni
with open('file.txt', 'w', encoding='utf-8') as f:
f.write('Data')
# Usa encoding warning durante test
# PYTHONWARNDEFAULTENCODING=1 pytest
# Identifica codice da aggiornare:
# - open() senza encoding
# - file operations implicit encoding
# - subprocess text mode
# Fix automatico:
# 1. Aggiungi encoding='utf-8' esplicito
# 2. Oppure encoding='locale' se necessario locale
Improved AttributeError Messages
Suggerimenti per attributi nested:
# ✅ Python 3.15 - Nested attribute suggestions
from dataclasses import dataclass
from math import pi
@dataclass
class Circle:
radius: float
@property
def area(self) -> float:
return pi * self.radius ** 2
class Container:
def __init__(self, inner: Circle) -> None:
self.inner = inner
circle = Circle(radius=4.0)
container = Container(circle)
# Accedi attributo errato
print(container.area)
# Output Python 3.14:
# AttributeError: 'Container' object has no attribute 'area'
# Output Python 3.15:
# AttributeError: 'Container' object has no attribute 'area'.
# Did you mean: 'inner.area'?
# Suggerisce path completo!
delattr() suggestions:
# ✅ Suggerimenti anche per delattr()
class A:
pass
a = A()
a.abcde = 1
# Typo durante delete
del a.abcdf
# Python 3.14:
# AttributeError: 'A' object has no attribute 'abcdf'
# Python 3.15:
# AttributeError: 'A' object has no attribute 'abcdf'.
# Did you mean: 'abcde'?
AsyncPaginator
Paginazione asincrona nativa:
# ✅ Python 3.15 - AsyncPaginator
from django.core.paginator import AsyncPaginator
async def list_articles(request):
articles = Article.objects.all()
paginator = AsyncPaginator(articles, per_page=25)
page_number = request.GET.get('page', 1)
page = await paginator.aget_page(page_number)
return {
'articles': [
{'title': a.title, 'id': a.id}
async for a in page
],
'has_next': page.has_next(),
'has_previous': page.has_previous(),
}
AsyncPage:
# ✅ Async iteration
from django.core.paginator import AsyncPaginator
async def process_large_dataset():
data = await fetch_large_dataset()
paginator = AsyncPaginator(data, per_page=100)
results = []
for page_num in paginator.page_range:
page = await paginator.aget_page(page_num)
async for item in page:
processed = await process_item(item)
results.append(processed)
return results
🔧 Module Improvements
math Module
# ✅ Nuove funzioni math
import math
# isnormal() - check normal float
print(math.isnormal(1.0)) # True
print(math.isnormal(0.0)) # False
print(math.isnormal(float('inf'))) # False
# issubnormal() - check subnormal float
print(math.issubnormal(1e-308)) # True
print(math.issubnormal(1.0)) # False
# fmax() / fmin() - max/min con NaN handling
print(math.fmax(1.0, float('nan'))) # 1.0
print(math.fmin(1.0, float('nan'))) # 1.0
print(max(1.0, float('nan'))) # nan (different!)
# signbit() - check sign bit
print(math.signbit(-0.0)) # True
print(math.signbit(0.0)) # False
calendar Module
# ✅ Dark mode support + HTML5
import calendar
# HTML calendar con dark mode
cal = calendar.HTMLCalendar()
html = cal.formatmonth(2024, 12)
# Output:
# <!DOCTYPE html>
# <html>
# <head>
# <meta name="color-scheme" content="light dark">
# <style>
# @media (prefers-color-scheme: dark) {
# /* Dark mode styles */
# }
# </style>
# </head>
# ...
# Accessibility improvements:
# - Semantic HTML5
# - ARIA labels
# - Keyboard navigation
difflib Module
# ✅ Color output
import difflib
text1 = "Hello World\nPython is great"
text2 = "Hello Universe\nPython is awesome"
# Unified diff con colori
diff = difflib.unified_diff(
text1.splitlines(keepends=True),
text2.splitlines(keepends=True),
color=True # Nuovo parametro!
)
print(''.join(diff))
# Output colorato come git diff:
# - linee rimosse in rosso
# + linee aggiunte in verde
# Controllo tramite environment variables:
# NO_COLOR, FORCE_COLOR, TERM
sqlite3 Module
# ✅ CLI improvements
# SQL keyword completion con <tab>
$ python -m sqlite3 database.db
sqlite> SEL<tab> → SELECT
# Colored output (di default)
sqlite> SELECT * FROM users;
# Risultati colorati per leggibilità
# Help text colorato
sqlite> .help
os Module
# ✅ os.statx() su Linux
import os
# statx() - extended file info (Linux 4.11+)
stat = os.statx(
'file.txt',
dir_fd=None,
flags=0,
mask=os.STATX_ALL
)
print(stat.st_size) # File size
print(stat.st_blocks) # Allocated blocks
print(stat.st_blksize) # Block size
print(stat.st_btime) # Birth time (creation)
print(stat.st_mtime) # Modification time
# Più dettagliato di os.stat()
🎨 Language Enhancements
Warning Filters con Regex
# ✅ Python 3.15 - Regex in warning filters
# Command line
python -W '/deprecation.*/::DeprecationWarning:mymodule' app.py
# PYTHONWARNINGS environment variable
export PYTHONWARNINGS='/future.*/:FutureWarning:/'
# In code
import warnings
warnings.filterwarnings(
'ignore',
message='/old.*api/', # Regex!
category=DeprecationWarning,
module='/my.*module/', # Regex!
)
# Match pattern: /regex/
# Prima: solo literal strings
# Ora: potenti regex per filtering
Real Number Support
# ✅ Timestamp con Decimal/Fraction
from decimal import Decimal
from fractions import Fraction
import time
# Timestamp precisi
timestamp = Decimal('1234567890.123456789')
time.sleep(timestamp) # Funziona!
# Fraction timeouts
timeout = Fraction(1, 2) # 0.5 secondi
socket.settimeout(timeout)
# Prima: solo int/float
# Ora: qualsiasi real number
# (non migliora precisione, solo convenience)
Enhanced repr
# ✅ ImportError/ModuleNotFoundError repr
try:
import nonexistent_module
except ImportError as e:
print(repr(e))
# Python 3.14:
# ImportError()
# Python 3.15:
# ImportError(name='nonexistent_module', path=None)
# Mostra name e path se forniti!
# Migliore debugging
📊 Deprecations & Removals
Removed
# ❌ Removed in Python 3.15
# ctypes.SetPointerType()
from ctypes import SetPointerType # ImportError!
# glob.glob0() / glob.glob1()
from glob import glob0, glob1 # ImportError!
# Use glob.glob() instead
# http.server.CGIHTTPRequestHandler
from http.server import CGIHTTPRequestHandler # ImportError!
# pathlib.PurePath.is_reserved()
from pathlib import Path
Path('CON').is_reserved() # AttributeError!
# Use os.path.isreserved() on Windows
# platform.java_ver()
from platform import java_ver # ImportError!
# sre_compile, sre_constants, sre_parse
import sre_compile # ImportError!
# Use re module instead
# typing.ByteString removed from __all__
from typing import ByteString # DeprecationWarning
Deprecated
# ⚠️ Deprecated in Python 3.15
# -b / -bb options (bytes warning)
python -b app.py # DeprecationWarning
# Diventerà no-op in 3.17
# hash function string= parameter
import hashlib
hashlib.md5(string=b'data') # DeprecationWarning
# Use positional: hashlib.md5(b'data')
# __version__ attributes
import ctypes
print(ctypes.__version__) # DeprecationWarning
# Use sys.version_info
# Bitwise inversion on bools
result = ~True # DeprecationWarning (-2)
result = ~False # DeprecationWarning (-1)
# Use: not True, not False
🎓 Best Practices
1. Use Sampling Profiler in Production
# ✅ Profile senza impatto
# Attach al processo
python -m profiling.sampling --duration=60 <PID>
# Identifica bottleneck
# Fix senza restart
# Zero overhead
2. Always Specify Encoding
# ✅ Explicit encoding per compatibilità
# Buono
with open('file.txt', 'w', encoding='utf-8') as f:
f.write('Data')
# Evita
with open('file.txt', 'w') as f: # Implicit UTF-8
f.write('Data')
3. Use Async Paginator
# ✅ Per large datasets async
async def process_data():
paginator = AsyncPaginator(data, per_page=100)
async for item in paginator.aget_page(1):
await process_item(item)
4. Leverage Improved Error Messages
# ✅ Let Python guide you
# Python suggests:
# 'container.inner.area'
# 'abcde' instead of 'abcdf'
# Faster debugging!
💡 Conclusioni
Python 3.15 migliora debugging e internazionalizzazione:
✅ Sampling profiler fino a 1MHz ✅ UTF-8 di default cross-platform ✅ AsyncPaginator per large datasets ✅ AttributeError con nested suggestions ✅ math.isnormal() e nuove funzioni ✅ Warning filters con regex ✅ Color support in CLI tools
Upgrade oggi:
# Installa Python 3.15
# pyenv
pyenv install 3.15.0
pyenv global 3.15.0
# Or download from python.org
# https://www.python.org/downloads/
# Verifica versione
python --version # Python 3.15.0
Quando usare Python 3.15:
- ✅ Nuovi progetti
- ✅ Production profiling necessario
- ✅ Multi-platform UTF-8
- ✅ Async web applications
- ✅ Large dataset processing