Planet Python
Last update: April 07, 2026 04:44 PM UTC
April 07, 2026
Python Engineering at Microsoft
Write SQL Your Way: Dual Parameter Style Benefits in mssql-python
Reviewed by: Sumit Sarabhai If you’ve been writing SQL in Python, you already know the debate: positional parameters (?) or named parameters (%(name)s)? Some developers swear by the conciseness of positional. Others prefer the clarity of named. With mssql-python, you no longer need to choose – we support both. We’ve added dual parameter style support to mssql-python, enabling both qmark and pyformat parameter styles in Python […]
The post Write SQL Your Way: Dual Parameter Style Benefits in mssql-python appeared first on Microsoft for Python Developers Blog.
Django Weblog
Django security releases issued: 6.0.4, 5.2.13, and 4.2.30
In accordance with our security release policy, the Django team is issuing releases for Django 6.0.4, Django 5.2.13, and Django 4.2.30. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.
Django 4.2 has reached the end of extended support
Note that with this release, Django 4.2 has reached the end of extended support. All Django 4.2 users are encouraged to upgrade to Django 5.2 or later to continue receiving fixes for security issues.
See the downloads page for a table of supported versions and the future release schedule.
CVE-2026-3902: ASGI header spoofing via underscore/hyphen conflation
ASGIRequest normalizes header names following WSGI conventions, mapping hyphens to underscores. As a result, even in configurations where reverse proxies carefully strip security-sensitive headers named with hyphens, such a header could be spoofed by supplying a header named with underscores.
Under WSGI, it is the responsibility of the server or proxy to avoid ambiguous mappings. (Django's runserver was patched in CVE-2015-0219.) But under ASGI, there is not the same uniform expectation, even if many proxies protect against this under default configuration (including nginx via underscores_in_headers off;).
Headers containing underscores are now ignored by ASGIRequest, matching the behavior of Daphne, the reference server for ASGI.
This issue has severity "low" according to the Django Security Policy.
Thanks to Tarek Nakkouch for the report.
CVE-2026-4277: Privilege abuse in GenericInlineModelAdmin
Add permissions on inline model instances were not validated on submission of forged POST data in GenericInlineModelAdmin.
This issue has severity "low" according to the Django Security Policy.
Thanks to N05ec@LZU-DSLab for the report.
CVE-2026-4292: Privilege abuse in ModelAdmin.list_editable
Admin changelist forms using ModelAdmin.list_editable incorrectly allowed new instances to be created via forged POST data.
This issue has severity "low" according to the Django Security Policy.
CVE-2026-33033: Potential denial-of-service vulnerability in MultiPartParser via base64-encoded file upload
When using django.http.multipartparser.MultiPartParser, multipart uploads with Content-Transfer-Encoding: base64 that include excessive whitespace may trigger repeated memory copying, potentially degrading performance.
This issue has severity "moderate" according to the Django Security Policy.
Thanks to Seokchan Yoon for the report.
CVE-2026-33034: Potential denial-of-service vulnerability in ASGI requests via memory upload limit bypass
ASGI requests with a missing or understated Content-Length header could bypass the DATA_UPLOAD_MAX_MEMORY_SIZE limit when reading HttpRequest.body, potentially loading an unbounded request body into memory and causing service degradation.
This issue has severity "low" according to the Django Security Policy.
Thanks to Superior for the report.
Affected supported versions
- Django main
- Django 6.0
- Django 5.2
- Django 4.2
Resolution
Patches to resolve the issue have been applied to Django's main, 6.0, 5.2, and 4.2 branches. The patches may be obtained from the following changesets.
CVE-2026-3902: ASGI header spoofing via underscore/hyphen conflation
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 4.2 branch
CVE-2026-4277: Privilege abuse in GenericInlineModelAdmin
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 4.2 branch
CVE-2026-4292: Privilege abuse in ModelAdmin.list_editable
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 4.2 branch
CVE-2026-33033: Potential denial-of-service vulnerability in MultiPartParser via base64-encoded file upload
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 4.2 branch
CVE-2026-33034: Potential denial-of-service vulnerability in ASGI requests via memory upload limit bypass
- On the main branch
- On the 6.0 branch
- On the 5.2 branch
- On the 4.2 branch
The following releases have been issued
- Django 6.0.4 (download Django 6.0.4 | 6.0.4 checksums)
- Django 5.2.13 (download Django 5.2.13 | 5.2.13 checksums)
- Django 4.2.30 (download Django 4.2.30 | 4.2.30 checksums)
The PGP key ID used for this release is Jacob Walls: 131403F4D16D8DC7
General notes regarding security reporting
As always, we ask that potential security issues be reported via private email to security@djangoproject.com, and not via Django's Trac instance, nor via the Django Forum. Please see our security policies for further information.
Real Python
Using Loguru to Simplify Python Logging
Learn how to use Loguru for simpler Python logging, from zero-config setup and custom formats to file rotation, retention, and adding context.
Django Weblog
Could you host DjangoCon Europe 2027? Call for organizers
We are looking for the next group of organizers to own and lead the 2027 DjangoCon Europe conference. Could your town's football stadium, theatre, cinema, city hall, circus tent or a private island host this wonderful community event?
DjangoCon Europe is a major pillar of the Django community, as people from across the world meet and share. Many qualities make it a unique event: Unconventional and conventional venues, creative happenings, a feast of talks and a dedication to inclusion and diversity.
Hosting a DjangoCon is an ambitious undertaking. It's hard work, but each year it has been successfully run by a team of community volunteers, not all of whom have had previous experience - more important is enthusiasm, organizational skills, the ability to plan and manage budgets, time and people - and plenty of time to invest in the project.
For 2027, rest assured that we will be there to answer questions and put you in touch with previous organizers through the brand new DSF Events Support Working Group (a reboot of the previous DjangoCon Europe Support Working Group).
Step 1: Submit your expression of interest
If you're considering organizing DjangoCon Europe (🙌 great!), fill in our DjangoCon Europe 2027 expression of interest form with your contact details. No need to fill in all the information at this stage if you don't have it all already, we'll reach out and help you figure it out.
Express your interest in organizing
Step 2: We're here to help!
We've set up a DjangoCon Europe support working group of previous organizers that you can reach out to with questions about organizing and running a DjangoCon Europe.
The group will be in touch with everyone submitting the expression of interest form, or you can reach out to them directly: events-support@djangoproject.com
We'd love to hear from you as soon as possible, so your proposal can be finalized and sent to the DSF board by June 1st 2026.
Step 3: Submitting the proposal
The more detailed and complete your final proposal is, the better. Basic details include:
- Organizing committee members: You won't have a full team yet, probably, naming just some core team members is enough.
- The legal entity that is intended to run the conference: Even if the entity does not exist yet, please share how you are planning to set it up.
- Dates: See "What dates are possible in 2027?" below. We must avoid conflicts with major holidays, EuroPython, DjangoCon US, and PyCon US.
- Venue(s), including size, number of possible attendees, pictures, accessibility concerns, catering, etc.
- Transport links and accommodation: Can your venue be reached by international travelers?
- Budgets and ticket prices: Talk to the DjangoCon Europe Support group to get help with this, including information on past event budgets.
We also like to see:
- Timelines
- Pictures
- Plans for online participation, and other ways to make the event more inclusive and reduce its environmental footprint
- Draft agreements with providers
- Alternatives you have considered
Have a look at our proposed (draft, feedback welcome) DjangoCon Europe 2027 Licensing Agreement for the fine print on contractual requirements and involvement of the Django Software Foundation.
Submit your completed proposal by June 1st 2026 via our DjangoCon Europe 2027 expression of interest form, this time filling in as many fields as possible. We look forward to reviewing great proposals that continue the excellence the whole community associates with DjangoCon Europe.
Q&A
Can I organize a conference alone?
We strongly recommend that a team of people submit an application.
I/we don't have a legal entity yet, is that a problem?
Depending on your jurisdiction, this is usually not a problem. But please share your plans about the entity you will use or form in your application.
Do I/we need experience with organizing conferences?
The support group is here to help you succeed. From experience, we know that many core groups of 2-3 people have been able to run a DjangoCon with guidance from previous organizers and help from volunteers.
What is required in order to announce an event?
Ultimately, a contract with the venue confirming the dates is crucial, since announcing a conference makes people book calendars, holidays, buy transportation and accommodation etc. This, however, would only be relevant after the DSF board has concluded the application process. Naturally, the application itself cannot contain any guarantees, but it's good to check concrete dates with your venues to ensure they are actually open and currently available, before suggesting these dates in the application.
Do we have to do everything ourselves?
No. You will definitely be offered lots of help by the community. Typically, conference organizers will divide responsibilities into different teams, making it possible for more volunteers to join. Local organizers are free to choose which areas they want to invite the community to help out with, and a call will go out through a blog post announcement on djangoproject.com and social media.
What kind of support can we expect from the Django Software Foundation?
The DSF regularly provides grant funding to DjangoCon organizers, to the extent of $6,000 in recent editions. We also offer support via specific working groups:
- The dedicated DjangoCon Europe support working group.
- The social media working group can help you promote the event.
- The Code of Conduct working group works with all event organizers.
In addition, a lot of Individual Members of the DSF regularly volunteer at community events. If your team aren't Individual Members, we can reach out to them on your behalf to find volunteers.
What dates are possible in 2027?
For 2027, DjangoCon Europe should happen between January 4th and April 26th, or June 3rd and June 27th. This is to avoid the following community events' provisional dates:
- PyCon US 2027: May 2027
- EuroPython 2027: July 2027
- DjangoCon US 2027: September - October 2027
- DjangoCon Africa 2027: August - September 2027
We also want to avoid the following holidays:
- New Year's Day: Friday 1st January 2027
- Chinese New Year: Saturday 6th February 2027
- Eid Al-Fitr: Tuesday 9th March 2027
- Easter: Sunday 28th March 2027
- Passover: Wednesday 21st - Thursday 29th April 2027
- Eid Al-Adha: Monday 17th - Thursday 20th May 2027
- Rosh Hashanah: Saturday 2nd - Monday 4th October 2027
- Yom Kippur: Monday 11th - Tuesday 12th October 2027
What cities or countries are possible?
Any city in Europe. This can be a city or country where DjangoCon Europe has happened in the past (Athens, Vigo, Edinburgh, Porto, Copenhagen, Heidelberg, Florence, Budapest, Cardiff, Toulon, Warsaw, Zurich, Amsterdam, Berlin), or a new locale.
References
Past calls
- Interested in organizing DjangoCon Europe 2016? | Weblog | Django
- Could you host DjangoCon Europe 2017? | Weblog | Django
- DjangoCon Europe 2019 - where will it be? | Weblog | Django
- Could you host DjangoCon Europe 2023? | Weblog | Django
- Last Chance for a DjangoCon Europe 2023 | Weblog | Django
- Want to host DjangoCon Europe 2024? | Weblog | Django
- DjangoCon Europe 2025 Call for Proposals | Weblog | Django
- Last call for DjangoCon Europe 2025 organizers | Weblog | Django
- Could you host DjangoCon Europe 2026? Call for organizers | Weblog | Django
Real Python
Quiz: Building a Python GUI Application With Tkinter
Test your Tkinter skills with this interactive challenge on widgets, layouts, event loops, and text/file handling in Python GUIs.
Quiz: Using Loguru to Simplify Python Logging
Test your knowledge of Loguru for Python logging, from zero-config setup and log levels to custom formats and adding context.
PyCharm
How to Train Your First TensorFlow Model in PyCharm
This is a guest post from Iulia Feroli, founder of the Back To Engineering community on YouTube. TensorFlow is a powerful open-source framework for building machine learning and deep learning systems. At its core, it works with tensors (a.k.a multi‑dimensional arrays) and provides high‑level libraries (like Keras) that make it easy to transform raw data […]
PyCon
Stories from the PyCon US Hotels
April 06, 2026
ListenData
How to Use Gemini API in Python
PyCon
Python and the Future of AI: Agents, Inference, and Edge AI
Trey Hunner
Using a ~/.pdbrc file to customize the Python Debugger
Real Python
D-Strings Could End Your textwrap.dedent() Days and Other Python News for April 2026
D-strings proposed to kill textwrap.dedent(), Python 3.15 alpha 7 ships lazy imports, GPT-5.4 launches, and Python Insider moves home.
Quiz: For Loops in Python (Definite Iteration)
Test your understanding of Python loops, iterables, and control flow with break, continue, and StopIteration.
Python Bytes
#476 Common themes
Topics include Migrating from mypy to ty: Lessons from FastAPI, Oxyde ORM, Typeshedded CPython docs, and Raw+DC Database Pattern: A Retrospective.
April 05, 2026
EuroPython
Humans of EuroPython: George Zisopoulos
Behind every flawless talk, engaging workshop, and perfectly timed coffee break at EuroPython is a crew of unsung heroes—our volunteers! 🌟 Today we’d like to introduce George Zisopoulos, member of the Operations team at EuroPython 2025.
April 04, 2026
Marcos Dione
Correcting OpenStreetMap wrong tag values
As a hobbyist consumer of OSM data to render maps, I find wrong tags annoying. Bad values mean that the resulting map is wrong or incomplete, so less useful. I decided to attack the most egregious ones, which include typos, street names instead of type and some other errors. The idea is to attack the long tail first, so I'm not blocked because the next batch of errors (objects with exactly the same error) looks too big (yes, OCD).
So I hacked a small python script to help me find and edit them:
#! /usr/bin/env python3 import os import psycopg2 def main(): db = psycopg2.connect(dbname='europe') cursor = db.cursor() cursor.execute(''' SELECT count(*) AS count, highway FROM planet_osm_line WHERE highway IS NOT NULL GROUP BY highway ORDER BY count ASC ''') data = cursor.fetchall() for count, highway in data: print(f"next {count}: {highway}") cursor.execute(''' SELECT osm_id FROM planet_osm_line WHERE highway = %s ''', (highway, )) for (osm_id, ) in cursor.fetchall(): if osm_id < 0: # in rendering DBs, this is a relation os.system(f"librewolf -P default 'https://www.openstreetmap.org/edit?relation={-osm_id}'") else: os.system(f"librewolf -P default 'https://www.openstreetmap.org/edit?way={osm_id}'") if __name__ == '__main__': main()
It is quite inefficient, but what I want is to edit the errors, not to write a script :) This requires a rendering database, which I already have locally :)
From here the workflow is:
- Analyze the type of error.
- This includes looking at the history of the object.
- Search the wiki.
- Correct the error or leave a note.
- Find the original changeset and leave a note if needed.
- Add any details to te changeset if needed.
In my machine, finding the long tail, and finding each set of errors takes one minute, so I was launching two at the same time. One of the things to notice is that if the object you try to edit does no exists anymore, you get and edit view of the whole planet.
Armin Ronacher
Absurd In Production
April 03, 2026
PyCon
¡Haciendo Historia! Celebrating PyCon US’s First-Ever Spanish-Language Keynote
Real Python
Quiz: How to Add Features to a Python Project With Codex CLI
Test your knowledge of Codex CLI, the AI-powered terminal tool for adding features to Python projects with natural language.
Quiz: Class Concepts: Object-Oriented Programming in Python
Test your understanding of Python classes, attributes, methods, properties, and the descriptor protocol.
Rodrigo Girão Serrão
Indexable iterables
Learn how objects are automatically iterable if you implement integer indexing.
Introduction
An iterable in Python is any object you can traverse through with a for loop.
Iterables are typically containers and iterating over the iterable object allows you to access the elements of the container.
This article will show you how you can create your own iterable objects through the implementation of integer indexing.
Indexing with __getitem__
To make an object that can be indexed you need to implement the method __getitem__.
As an example, you'll implement a class ArithmeticSequence that represents an arithmetic sequence, like \(5, 8, 11, 14, 17, 20\).
An arithmetic sequence is defined by its first number (\(5\)), the step between numbers (\(3\)), and the total number of elements (\(6\)).
The sequence \(5, 8, 11, 14, 17, 20\) is seq = ArithmeticSequence(5, 3, 6) and seq[3] should be \(14\).
Using some arithmetic, you can implement indexing in __getitem__ directly:
class ArithmeticSequence:
def __init__(self, start: int, step: int, total: int) -> None:
self.start = start
self.step = step
self.total = total
def __getitem__(self, index: int) -> int:
if not 0 <= index < self.total:
raise IndexError(f"Invalid index {index}.")
return self.start + index * self.step
seq = ArithmeticSequence(5, 3, 6)
print(seq[3]) # 14
Turning an indexable object into an iterable
If your object accepts integer indices, then it is automatically an iterable.
In fact, you can already iterate over the sequence you created above by simply using it in a for loop:
for value in seq:
print(value, end=", ")
# 5, 8, 11, 14, 17, 20,
How Python distinguishes iterables from non-iterables
You might ask yourself “how does Python inspect __getitem__ to see it uses numeric indices?”
It doesn't!
If your object implements __getitem__ and you try to use it as an iterable, Python will try to iterate over it.
It either works or it doesn't!
To illustrate this point, you can define a class DictWrapper that wraps a dictionary and implements __getitem__ by just grabbing the corresponding item out of a dictionary:
class DictWrapper:
def __init__(self, values):
self.values = values
def __getitem__(self, index):
return self.values[index]
Since DictWrapper implements __getitem__, if an instance of DictWrapper just happens to have some integer keys (starting at 0) then you'll be able to iterate partially over the dictionary:
d1 = DictWrapper({0: "hey", 1: "bye", "key": "value"})
for value in d1:
print(value)
hey
bye
Traceback (most recent call last):
File "<python-input-25>", line 3, in <module>
for value in d1:
^^
File "<python-input-18>", line 6, in __getitem__
return self.values[index]
~~~~~~~~~~~^^^^^^^
KeyError: 2
What's interesting is that you can see explicitly that Python tried to index the object d with the key 2 and it didn't work.
In the ArithmeticSequence above, you didn't get an error because you raised IndexError when you reached the end and that's how Python understood the iteration was done.
In this case, since you get a KeyError, Python doesn't understand what's going on and just...
Talk Python Blog
Announcing Course Completion Certificates
I’m very excited to share that you can now generate course completion certificates automatically at Talk Python Training. What’s even better is our certificates allow you to one-click add them as official licenses and certifications on LinkedIn.
Remember last week, I added some really nice features to your account page showing which courses are completed and which ones you’ve recently participated in. Just start there. Find a course you recently completed, click certificate, and there is a Share to LinkedIn UI right there. It’s nearly entirely automated.
ListenData
How to Build ChatGPT Clone in Python
How to Use Web Search in ChatGPT API
4 Ways to Use ChatGPT API in Python
