Weblog

published Nov 03, 2021 , last modified Nov 04, 2021

Cheuk Ting Ho: Epic Evolution of Typing in Python: How We Get Here and Where Are We Going?

published Oct 17, 2025 , last modified Jan 22, 2026

Talk by Cheuk Ting Ho at Plone Conference 2025 in Jyväskylä, Finland.

Read about me: https://cheuk.dev

Question: What is the typing system of Python? Answer: Python is a dynamically typed language.

Strict typing can help avoid bugs, and make the expectations clearer.

Dynamically typed is good. It is easy to learn, faster to code if the code base is small, faster in runtime, makes for more flexible APIs, nice for prototypes.

Dynamically typed is bad. There are fewer signs of potential errors. A type mismatch will not raise an error until runtime. If the code base is big, it can be hard to maintain. Information about what input type works, needs then to be specified in documentation.

As Python grows, there are needs to overcome these disadvantages of dynamic typing. So Python evolved, and you can now use typing. A short history:

  • Before Python 3.5, there were already arbitrary annotations.
  • In Python 3.5, PEP 484: optional type hints, with the typing module added. This established gradual typing, giving space to gradually move code over to typing.
  • In Python 3.9, PEP 585: typing in the standard built-ins without always having to import typing; collection types.
  • In Python 3.12, PEP 695: type statement added. This introduces a first-class syntax for declaring type paremeters. It simplifies and clarifies.

But how can we achieve typing in Python? You can use type checkers. Static type checkers don't run your code: they just read it and check it that way. Examples: Mypy, Ty, Pyrefly. Dynamic validation: serializing complex data in runtime. Examples: Pydantic, Marshmallow.

Mypy is the reference implementation of PEP 484. Ty, Pyrefly and Pydantic (v2) are written in Rust, which improves the speed a lot.

Aroma Rodrigues: The limits of imagination

published Oct 17, 2025 , last modified Jan 22, 2026

Talk by Aroma Rodrigues at Plone Conference 2025 in Jyväskylä, Finland.

Historically we have all used computers mathematically, but now we get to use them linguistically. I will tell some stories of my work over time.

PyCon India: Terms and Conditions summarizer. You have an unreadable (for you) legal document. You get an email saying your rights have changed, but hardly anyone ever reads that. You could hire a lawyer, but I wanted to use a computer. Problem: no existing dataset. Approach: build a labeled dataset from scratch. Outcome: an NLP pipeline to extract obligations, permissions, and risks from such a doc. But the dataset was not really usable.

PyCon US 2024: Only bad demos in the building. With all the LLMs and AI, I was wondering what I would do if I could not keep my job? Maybe I could become a forensic portrait artist, so creating pictures of suspects of a robbery? I started experienting with giving a description of a man, and using an LLM to generate a picture. Kind of worked for some descriptions.

I also let an AI make a travelogue based on my photos. You run into things like the AI saying "I saw a car coming down the road" when I made the photo not for the car, but for the buildings.

Clothes matching: can AI do it? So picking out pieces of clothes that match nicely together. I got something together.

So basically, I can do anything!

PyCon-ZA 2019: NLP Fake News detector. There is improvement: today, LLMs offer richer context better understanding of blame dynamics, and scalable solutions. My source: 22M conversations from BuzzFeed on top 50 fake stories. Compare articles from spoof website and mainstream media. Use of fact-checking platforms like Alt News and SMHoaxSlayer. Looking for syntactic patterns, tagging statements to detect blame assignment, praise, event causality, active/passive voice patterning using nltk.RegExpParser.

PyCon Estonia 2023: If your friends are bullshitting, using SNLI. Goal: use LNP to spot contradictions in statements, proving when your friends are contradicting themselves. Check for two sentences: Entailment (they are roughly the same), contradition (they contradict), or neutrality (they are about something else).

I have lots more to tell, but time is up.

Patrik Lauha: Muuttolintujen Kevät - Automatic Bird Sound Classifier

published Oct 17, 2025 , last modified Jan 22, 2026

Patrik Lauha: Muuttolintujen Kevät - Automatic Bird Sound Classifier

LIFEPLAN project: international bio monitoring project, with DNA samples, camera traps, audio recordings. This is a huge amount of data.

Muuttolintujen Kevät (“Spring of migratory birds”) is a mobile application based citizen science campaign where citizens collect bird observations with help of an automated bird sound classifier of Finnish birds. You can download the app on your phone. Recordings are analyzed with AI model, which is trained to recognize the vocalizations of Finnish birds. You need a Finnish phone operator for the app to work.

You can also scroll through your old observations, see a list of species you have recorded. You see the confidence percentage of the bird recognition. Also a small game: listen and choose the correct bird.

We have more than 300 thousand users. This is 5 percent of the Finnish population! 16 million recordings. Most common species: common chaffinch, eurasian blue tit, great tit, common blackbird, willow warbler. So the people help us to collect data about birds in nature, without us having to install lots and lots of audio equipment.

We transform audio to a spectogram image. Why? Image recognition is really good. And it is natural to represent audio as an image. With audio you have about 48,000 tiny data points per second. Represented as image this is much less, but enough for the pattern to be recognizable. We use a short-time Fourier transform. See also https://bsg.laji.fi

We use TensorFlow and Keras in Python. Convolutional neural netword processes input audio in 3-second segments. Training data from global bird sounds library xeno-canto, Finnish field recordings, and our phone app. Trained for 263 Finnish bird species. Output is then for each species the likelyhood that there is a match.

We use data augmentation to avoid data overfitting, where the model would be really good at recognizing only the training data based on irrelevant details. In Python: Scipy, colorednoise, noisereduce.

With passive acoustic monitoring we record the whole day and can see what birds are most active in the early morning. With the data from citizens, we see most data a bit later in the morning, because people are asleep before, and another peak near the end of the day.

Ongoing research: with the app data:

  • Digital twinning and real-time bird forecasts. With the data we get really good predictions of when the migratory birds are coming and going. We can also show predictions of where and at which time you are most likely to hear your favorite bird, so you can be there.
  • Complementing the breeding bird atlas: https://lintuatlas.fi
  • Humanities / social sciences study of nature experience. In the app you can record your nature experience: tell how your surroundings look, how you feel, what you hear, smell, think. We don't know who is behind the recordings, so you should feel safe to use this part of the application.

For training we need a large computer. For classification we don't need much.

Plone Foundation Annual General Meeting

published Oct 17, 2025 , last modified Jan 22, 2026

Plone Foundation Annual General Meeting at Plone Conference 2025 in Jyväskylä, Finland.

Main goals the past year:

  • Strengthen the Plone Foundation. Push for more diversity in the community. We are a bit too much European, male, and white. And old? Google Summer of Code helps here. Some people travelled here by train, which is better for our carbon footprint. Have a straightforward sponsorship program. A document was drafted with a written list of requirements to organize a Plone conference or sprint. We try to find new funding sources. We are looking to establish an EU entity to reduce costs associated with financial transactions. We have better defined benefits and duties of Foundation membership. Align sprint funding with sponsorship commitments and the product roadmap, so the roadmap was aligned with the funding of sprints. A sprint should move the roadmap forward, but it is also important that it builds community. Ensure financial operations and transfer of the treasury, making the work of the treasurer future proof. Steve Piercy has stepped up for this, doing a lot of work figuring out the situation, making it clearer, make sure the treasurer has access to accounts where needed.
  • Empower the Plone community. More in-person events, like sprints. Thinking of ways to better train newcomers. have a clear and community-adopted roadmap, shared between Classic and Volto Teams. The PloneEdu Team was revamped. plone.org Dev Team and Content Team, relaunch planned for next year. Helped conference organizers with regular meetings. If you know some organisation that wants to throw money at an open source, Python, Javascript project, contact Steve and he will help you write a grant application.
  • Promote and market Plone. We had 8 new releases of Plone since last conference. We publish every sprint report. Improve plone.org SEO and metadata. Encouraging participation in community events: TuneUp days, sprints, World Plone Day, PloneConf. PloneGov-BR will organize a Plone Symposium in November.

We have new Foundation members. Currently 96 active members from 21 countries. 215 emeritus members. 3 pending.

  • Community and code. Every month meeting of the Steering Circle, led by Eric Steele. 21 active new contributors, and 4 for Zope. GSOC: 3 students joined, supported by 6 mentors. Thank you! We had 5 strategic sprints this year. Also Plone Tune-Ups each third Friday of the month. World Plone Day with 48 videos. We supported the Plone Conference 2025 organization.
  • Evangelism and outreach. CMS Garden. Plone Tagung. Some podcasts/videos. Sponsors: 6 premium, 4 standard, and a one-time 1000 dollar donation from the Frappe organisation. Plus individual sponsors via GitHub, which amounts to about 500 euro per month.

Board of Directors. We had four candidates for three seats on the next board. Elected have been Rikupekka Oksanen, Eric Brehault, and Gildardo Bautista. Thank you Mikel and Guido for their service on the board, they are stepping out now.

Alexander now "pulls a Sjoerd". That points to an old board member who always tried to end the meeting as soon as possible. Meeting adjourned.

Daniel Vahla: Preparing for a Free-Threaded Python World

published Oct 17, 2025 , last modified Jan 22, 2026

Talk by Daniel Vahla at Plone Conference 2025 and PyCon Finland in Jyväskylä, Finland.

Slides are here: https://pycon2025.vahla.fi

This is a recap on thread safety and synchronisation primitives. Python is going to a free-threaded model.

I am consultant at Mavericks Software, 7 years of Python experience.

Why does this talk matter? Python 3.14 has an opt-in with GIL-free builds, via python3.14t. True parallism means real race conditions. We need to protect ourselves in ways that the GIL (global interpreter lock) did for us.

Without synchronization, multiple threads can touch the same data.

Demo: game of throwing dice by three players, each in a separate thread. A player plays until they have 20 points. This goes wrong, only one of the three throws gets used for all three.

So we add a Lock. Only one thread can hold the lock at a time. Others wait until it is released. This works.

We can use RLock: Recursive locking. With a regular lock you cannot acquire the same lock twice in same thread. In our game we will say: if you roll 6, you can roll again. This needs the RLock.

Demo 3: semaphore. This is like a lock with a counter, allowing limited access. N threads can have access at the same time. For example used for connection pools, resource limits, rate limiting. In our game we will allow at most 2 players to play the game. On join, we acquire the semaphore, and when finished, we release it.

Demo 4: BoundedSemaphore. You may need a defensive semaphore. This is for bug detection. Semaphore can release more than acquired. For best practice: always use the BoundedSemaphore.

Demo 5: Event. A simple signal. A boolean flag. Threads can wait() for event. One thread callse set() to wake all. We use this in our game to wait until all threads have been created.

Demo 6: Condition. For complex coordination: a Wait plus Notify. wait() releases locks and blocks. notify() or notify_all() wakes the waiters. You should always use this in a while loop, to avoid spurious wakeups. Used for producer-consumer patterns. We will use this to wait for enough players to join.

Demo 7: Barrier. For Phase Sync. Cleaner than Condition for rounds. Created with a party count: Barrier(n). You can have optional action callbacks. Used for multi-phase algorithms, round-based games, synchronizing computational stages. We use it in our game to wait for 3 players and play 3 rounds. In the callback we will print that a new round has started.

Key takeaways:

  • GIL-free is here, opt-in
  • Thread safety is critical
  • Know your primitives, use the right tool for the job
  • Test now with python3.14t.
  • Always use BoundedSemaphore over Semaphore.
  • If you are not sure if something is safe, just use a Lock.