EuroPython: EuroPython April 2023 Newsletter

Planet Python - Thu, 2023-05-11 05:51

Hey there 👋

With less than 70 days left until we gather together in Prague for EuroPython, here’s what’s been going on.

📣 Programme

Thank you to everyone who contributed to our community voting and a special thanks to our team of 35 reviewers, who provided over 1000 reviews on the proposals! Without their help, it would not be possible to create the EuroPython programme and there wouldn’t be a conference to attend.

Our wonderful programme team has been hard at work and sent most of our acceptance letters to our speakers! Please get your acceptance tweets and emails ready! We hope to publish the list of accepted talks within the next few days!

🏃 Sprints

We are delighted to announce  our sprint weekend will be held at VŠE (Prague University of Economics and Business) on 22-23 July. Sprints are free to attend and open to the public (registration to be announced later for those who do not have a conference ticket). The sprints are a great way to learn from each other, share knowledge and ideas, and solve problems together through the medium of Python.

Find out more details and how to propose a sprint here: https://ep2023.europython.eu/sprints

🌟 Keynote

We have a couple more awesome keynoters lined up!!

Ines Montani

Ines Montani is a developer specialising in tools for AI and natural language processing (NLP) technology.

She’s the co-founder and CEO of Explosion, a core developer of spaCy, a popular open-source library for Natural Language Processing in Python, and Prodigy, a modern annotation tool for creating training data for machine learning models.

Ines, who had already keynoted EuroPython five years ago, will share with us the developments, progress and lessons learned in the field of natural language processing. It&aposll be an opportunity for us to collectively retrospect on half a decade of work in the Python community within a field that is gaining in popularity and momentum.

(Ines owning the stage in her keynote at EuroPython 2018)Petr Viktorin

Petr works at Red Hat, integrating Python into Linux distros.

He started contributing to Python in 2015, answering Nick Coghlan&aposs call for a volunteer to improve extension module loading. After about six PEPs and eight years of work, that project expanded to better support for subinterpreters and maintaining the stable ABI, and helping Eric Snow&aposs effort to break up the GIL.

Last year, after a nomination for Steering Council forced him to look at parts of the project that needed help, Petr revived the Documentation community, and spent time removing roadblocks from contributing to Python&aposs documentation.

To give back to the community, he started teaching free courses to local beginners. But that is a story for his talk at EuroPython.

🎫 Ticket Sales

Our tickets are up for sale now and we’re seeing a strong and steady trend in ticket purchases. Please book your ticket now, to avoid disappointment later when they all (inevitably) sell out.

Tickets can be purchased on our website: https://ep2023.europython.eu/tickets

💶 Financial Aid

Submissions for the first round of our financial aid programme have closed. With over 125 applications from over 40 countries, we&aposre calling this a huge success. The financial aid team is currently reviewing the applications and will send out grant approval notifications by 8 May 2023 at the latest.

You can still apply for the second round of the financial aid programme. The deadline for submitting your application is 21 May 2023. If you’ve applied for a grant in round one but did not receive one, you don’t have to submit another application. Your application will automatically be considered in round two.

Visit https://europython.eu/finaid for information on how to apply for a financial aid grant.

💸  Sponsorship

We&aposre thrilled to announce that our Platinum sponsorship packages for EuroPython 2023 have all been sold out! We&aposre incredibly grateful for the support of our sponsors and are looking forward to an amazing event.

Thank you to all our sponsors for supporting EuroPython 2023!

We still have other exciting sponsorship opportunities available which come with a range of benefits.

Check out our website for more information on the available packages at https://ep2023.europython.eu/sponsor

🗣️ Speaker Placement Programme

Our speaker placement programme supports those in our community who would like advice, guidance and friendly support while preparing for their contribution to EuroPython.

Happy news! Our first two mentees have been matched with an organiser of their choice. Now they will have the opportunity to be connected with a local community, present their talks and get more involved in new activities.

For more information about the Speaker Placement Programme please check here: https://ep2023.europython.eu/mentorship#3-speaker-placement-programme

🎤 First-Time Speaker’s Workshop

In this event, we&aposll have experienced speakers from the EuroPython community to share their know-how on delivering an effective talk. We hope this will help our participants learn something meaningful about public speaking before their presentation at EuroPython 2023 or in general.

The workshop will take place on 1st of June 2023 at 18.00 CET via Zoom (details will be communicated in the coming weeks). A recording of the session will be made available after the event.

⚖️ The new Cyber Resilience Act proposal

While we welcome the intention of strengthening software and digital products’ cyber security by the European Union’s proposed Cyber Resilience Act (CRA) and Product Liability Act , we echo the concerns the PSF have in its potentially unintended consequences of putting the health of open-source software at risk, including Python and PyPI.

Please check out this blog post for details. If you too are concerned that the broad language of the proposed acts could make open source organisations and developers held liable for security flaws of commercial products that incorporate open source codes, then consider writing to your MEP voicing concerns and asking for clarifications about the proposed CRA law.

💥 Project Feature - Ruff

Ruff is an extremely fast Python linter, written in Rust.

In the landscape of python tooling there often comes a tool that creates a paradigm shift,  Ruff is such a tool! there are tons of linters in Python like flake8, pylint, pycodestyle, yapf etc but ruff just beats it out of the park by being 10-100x faster than existing linters and having integrations with dozens of existing Flake8 plugins. Its speed and versatility has driven adoption in major OSS projects like Apache Airflow, FastAPI, Pandas and Scipy.

Check out Ruff on: https://github.com/charliermarsh/ruff

🍿 EuroPython Classics

EuroPython’s history is full of amazing talks, entertaining presentations and thought provoking interactions… many of which can be found on our YouTube channel. These historic and important artefacts of our European Python community are a source of much wisdom, learning and community bonding. So we want you to suggest your “EuroPython Classic” from our archives.

Our inaugural suggestion comes from Shekhar: “Simple data validation and setting management with Pydantic” by Teddy Crepineau.

Shekhar explains, “Pydantic is a must-have for every Python project, and when combined with Ruff, the result is simply awesome!”

We would love to hear your suggestions for EuroPython classics., so share those bookmarked talks by tagging us on our socials @europython or email comms@europython.eu. We’d love to know why you think your suggested talk is a classic.

Let’s celebrate, recognise and learn again from those hidden gems in our archive.

🥸 PyJok.es$ pip install pyjokes Collecting pyjokes Downloading pyjokes-0.6.0-py2.py3-none-any.whl (26 kB) Installing collected packages: pyjokes Successfully installed pyjokes-0.6.0 $ pyjoke What do you call eight hobbits? A hobbyte.

Add your own jokes to PyJokes (a project invented at a EuroPython sprint) via this issue: https://github.com/pyjokes/pyjokes/issues/10

Categories: FLOSS Project Planets

Value Semantics

Planet KDE - Thu, 2023-05-11 05:00

C++ is an old language. Many aspects of our programming styles have become habits that we do not think about too much today. In this blog, I’m going to address one major issue that has resulted from such habits and get you prepared for a new bright world of C++2b. So without further ado, let’s dive!

Identifying a Problem

There is a problem that we don’t want to face. It’s called reference semantics. Reference semantics tells us that the variable is referenced by one or more places in code, like a crossroads, leading to a center of the city. Let’s address an elephant in the room: the global variable.

You probably already know that the global variable is a big no-no in the C++ community because the prediction of the state of a global variable is borderline impossible, if it’s writable and readable. If the code is concurrent, it becomes a big pain to synchronize all the ins and outs to make it work.

Thus, global variables are frowned upon. Though we’ve become pretty good at replacing them with other things, the issue still exists within references. The global variable is, in its core, a reference to memory that is globally allocated. It has a way to be addressed from any point in code, adding roads to the crossroads of reference semantics. It’s the same as a reference or a pointer to something, just on a larger scale.

So, what’s the cost of it? Upon expansion, programs become more coupled and fragile, accumulating technical debt. Removing a global variable from a program is hard, but the same goes for anything that is shared or pointed to in a non-unique manner.

We are not going to tackle all the problems the reference semantics cause today. Instead, we’ll move on to and focus on function calls.

Call Safe, Not Fast.

Why focus on functions? Because we need to specify the guarantees that we, as programmers, give to our library users.

First, let’s define some common value semantics rules for easier understanding.

Those rules are:

  1. Regularity: the state of an object is equivalent to its copy.
  2. Independence: the state of an object remains constant for the local scope and can be changed only by a local scope.

Those give us the following conditions:

  • Values can’t be written by operations on other values.
  • Writing the value does not affect other values.

Let’s look at an example:

void add(int& a, const int&b){ a+=b; } void add2(int& a, const int&b){ add(a,b); add(a,b); } int main(){ int x = 10; add2(x,x); return x; }

Even if it is somewhat artificial, can you guess what the output will be? If you said 40, congratulations!

But why is it 40? Add adds const& b to a. So the first time, it should be 20 and, the second time, it’s 30! Well, we passed x as a const reference, even though its const didn’t give any guarantee that the value is not going to change by external factors. So const& is not const enough.

Even if we designed and documented the usage of the function, the model of human thinking ignores the possibility of overlapping values. Additionally, the documentation often does not help with that, since we assume the library user knows that already.

The solution would be to pass the ints by value and return them by value, thus fulfilling the value semantics rules.

But what about for larger types? For those, the possible solutions would be to wrap them in the unique pointer and return it or use std::inout_ptr from C++23. Move semantics help us in that regard.


We’ve looked at the problems with data coherency. Now, let’s talk about lifetimes. Assume we have a function:

auto f(const std::vector<int>& vec, class SomeClass& to_fill);

We know that data isn’t overlapping and “to_fill” is not modifying the vec in any circumstance. But still, there is a phantom menace lurking around. Let’s define some words about function execution:
the function gives strong guarantee of execution if the selected scenario of execution provides strong lifetime to its arguments and the internal state of the function. Basically, it’s a way to say that on current execution will not result in UB under any conditions.

int main() { SomeClass c; std::array<int, 4> arr{1,2,3,4}; f(arr, c); }

This call is strong because the lifetimes of the objects extend beyond function call.

But now, what if the function “f” is asynchronous, either a regular async function or a coroutine?

Task f(const std::vector<int>& vec, class SomeClass& to_fill) { co_await resume_on_threadpool(); // Do some expensive calculations }

Now this function returns immediately after resume_on_threadpool() is called. Suddenly, all the objects are destroyed, even before the execution is finished. Now, references and reference semantics become a big evil. Because we can’t guarantee the lifetimes of objects, function becomes weak and, if not executed within synchronous context or not “co_await”ed upon, may and probably will result in UB.

This is where value semantics come to the rescue at last! We can change vector& to vector itself and move in the value.

But what should we do with the class here? If we assume it comes from another part of a program that has it instantiated, the best bet is to use smart pointers.

Task<std::unique_ptr<SomeClass>> f( std::vector<int> vec, std::unique_ptr<SomeClass>> to_fill );

Now the execution is ensured to run safely.


Value semantics is a great tool for ensuring the stability of your code. Use it sparingly, because C++ is eagerly copying everything you pass into functions, sometimes resulting in performance loss.

Because asynchronous programming is coming towards us at an astonishing speed with coroutines, we need to consider the correct behavior and the lifetime of arguments for more use cases.

Thank you for reading. There is much more I could share, but this would quickly become an unusually long blog if I were to share it all here. Stay tuned for more advanced C++ in the future.

About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

The post Value Semantics appeared first on KDAB.

Categories: FLOSS Project Planets

Python Bytes: #335 Should you get your mojo on?

Planet Python - Thu, 2023-05-11 04:00
<a href='https://www.youtube.com/watch?v=uPb7l9vDc_Y' style='font-weight: bold;'>Watch on YouTube</a><br> <br> <p><strong>About the show</strong></p> <p>Sponsored by <a href="https://pythonbytes.fm/influxdata"><strong>InfluxDB</strong></a> from Influxdata.</p> <p><strong>Connect with the hosts</strong></p> <ul> <li>Michael: <a href="https://fosstodon.org/@mkennedy"><strong>@mkennedy@fosstodon.org</strong></a></li> <li>Brian: <a href="https://fosstodon.org/@brianokken"><strong>@brianokken@fosstodon.org</strong></a></li> <li>Show: <a href="https://fosstodon.org/@pythonbytes"><strong>@pythonbytes@fosstodon.org</strong></a></li> </ul> <p>Join us on YouTube at <a href="https://pythonbytes.fm/stream/live"><strong>pythonbytes.fm/live</strong></a> to be part of the audience. Usually Tuesdays at 11am PT. Older video versions available there too.</p> <p><strong>Michael #1:</strong> <a href="https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/"><strong>Introducing 'Trusted Publishers’</strong></a></p> <ul> <li>PyPI package maintainers can adopt a new, more secure publishing method that does not require long-lived passwords or API tokens to be shared with external systems.</li> <li>Our term for using the <a href="https://openid.net/connect/">OpenID Connect (OIDC)</a> standard to exchange short-lived identity tokens between a trusted third-party service and PyPI.</li> <li>Instead, PyPI maintainers can configure PyPI to trust an identity provided by a given OpenID Connect Identity Provider (IdP).</li> <li>These API tokens <ul> <li>never need to be stored or shared</li> <li>rotate automatically by expiring quickly</li> <li>provide a verifiable link between a published package and its source</li> </ul></li> <li>Additional security hardening is available</li> </ul> <p><strong>Brian #2:</strong> <a href="https://www.modular.com/mojo"><strong>Mojo : a new programming language for all AI developers.</strong></a></p> <ul> <li><a href="https://www.fast.ai/posts/2023-05-03-mojo-launch.html">Mojo may be the biggest programming language advance in decades</a> - fast.ai blog</li> <li>Suggested by many listeners</li> <li>“Mojo combines the usability of Python with the performance of C, unlocking unparalleled programmability of AI hardware and extensibility of AI models.”</li> <li>A programming language compatible with Python, with performance similar to C++/Rust.</li> <li>“Mojo is designed <strong>to become</strong> a superset of Python over time by preserving Python’s dynamic features while adding new primitives for systems programming.” - emphasis from Brian <ul> <li>It’s not there yet, but still super cool</li> </ul></li> <li>Built on a MLIR, not LLVM</li> <li>“<strong>How compatible is Mojo with Python really?</strong> <ul> <li>Mojo already supports many core features of Python including async/await, error handling, variadics, etc, but… it is still very early and missing many features - so today it isn’t very compatible. Mojo doesn’t even support classes yet!”</li> </ul></li> </ul> <p><strong>Michael #3:</strong> <a href="https://github.com/withlogicco/django-prose">django-prose</a></p> <ul> <li>Wonderful rich-text editing for your Django project.</li> <li><a href="https://github.com/withlogicco/django-prose#rendering-rich-text-in-templates">Rendering rich-text in templates</a></li> <li><a href="https://github.com/withlogicco/django-prose#small-rich-text-content">Small rich-text content</a> (as model fields)</li> <li>Django Prose is using <a href="https://bleach.readthedocs.io/en/latest/">Bleach</a> to only allow certain tags and attributes</li> <li>See the website for a screenshot of it in action</li> </ul> <p><strong>Brian #4:</strong> <a href="https://github.com/mtshiba/pylyzer"><strong>pylyzer</strong></a> <a href="https://github.com/mtshiba/pylyzer"><strong>is a static code analyzer / language server for Python, written in Rust.</strong></a></p> <ul> <li>Shunsuke Shibayama</li> <li>Suggested by <a href="https://fosstodon.org/@owenrlamont">Owen</a></li> <li>Features <ul> <li>fast </li> <li>detailed analysis <ul> <li>type checking</li> <li>plus things like out-of-bounds accesses to lists, and non-existent key references to dicts</li> </ul></li> <li>more readable reports</li> <li>and a VS Code extension</li> </ul></li> <li>pylyzer vs ruff <ul> <li>“<a href="https://github.com/charliermarsh/ruff">Ruff</a>, like pylyzer, is a static code analysis tool for Python written in Rust, but Ruff is a linter and pylyzer is a type checker &amp; language server. pylyzer does not perform linting, and Ruff does not perform type checking.”</li> </ul></li> <li>Some limitations and incomplete “todo list”. See README for more details.</li> </ul> <p><strong>Joke:</strong> <a href="https://twitter.com/arthur_rio/status/1651272804460032000">Escape Room</a></p>
Categories: FLOSS Project Planets

The Drop Times: Drupal Takes a Step Forward in Accessibility with Automated Testing Integration

Planet Drupal - Thu, 2023-05-11 03:27
The history of working to implement automated accessibility checks for Core goes back to 2017, shortly after a few open source accessibility tools were released. Deque’s axe-core had been released two years earlier, and it was starting to get embedded in a variety of other systems.
Categories: FLOSS Project Planets

Dropsolid Experience Agency: Drupal 7's End-of-Life extended to November 2023

Planet Drupal - Thu, 2023-05-11 02:29
Instead of a Drupal 7 exit with a hard end-of-life date in November 2022, the Drupal Community decided yesterday to postpone this date to November 2023.
Categories: FLOSS Project Planets

Shirish Agarwal: India Press freedom, Profiteering, AMD issues in the wild.

Planet Debian - Thu, 2023-05-11 02:17
India Press Freedom

Just about a week back, India again slipped in the Freedom index, this time falling to 161 out of 180 countries. The RW again made lot of noise as they cannot fathom why it has been happening so. A recent news story gives some idea. Every year NCRB (National Crime Records Bureau) puts out its statistics of crimes happening across the country. The report is in public domain. Now according to report shared, around 40k women from Gujarat alone disappeared in the last five years. This is a state where BJP has been ruling for the last 30 odd years. When this report became viral, almost all national newspapers the news was censored/blacked out. For e.g. check out newindianexpress.com, likewise TOI and other newspapers, the news has been 404. The only place that you can get that news is in minority papers like siasat. But the story didn’t remain till there. While the NCW (National Commission of Women) pointed out similar stuff happening in J&K, Gujarat Police claimed they got almost 39k women back. Now ideally, it should have been in NCRB data as an addendum as the report can be challenged. But as this news was made viral, nobody knows the truth or false in the above. What BJP has been doing is whenever they get questioned, they try to muddy the waters like that. And most of the time, such news doesn’t make to court so the party gets a freebie in a sort as they are not legally challenged. Even if somebody asks why didn’t Gujarat Police do it as NCRB report is jointly made with the help of all states, and especially with BJP both in Center and States, they cannot give any excuse. The only excuse you see or hear is whataboutism unfortunately

Profiteering on I.T. Hardware

I was chatting with a friend yesterday who is an enthusiast like me but has been more alert about what has been happening in the CPU, motherboard, RAM world. I was simply shocked to hear the prices of motherboards which are three years old, even a middling motherboard. For e.g. the last time I bought a mobo, I spent about 6k but that was for an ATX motherboard. Most ITX motherboards usually sold for around INR 4k/- or even lower. I remember Via especially as their mobos were even cheaper around INR 1.5-2k/-. Even before pandemic, many motherboard manufacturers had closed down shop leaving only a few in the market. As only a few remained, prices started going higher. The pandemic turned it to a seller’s market overnight as most people were stuck at home and needed good rigs for either work or leisure or both. The manufacturers of CPU, motherboards, GPU’s, Powersupply (SMPS) named their prices and people bought it. So in 2023, high prices remained while warranty periods started coming down. Governments also upped customs and various other duties. So all are in hand in glove in the situation. So as shared before, what I have been offered is a 4 year motherboard with a CPU of that time. I haven’t bought it nor do I intend to in short-term future but extremely disappointed with the state of affairs

AMD Issues

It’s just been couple of hard weeks apparently for AMD. The first has been the TPM (Trusted Platform Module) issue that was shown by couple of security researchers. From what is known, apparently with $200 worth of tools and with sometime you can hack into somebody machine if you have physical access. Ironically, MS made a huge show about TPM and also made it sort of a requirement if a person wanted to have Windows 11. I remember Matthew Garett sharing about TPM and issues with Lenovo laptops. While AMD has acknowledged the issue, its response has been somewhat wishy-washy. But this is not the only issue that has been plaguing AMD. There have been reports of AMD chips literally exploding and again AMD issuing a somewhat wishy-washy response. Asus though made some changes but is it for Zen4 or only 5 parts, not known. Most people are expecting a recession in I.T. hardware this year as well as next year due to high prices. No idea if things will change, if ever

Categories: FLOSS Project Planets

Plasma 6: “Better defaults”

Planet KDE - Thu, 2023-05-11 02:10

The 2023 Plasma sprint is now finished! KDE Patron Tuxedo Computers were kind enough to open their offices to us for a full week to do the sprint. We had some great conversations with Tuxedo employees, who were very friendly and excited to work with us, and made us thoroughly aware of just how much more complicated modern keyboard backlighting is than we had imagined! I’d like to thank KDE’s Software Platform Engineer Nicolas Fella for organizing this sprint, and Tuxedo Computers for providing the space and free pizza for lunch yesterday.

This actually isn’t all of us, because we foolishly forgot to take a picture earlier when everyone was present!

This won’t be a retrospective of the entire sprint, because I don’t want to steal anyone else’s thunder! People will be blogging and making videos about their own personal work and experience, so this one will be about mine.

The first thing was to get a Plasma 6 session working for daily driving. My colleagues have been working unbelievably hard on this, and I’m happy to report that I was able to live on Plasma 6 for the entire sprint without major showstoppers (from the perspective of a technical developer, of course). Almost everyone else there was as well, and I expect this to lead to extremely rapid stabilization despite the heavy code refactoring underway. I plan to continue living on Plasma 6 until its eventual release, and I encourage any adventurous developers to do so as well. If you try it out and submit any bug reports, make sure to add the “qt6” keyword to it.

I also did a bunch of technical work of my own, but I largely found myself in the role of facilitator, hosting discussions and meetings with different groups of people to bridge gaps.

New Default settings

As a result, we advanced a number of topics that had been stuck for a while. A major area of my focus in this respect became “Better default settings”. The 5 -> 6 transition is the perfect time to make significant changes to the default settings in a way that improve the UX out of the box. Among these are:

Double-click by default

Link to task

Wait, did I just bury the lede!? I did indeed. This is because the work hasn’t actually been done yet… but it has in fact been approved! That’s right, Plasma 6 will default to opening files and folders with a double-click, not a single-click. Even though almost everyone in the room for the discussion actually uses and prefers opening with single-click, we had to admit that it’s probably not the ideal default setting for people who are migrating from other platforms, which is most of them. They can still learn the benefits of single-click later.

Wayland by default

Link to task

We’re going to make a very strong push for Wayland to be the default session type for Plasma 6. The X11 session will still be there of course, and distros will be free to override this and continue defaulting to X11 if they feel like it suits them better. But we want Wayland to be our official recommendation.

To get there, we went over our “Wayland showstoppers” wiki page with a fine-toothed comb to refine what we really consider a showstopper. We decided that a lot of them are really more like annoyances rather than showstoppers, because X11 has plenty of annoyances of a similar severity too! The true showstoppers are down to five, plus a couple of NVIDIA issues that need further investigation. Many of these issues are in progress with a clear path towards resolution, so I do expect us to be able to achieve the goal!

Floating Panel by default

Link to task

This feature has been optional since its introduction a year ago. In that time it’s become quite popular, but its visual fanciness alone wasn’t enough to tip this proposal over the finish line. Rather, it’s the fact that Microsoft has blatantly copied us in Windows 11, and as a result, people are starting to see Plasma as a cheap clone of Windows again. We see this all the time in the VDG room when some rando comes by and starts telling us why our design isn’t as good as what Windows 11 has; they’ve implicitly made the comparison and found us wanting. It’s the wrong mindset!

Making the panel float by default provides an immediate visual differentiation from Windows 11 and we hope this will help jolt users’ brains out of “ew, it’s slightly different from Windows 11” mode and into “wow, this is new and cool and I wonder what’s in it” mode. There’s probably more that needs to be done for that, but I think this is a good start.

And let’s face it, it’s also just sexy af Accent-color-tinted header area by default

Link to task

In the middle of the Plasma 5 lifecycle, we switched to the Breeze Light color scheme by default, and we changed its appearance to use a medium gray header area, sort of mimicking the visually pleasing CSD headerbar look without actually using CSD headerbars. This appearance change has generally been well-received by users, but it faced a persistent criticism: diminished ability to distinguish the active window at a glance.

It’s a legitimate problem, and we decided to fix it by lightly tinting the header area with your current accent color (or the current color scheme’s selection color, if you’re not using Accent colors). This will distinguish the active window with a small amount of color, making it pop more without being visually overwhelming. Something like this:

Note: this is a mockup and the appearance is not final! So don’t go posting this all over social media declaring that it’s going to be the way everything looks forever New default Task Switcher

Link to task

For a while, we’ve had a goal of switching our current default “Breeze” Task Switcher to something that doesn’t vertically scroll with even a relatively small number of windows, which feedback had indicated was bad for usability. We also wanted to make our default task switcher better for people who navigate primarily by looking at app icons rather than thumbnails or text. With those design goals in mind, we decided to use the “Thumbnail Grid” Task Switcher by default and make some UI changes. Here’s what it looks like at this point in time:

As a part of this work, we also deleted a bunch of infrequently-used Task Switchers in the kdeplasma-addons Git repo that were simply worse versions of other ones. And finally, we made our Breeze Global Themes no longer have an opinion about what they want the Task Switcher to be, so if you use a non-default one, you can safely switch Global Themes without having it reset your Task Switcher all the time! That makes it less annoying to use the Dark and Light buttons on System Settings’ Quick Settings page to switch the system’s appearance between those two states.

This work is already merged and was done by me.

No more scrolling on desktop to switch virtual desktops by default

Link to task

We got feedback over the years that scrolling on the desktop to switch virtual desktops was disorienting, especially because you could switch to a desktop that you couldn’t switch out of in the same way because the desktop was covered up. So we decided to turn this feature off by default. If you really like it, you’re still welcome to turn it back on, of course!

This work is already merged and was done by me.

Clicking in scrollbar track jumps scrollbar to that location

Link to task

This change makes it easy to scroll straight to a specific location without having to drag the scrollbar, which is worse from the perspective of avoiding repetitive motion injuries. The old style is still available as an option to can switch back to.

This work is already merged and was done by me.

Other discussions and decisions

Many other discussions were also had besides just default settings. Here are a few:

City of Treuchtlingen’s use of KDE software

We found out that the nearby German city of Treuchtlingen has been using KDE software for over 20 years for their government IT purposes. Two representatives came out to the Tuxedo HQ to give us a presentation and we all talked about how to continue this going forward not only for us, but potentially for a lot of other German governments. The possibilities here are quite exciting.

A slower-paced release schedule

Link to task

In the beginning of Plasma 5, the release schedule was very fast–four releases a year. As it stabilized, we went down to three, which we kept for the whole lifecycle of Plasma 5.

Over time we’ve gotten a lot of feedback from distros in particular who have told us that this represents a hardship. It’s also been my personal observation that we often don’t have enough time to polish a new Plasma version before it’s released.

Now, a fast release cycle makes sense for a product under heavy development that breaks a lot of things and needs to fix them quickly. However, at this point Plasma is mature and feature complete after 8 years of hard work. It can always be improved, of course, but it pretty much does everything a general user needs at this point in time. So a fast release schedule isn’t as useful as it once was.

For Plasma 6, we’re going to try a slower release schedule of two per year once we feel like it’s stabilized enough after its initial release. And we’re going to be reaching out to distros with twice-yearly release schedules themselves to see if we can find release dates that will allow all of them to ship the latest version of Plasma soon after it’s released rather than skipping it in favor of something older. Making use of these lengthened release periods, we’re also going to lengthen our Beta releases and update them on a weekly basis, so there’s more time to find and fix bugs. We’re hoping this should result in Plasma 6 having a high level of stability and reliability throughout its lifecycle.

A wallpaper page in System Settings

Link to task

We agreed that the status quo isn’t ideal because people expect to find wallpaper settings in System Settings. So we started sketching out a wallpaper KCM that will let people change their wallpapers in a central location, including the ability to apply them to the lock and login screens. You’ll still be able to access the wallpaper changing UI from the current method in addition to the new KCM.

Consolidate Desktop plugins

Link to task

Currently we have two default desktop plugin types: “Folder” (the default) and “Desktop”. “Desktop” is just “Folder” without support for desktop icons. This is a bit silly, and internally they’re 99% the same because its prior developer also thought it was a bit silly and implemented them with the same backend code. So for Plasma 6, we’re going to collapse the distinction in the UI and instead expose a “Show desktop icons” checkbox somewhere. This will make it even easier for people who don’t like desktop icons to hide them, avoid putting implementation details in front of the user, and de-clutter the wallpaper choosing view.

Keyboard backlighting is hard

Taking advantage of the fact that we were in Tuxedo’s offices, we took the opportunity to ask many Tuxedo employees about their and their customers’ biggest pain points with KDE software. Happily, there were actually few complaints. But something that came up a few times was how we handle keyboard backlighting. Currently our code assumes there will be one keyboard backlight that affects all keys, so it only affects the first one it finds. But many modern laptops have more than one backlight, with some even giving each key its own! Needless to say, the result of adjusting a single backlight on such a keyboard looks somewhat hilarious. So we plan to put some effort into improving this.

That’s not all

This blog post contains only a small sampling of what was done and talked about during the sprint. There are many, many other plans and in-progress projects for Plasma 6, but I’ll let others talk about their own projects elsewhere, so look for them on https://planet.kde.org! I’d say that Plasma 6 promises to be a very large and exciting release.

Help make it possible again

Thanks again to Tuxedo Computers for graciously opening their offices to us, and for Nicolas Fella for organizing the sprint!

In addition, funding for the sprint was covered by KDE e.V., the nonprofit backing KDE. As you can probably imagine, transporting and lodging 20 people for a week is expensive, and most e.V. funding comes from individual donations. So if you’d like to see more of this kind of thing, please consider making a donation today! Every little bit helps!

Categories: FLOSS Project Planets

The vital role of Open Source maintainers facing the Cyber Resilience Act

Open Source Initiative - Wed, 2023-05-10 22:56

This year’s Maintainer Month feels different given what’s happening with the European Cyber Resilience Act. Their role is under more pressure than usual and yet, it’s often misunderstood. 

Open Source maintainers are the cornerstone of collaborative software development. They dedicate their time and expertise to ensure the smooth functioning and growth of Open Source projects. As gatekeepers of the code, they review contributions, manage repositories, and maintain the software’s integrity. They provide guidance, mentorship, and support to the community of contributors, fostering an inclusive environment for developers of all levels. Maintainers also serve as community managers, facilitating discussions and resolving conflicts. 

Their voluntary contributions result in significant technological advancements, yet their role as volunteers is too often mischaracterized. Even when paid by corporations, maintainers of Open Source projects do it on a voluntary basis. This is hard to comprehend. Recognizing and supporting their efforts is crucial for the sustainability of projects. 

Open Source maintainers are the driving force behind the success of collaborative software development, and their dedication deserves our appreciation and support.

I hold weekly office hours on Fridays with OSI members: book time if you want to chat about OSI’s activities, if you want to volunteer or have suggestions.

Stefano Maffulli

Executive Director, OSI

In this month’s Open Source Initiative Newsletter:
  • What Is Open Governance? Drafting a charter for an Open Source project
  • The importance of Open Source AI and the challenges of liberating data
  • Things I learned at Brussels to the Bay: AI governance in the world
  • Open Source ensures code remains a part of culture
  • Salesforce: Why we sponsor OSI
What Is Open Governance? Drafting a charter for an Open Source project

Building a healthy Open Source community is much more than just choosing an Open Source license for the project. It involves creating a contributing guide, adopting a code of conduct, and establishing an open governance structure that allows all members to actively participate in and contribute to the project.

This article by ClearlyDefined Community Manager Nick Vidal provides a hands on guide on how to establish an open governance structure for an Open Source project. In fact, he is currently in the process of proposing an amendment to the existing charter of the ClearlyDefined project.

The importance of Open Source AI and the challenges of liberating data

The values in Open Source are encapsulated in its Definition, but can be distilled to “autonomy, transparency, frictionless innovation, education, community improvement”. The licenses are a way to enable these things in the face of copyright law that defaults to the contrary. The licenses are not the mechanism to achieve these goals. Instead it’s the community and innovation that they produce when you remove legal barriers to collaboration.

This blog post by Executive Director Stefano Maffulli was taken from a speech given remotely at LLW 2023.

Things I learned at Brussels to the Bay: AI governance in the world

Recently Executive Director Stefano Maffulli participated in Brussels to the Bay: AI governance in the world, a conference hosted by Berkeley Law’s Center for Law, Energy and the Environment (CLEE) and EU in the US, to learn more about the status of international policies on AI. Here is his takeaway.

Open Source ensures code remains a part of culture

Software is a cultural artifact, a proxy for the law in the lives of every citizen, a tool for control and for freedom depending on the hand that wields it.  It is imperative that all software is open for scrutiny and preserved for posterity. Standards & EU Policy Director Simon Phipps explains further in this blog post.

Salesforce: Why we sponsor OSI

We asked Alyssa Gravelle, Salesforce Senior Program Manager, Open Source to share the organization’s intrinsic ties to Open Source, its reasons for supporting the Open Source Initiative, and its hopes for the Open Source movement. Here’s what she said.

Are you interested in sponsoring or partnering with the OSI? Contact us to find out more about how your organization can promote open source development, communities and software

Image by peshkov from Getty Images via Canva.com

The post <span class='p-name'>The vital role of Open Source maintainers facing the Cyber Resilience Act</span> appeared first on Voices of Open Source.

Categories: FLOSS Research

Read the Docs: Read the Docs newsletter - May 2023

Planet Python - Wed, 2023-05-10 20:00
News and updates
  • 🚁️ The proxy application El Proxito has been rewritten and the new version is rolled out to selected projects. El Proxito resolves URLs for all documentation websites hosted on Read the Docs. The new rewrite improves the performance of the resolver and makes it possible to add planned features. We are enabling the new implementation gradually for more projects, while monitoring its stability. Eventually, it will be enabled on all projects.

  • 🔎️ …One of the new features available in the new El Proxito implementation, is an improved 404 page (see the screenshot below). The new 404 pages contain better error messages and tips for users and project owners.

  • 💫️ We now support multiple .readthedocs.yaml files in the same repository. This is especially useful for monorepos containing multiple documentation projects with different configurations. This allows for instance configurations of several projects with different documentation tools and build environments. Read more about the feature in our docs.

  • ⚙️ If you use build.commands in .readthedocs.yaml, you are no longer required to have a build.tools section. We changed the validation for .readthedocs.yaml to accommodate projects that do not need any of the built-in tools exposed.

  • 🐛️ Fixed: URLs on pull request builds were pointing to the build page, rather than the documentation preview. If a build is successful, the URL now points to the documentation preview.

  • 🐛️ Fixed: An issue in our legacy build images caused builds using Sphinx to start failing on May 4th when urllib3 2.0.2 was released. The issue has been fixed by upgrading OpenSSL on these images.

    We still encourage to specify a newer build image, an example is given in this comment.

  • 🔒️ Vulnerability fixed: CAS session hijacking on Read the Docs for Business

Left: the classic old 404 page with the ascii art maze - right: new contextualized 404 pages. The new default 404 pages are aimed at being more helpful to users and project owners and uses context to specify what was not found, such as a file path, a version, a translation or the project slug.

Upcoming features
  • 🚁️ As mentioned earlier, we have rewritten our proxy application El Proxito and will start to add new features. One of the features being worked on is the ability to serve subprojects at custom URL paths.

Want to follow along with our development progress? View our full Roadmap 📍️

Possible issues

We have updated our legacy build images with a newer version of OpenSSL. If this update affects your builds, please reach out.

These changes only affects projects that do not specify build.os. We will announce plans to sunset the legacy build images soon. For instance, urllib3 will also announce further removal of OpenSSL support, and we already consider the old build images as pretty legacy.

Questions? Comments? Ideas for the next newsletter? Contact us!

Categories: FLOSS Project Planets

KDE Gear 23.04.1

Planet KDE - Wed, 2023-05-10 20:00

Over 120 individual programs plus dozens of programmer libraries and feature plugins are released simultaneously as part of KDE Gear.

Today they all get new bugfix source releases with updated translations, including:

  • kdenlive: Fix corrupted project files on opening (Commit, fixes bug #469217)
  • skanpage: Scan Export window's OCR language list is now scrollable (Commit, fixes bug #468522)
  • spectacle: Quitting Spectacle with Escape no longer affects windows below it (Commit, fixes bug #428478)

Distro and app store packagers should update their application packages.

Categories: FLOSS Project Planets

Charles Plessy: Upvote to patch Firefox to render Markdown

Planet Debian - Wed, 2023-05-10 19:43

I previously wrote that when Firefox receives a file whose media type is text/markdown, it prompts the user to download it, whereas other browsers display rendered results.

Now it is possible to upvote a proposal on connect.mozilla.org asking that Firefox renders Markdown by default.

Categories: FLOSS Project Planets

CodersLegacy: Python Metaclass Tutorial (with Examples)

Planet Python - Wed, 2023-05-10 15:49

In this Python tutorial, we will discuss the concept of a “Metaclass”, and how it can be used effectively.

Metaclasses are a powerful feature in Python that allow you to create classes dynamically at runtime. In Python, everything is an object, including classes. When you define a class in Python, you are actually creating an object of type type. This means that you can use metaclasses to create custom classes with their own behaviors and attributes.

In a nutshell, a metaclass is a class that creates other classes. When you define a class with a metaclass, you are essentially telling Python to use that metaclass to create the class object. Metaclasses can be used to add new functionality to classes, modify the behavior of existing classes, and perform validation on class attributes.

The importance of metaclasses in Python programming cannot be overstated. They are a powerful tool that can be used to create more dynamic and flexible programs. With metaclasses, you can customize the way classes are created and add new features to your classes that would be difficult or impossible to achieve with normal class inheritance.

This is just one example of the many ways that metaclasses can be used to customize class creation in Python. In the following sections of this Python tutorial, we’ll explore the basics of a metaclass, as well as more advanced features and use cases.

The Basics of Metaclasses in Python

In order to understand metaclasses in Python, it’s important to first understand the type() function. The type() function is the built-in metaclass in Python, and is used to create new classes.

When you define a new class in Python, you are actually calling the type() function with three arguments: the name of the class, the tuple of base classes, and a dictionary containing the attributes of the class. For example:

class MyClass: pass

Is equivalent to:

MyClass = type('MyClass', (), {})

In this example, we are calling the type() function with the arguments 'MyClass', an empty tuple for the base classes, and an empty dictionary for the attributes.

Now that we understand the type() function, let’s take a look at how we can create custom metaclasses. To create a custom metaclass, we simply define a new class that inherits from type. For example:

class MyMeta(type): pass

In this example, we are defining a new class called MyMeta that inherits from type. This means that MyMeta is itself a metaclass, and can be used to create new classes.

When creating a custom metaclass, we can define two special methods: __new__() and __init__().

The __new__() method is called when the metaclass is used to create a new class object, and is responsible for creating and returning the new class object. The __init__() method is called after the new class object has been created, and is responsible for initializing the class attributes.

Here’s an example of a custom metaclass that adds a new class attribute:

class MyMeta(type): def __new__(cls, name, bases, attrs): attrs['custom_attribute'] = 'Hello, world!' return super().__new__(cls, name, bases, attrs) class MyClass(metaclass=MyMeta): pass print(MyClass.custom_attribute) # Output: "Hello, world!"

In this example, we define a new metaclass called MyMeta that adds the custom_attribute to every new class it creates. Then, we define a new class called MyClass that uses MyMeta as its metaclass. When we create an instance of MyClass, we can see that it automatically has the custom_attribute.

In the next section, we will explore these two functions (new and init) in greater detail with some new examples.

Creating Custom Metaclasses in Python

Now that we have an understanding of the basics of metaclasses and how to define them, let’s explore some more examples of how to use metaclasses and their associated methods.

new() Function

The new() method is responsible for creating and returning a new class object. It takes four parameters:

  • cls: the metaclass being called
  • name: the name of the class being created
  • bases: a tuple of base classes
  • attrs: a dictionary of class attributes

Let’s take a look at an example that demonstrates the use of the new() method:

class MyMeta(type): def __new__(cls, name, bases, attrs): new_attrs = {} for attr_name, attr_value in attrs.items(): if isinstance(attr_value, str): new_attrs[attr_name.upper()] = attr_value else: new_attrs[attr_name] = attr_value return super().__new__(cls, name, bases, new_attrs) class MyClass(metaclass=MyMeta): x = 'hello' y = 123 z = 'world' print(MyClass.X) # Output: "hello" print(MyClass.Z) # Output: "world" # MyClass.y remains unchanged because its an integer

In this example, we define a new metaclass called MyMeta that modifies the class attributes by converting the values of any string attributes to uppercase. Then, we define a new class called MyClass that uses MyMeta as its metaclass. When we create an instance of MyClass, we can see that the string attributes have been converted to uppercase.

init() Function

The init() method is responsible for initializing the class attributes. It takes three parameters:

  • self: the newly created class object
  • name: the name of the class being created
  • bases: a tuple of base classes

Here’s an example of a custom metaclass that adds a new method to every class it creates:

class MyMeta(type): def __init__(self, name, bases): super().__init__(name, bases) self.foo = lambda self: print('Hello from foo!') class MyClass(metaclass=MyMeta): pass obj = MyClass() obj.foo() # Output: "Hello from foo!"

In this example, we define a new metaclass called MyMeta that adds a new method called foo() to every class it creates. Then, we define a new class called MyClass that uses MyMeta as its metaclass. When we create an instance of MyClass and call the foo() method, we can see that it works as expected.

In the next section of this tutorial, we will explore some more advanced use cases of a Metaclass in Python.

Advanced Metaclass Features in Python

Metaclass inheritance:

Just like classes can inherit from other classes, metaclasses can also inherit from other metaclasses. This allows for the creation of complex hierarchies of metaclasses that can have their own special behaviors and attributes. To define a metaclass that inherits from another metaclass, simply specify the parent metaclass as the first argument when defining the new metaclass. For example:

class MyBaseMeta(type): pass class MyChildMeta(MyBaseMeta): pass

In this example, we define a new metaclass called MyBaseMeta, and then define a child metaclass called MyChildMeta that inherits from MyBaseMeta.

Here’s a more detailed example of metaclass inheritance:

class BaseMeta(type): def __new__(cls, name, bases, attrs): print("Creating class", name, "with base classes", bases) return super().__new__(cls, name, bases, attrs) class ChildMeta(BaseMeta): def __new__(cls, name, bases, attrs): print("Creating child class", name) return super().__new__(cls, name, bases, attrs) class MyBaseClass(metaclass=BaseMeta): pass class MyChildClass(metaclass=ChildMeta): pass

In this example, we define two metaclasses: BaseMeta and ChildMeta. ChildMeta inherits from BaseMeta.

When MyBaseClass and MyChildClass are defined, the __new__ method of each respective metaclass is called. When MyBaseClass is defined, only BaseMeta‘s __new__ method is called. However, when MyChildClass is defined, both ChildMeta‘s and BaseMeta‘s __new__ methods are called, in that order.

Output from defining the MyBaseClass.

# Creating class MyBaseClass with base classes ()

Output from defining the MyChildClass.

# Creating class MyBaseClass with base classes () # Creating child class MyChildClass # Creating class MyChildClass with base classes () Multiple inheritance with metaclasses:

Just like classes, metaclasses can also use multiple inheritance. This allows for even more complex hierarchies of metaclasses that can have their own unique behaviors and attributes. To specify multiple inheritance in a metaclass, simply provide a tuple of parent metaclasses as the first argument when defining the new metaclass. For example:

class MyBaseMeta1(type): pass class MyBaseMeta2(type): pass class MyChildMeta(MyBaseMeta1, MyBaseMeta2): pass

In this example, we define two base metaclasses (MyBaseMeta1 and MyBaseMeta2), and then define a child metaclass called MyChildMeta that inherits from both base metaclasses.

Dynamically generating classes with metaclasses:

Metaclasses can be used to dynamically generate new classes at runtime. This can be useful in situations where you need to create many similar classes, or when you need to generate classes based on user input or configuration files. To generate a new class dynamically with a metaclass, simply call the metaclass with the appropriate arguments. For example:

class MyMeta(type): pass class MyClass1(metaclass=MyMeta): pass class MyClass2(metaclass=MyMeta): pass def create_class(class_name): return MyMeta(class_name, (), {}) MyClass3 = create_class('MyClass3')

In this example, we define a new metaclass called MyMeta, and then use it to generate three new classes (MyClass1, MyClass2, and MyClass3). The MyClass3 class is generated dynamically at runtime using the create_class() function, which calls the MyMeta metaclass with the appropriate arguments.

In the next section of this tutorial, we’ll take a look at some of the special attributes and methods that can be defined in a python metaclass.

Python Metaclass: Special Attributes and Methods

In addition to the __new__() and __init__() methods, metaclasses can also define special attributes and methods that affect how new classes are created. Let’s take a look at some of the most commonly used metaclass attributes and methods.


This method is called when a new class is defined inside another class. It takes two arguments: the metaclass and the cell that contains the class definition.

class MyMeta(type): def classcell(cls, cell): print(f"Class '{cls.__name__}' defined in '{cell.cell_name}'") class MyClass(metaclass=MyMeta): class MyNestedClass: pass

In this example, we define a new metaclass called MyMeta that defines the classcell() method. When we define a new nested class called MyNestedClass inside MyClass, the classcell() method is called with the MyMeta metaclass and the cell that contains the class definition. The method prints out a message indicating the name of the class and the name of the cell where it was defined.


This method is called before the __new__() method when a new class is created. It takes three arguments: the metaclass, the name of the class, and the list of base classes. It returns a new dictionary of class attributes that will be used to create the new class.

class MyMeta(type): def prepare(cls, name, bases): print(f"Preparing class '{name}'") return {'custom_attribute': 'Hello, world!'} class MyClass(metaclass=MyMeta): pass print(MyClass.custom_attribute) # Output: "Hello, world!"

In this example, we define a new metaclass called MyMeta that defines the prepare() method. When we create a new class called MyClass with MyMeta as its metaclass, the prepare() method is called with MyMeta, the name 'MyClass', and an empty tuple for the base classes.

The method returns a new dictionary containing a single attribute, custom_attribute, with the value 'Hello, world!'. This dictionary is then used to create the new class object.

__instancecheck__() and __subclasscheck__():

These methods are called when checking the type of an object or the subclass relationship between two classes. They take two arguments: the metaclass and the object or class being checked. They should return True if the object or class satisfies the type or subclass relationship, and False otherwise.

class MyMeta(type): def __instancecheck__(cls, instance): print(f"Checking instance of '{cls.__name__}'") return isinstance(instance, str) def __subclasscheck__(cls, subclass): print(f"Checking subclass of '{cls.__name__}'") return issubclass(subclass, str) class MyString(str, metaclass=MyMeta): pass my_string = MyString('Hello, world!') # Output: "Checking instance of 'MyString'", "True" print(isinstance(my_string, MyString)) # Output: "Checking subclass of 'MyString'", "True" print(issubclass(str, MyString))

In this example, we define a new metaclass called MyMeta that defines the __instancecheck__() and __subclasscheck__() methods. When we define a new class called MyString that inherits from str and uses MyMeta as its metaclass, these methods are called when we check the instance type of my_string and the subclass relationship between str and MyString.

The __instancecheck__() method prints out a message indicating that we are checking an instance of 'MyString', and returns True if the instance is a string. The __subclasscheck__() method prints out a message indicating that we are checking a subclass of 'MyString', and returns True if the subclass is a string.

This marks the end of the Python MetaClass Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

The post Python Metaclass Tutorial (with Examples) appeared first on CodersLegacy.

Categories: FLOSS Project Planets

PyCharm: How To Create a Passphrase Generator in PyCharm

Planet Python - Wed, 2023-05-10 14:56

In this tutorial, you will create a passphrase generator in PyCharm. You’ll learn how to:

  • Create a project in PyCharm Community Edition.
  • Install and import Python packages.
  • Use the Typer library to create command line interfaces in Python.
  • Run and debug code in PyCharm.
  • Create and edit run configurations.

The purpose of the tutorial is to show how you can develop simple CLI applications for automating your everyday tasks by using the free PyCharm Community Edition. Although you’ll get a working passphrase generator by the end of this tutorial, please consider it merely a learning project. Never use the passwords produced by this generator to protect any real data.

To get the full code, you can clone the repository. For information about cloning, see the PyCharm documentation.

About passphrases What is a passphrase?

We all use lots of passwords every day. Whenever you sign up for a service or a website, it requires you to create a long and unique password with numbers, special characters, uppercase letters, and so on.

All these requirements are meant to make a password resistant to brute force attacks. A brute force attack is basically making a number of attempts to guess the password until one of them eventually gets it right. How many attempts and how much time is required depends on the password’s length and complexity.

A passphrase is a password consisting of several random words. It doesn’t have to make sense or to be grammatically correct. Passphrases usually contain 4 to 5 words – the more, the better. For example, PhysicianBuiltHotPotatoRegularly is a passphrase.

Why is a passphrase better?

A^1rL#2k2oPiA9H is a good, strong password. It contains lowercase and uppercase letters, numbers, special symbols, and is 15 characters long. But what would you rather memorize, A^1rL#2k2oPiA9H or PhysicianBuiltHotPotatoRegularly? By the way, the latter has 32 characters in it.

Apart from how easy or difficult a password is to memorize, we should also pay attention to how easy or difficult it is to crack. Have a look at the following table:

A^1rL#2k2oPiA9HPhysicianBuiltHotPotatoRegularlySymbol set size9552Password length1532Attempts required to crack (?)2982182

Both are strong, but the passphrase is stronger and much easier to remember. What’s more, if you added a couple of numbers and special characters to the passphrase, that would increase the average number of required guessing attempts to 2210 – virtually impossible to crack! 

To sum up:

  • Passphrases consisting of random words are easier to memorize than passwords consisting of random characters.
  • Passphrases are generally longer than most passwords, which makes them more resistant to brute force attacks and thus more secure.
  • Passphrases can be modified to comply with complexity requirements. For example, you can capitalize words to include uppercase letters, or add special characters and numbers as separators between the words.
What is a passphrase generator

In general, a passphrase generator is a program that makes passwords by combining random words into pseudo-sentences. In this tutorial, we will use PyCharm and Typer to develop a command line tool that will do the following:

  • Generate a passphrase consisting of 4–5 random words.
  • Capitalize words in a passphrase if such an option is selected. By default words aren’t capitalized.
  • Use any symbol as a separator for words. By default there are no separators.
  • Create longer passphrases by adding the fifth word. The default length is four words.

The tool will NOT store your passwords.

  • Some previous experience with Python.
  • PyCharm Community Edition 2023.1 or newer.
  • Python (can be downloaded during project creation).
First steps Write ‘Hello World’ with Typer

When you launch PyCharm for the first time, you’ll see the Welcome screen. Click New Project:

If you already have PyCharm running, select File | New Project from the main menu.

When the New Project window opens, look for the Location field at the top and use it to specify the directory for your project. This will also be used as the project name.

You can choose the type of the virtual environment where PyCharm will install the project dependencies. You can also select the location where the environment will be created, as well as the base Python interpreter.

Choose the preferred environment type and specify the options (or keep the defaults), and then click Create.

PyCharm will create the project directory with the virtual environment in it (venv in our case). If you didn’t clear the Create a main.py welcome script checkbox on the previous step, it will also create main.py and open it in the editor:

The file contains a ‘Hello World’ script with some basic instructions. Copy the following code to the clipboard:

def main(): print("Hello World") if __name__ == "__main__": typer.run(main)

Now, go to PyCharm and replace the contents of main.py by pressing ⌘A / Ctrl+A followed by ⌘V / Ctrl+V. You should get the following:

You can see that typer has a red squiggly line underneath it. This means that the Python interpreter doesn’t recognize what Typer is. We need to install this package and import it in main.py to be able to launch the script.

Hover the mouse pointer over the highlighted symbol, and then select Install and import package ‘typer’ in the popup:

PyCharm will install the Typer package into the project environment and import it in main.py.

Now we can run the script. Click the run icon in the gutter and then select Run ‘main’:

The Run tool window with “Hello World” will open at the bottom:

Generate your first passphrase

Let’s modify the code so that it prints passphrases instead of “Hello World”. The idea is to pick random words and make phrases out of them. That means we’ll need one or more word lists to pick from. You can prepare such lists manually or generate them by using one of the available large language models.

When you create your word lists, make sure to keep them secure. If a malicious actor gets access to your word lists, they will be able to crack your passwords in a matter of seconds.

Our repo contains word lists along with the full code for this tutorial. You can download and use them only for learning purposes, and at your own risk. Generating real passphrases based on these word lists is strongly discouraged.

At this step, you’ll need 4 word lists:

  • obj_nouns.txt with nouns that will act as objects in our generated pseudo-sentences.
  • sub_nouns.txt with nouns that will act as subjects.
  • verbs.txt with verbs.
  • adjectives.txt with adjectives.

The more words you have in each list, the more combinations the script will be able to generate. Each word should start with a new line.

Copy the generated or downloaded word lists to the project directory. If you want to create the word lists manually, you can do that in PyCharm:

  1. Click the project directory in the Project tool window, and then press ⌘N / Ctrl+N.
  2. Select File and then specify the file name, such as obj_nouns.txt.
  3. PyCharm will create the file and open it in the editor.

This is what the project structure should look like:

First of all, we need to read the words from the text files. Replace print("Hello World") with the following code:

sub_nouns = read_words('sub_nouns.txt')

Again, read_words has a red squiggly line underneath it. We need to create this function. Hover the mouse over read_words and then click Create function ‘read_words’ in the popup:

PyCharm will create a function stub. Specify file_name as the function parameter, and then press Tab to start writing the function code:

You can copy the highlighted code into the function body:

def read_words(file_name): with open(file_name, 'r') as f: words = f.readlines() return words

The function opens the file whose name is provided in the first parameter. Then it applies the readlines() method, which returns a Python list containing the lines of the file as its elements. That list is saved to the words variable and returned by the function.

Let’s go back to the main() function and use the newly created read_words function to read the other 3 word lists:

def main(): sub_nouns = read_words('sub_nouns.txt') verbs = read_words('verbs.txt') adjectives = read_words('adjectives.txt') obj_nouns = read_words('obj_nouns.txt')

Now, let’s create a list of word lists and call it word_bank. Later we will iterate through it when picking random words for the passphrase:

word_bank = [sub_nouns, verbs, adjectives, obj_nouns]

The selected random words will be saved into yet another list. Let’s call it phrase_words and initialize it:

phrase_words = []

In the following for cycle, we iterate through the items of word_bank. Each item there is a list with words. We call the choice() method of the SystemRandom() class from the built-in random module to select a random word from the list. Then we append the selected word to phrase_words:

for word_list in word_bank: random_word = random.SystemRandom().choice(word_list) phrase_words.append(random_word)

Although random is a built-in module, we still need to import it. Like before, you can tell that by the red squiggly line in the editor. Hover the mouse over it and select Import this name.

Finally, let’s use join to turn the list with randomly selected words into a phrase and print the result:

passphrase = ''.join(phrase_words) print(passphrase)

Here’s what main() should look like at this stage:

def main(): sub_nouns = read_words('sub_nouns.txt') verbs = read_words('verbs.txt') adjectives = read_words('adjectives.txt') obj_nouns = read_words('obj_nouns.txt') word_bank = [sub_nouns, verbs, adjectives, obj_nouns] phrase_words = [] for word_list in word_bank: random_word = random.SystemRandom().choice(word_list) phrase_words.append(random_word) passphrase = ''.join(phrase_words) print(passphrase)

Now we can run the script to check that it works correctly. Click the Run icon in the gutter and select Run ‘main’, and this is what you should get:

OK, there are 4 words, but it’s definitely not a phrase. When code generally works but produces unexpected results, it needs to be debugged.

As we can see from the current output, the script successfully selected random words from the word lists. What it didn’t do is combine the words together into one phrase. The second-to-last line of main() appears to be the likely culprit:

def main(): ... passphrase = ''.join(phrase_words) print(passphrase)

To see what a specific line of code produces, we should put a breakpoint on that line. The debugger will then stop just before executing the line with the breakpoint. To set a breakpoint, click the gutter next to the line we are interested in checking:

To start the debugging process, click the Run icon in the gutter, like you’ve done before, but this time, select Debug ‘main’ in the popup. The debugger will start and then stop execution at the breakpoint, opening the Debug tool window at the bottom:

In the right-hand pane of the Debug tool window, you can see the variables that have been assigned so far. Expand phrase_words to see what’s inside:

There are 4 items of type str in the list. Each string ends with a new line (‘\n’). That’s why, when we later join these strings together and print them, each word is printed on a separate line.

If you have a look at the other lists, for example adjectives, you’ll notice that all items in them also end with ‘\n’. We get these lists from the read_words function. That means we need to fix it so that it returns a list of words without a trailing ‘\n’.

Let’s use strip() and list comprehension to get rid of ‘\n’ in each list item before returning it:

def read_words(file_name): with open(file_name, 'r') as f: words = f.readlines() words = [word.strip() for word in words] return words

Rerun main() and enjoy the result:

Create better passphrases Make them easier to memorize

As you may have noticed, the passphrase generated on the previous step is a little hard to read. What about capitalizing each word to improve readability?

We are using Typer in this application because we don’t want to just run the script and get a passphrase. We need to create a command line interface, so that we can pass various options to the script and thus control the properties of the resulting passphrase. One such option is capitalizing the words.

When we run main.py, the following line is executed:

... if __name__ == "__main__": typer.run(main)

So, we’ll use typer to execute the main function. The reason why we are doing this is that Typer can accept command line arguments and then pass them to functions as parameters.

Let’s introduce the capitalize parameter in the main() function and make it False by default:

def main(capitalize = False): sub_nouns = read_words('sub_nouns.txt') ... passphrase = ''.join(phrase_words) print(passphrase)

According to Python coding best practices, we should specify the parameter type. Place the caret on capitalize and press ⌥Enter/ Alt+Enter. Then select Specify type for the reference using annotation. Type bool, as capitalize should have a Boolean value.

Now let’s capitalize words before joining them if capitalize is True. Start an if statement with if capitalize:. Let’s do it in a way similar to the one we used when fixing the read_words function, except this time we’ll use a live template instead of writing the list comprehension manually. Type compl and press Enter. Then specify all elements of the list comprehension, and press Tab to move to the next element.

This is what you should get:

def main(capitalize: bool = False): sub_nouns = read_words('sub_nouns.txt') verbs = read_words('verbs.txt') adjectives = read_words('adjectives.txt') obj_nouns = read_words('obj_nouns.txt') word_bank = [sub_nouns, verbs, adjectives, obj_nouns] phrase_words = [] for word_list in word_bank: random_word = random.SystemRandom().choice(word_list) phrase_words.append(random_word) if capitalize: phrase_words = [phrase_word.capitalize() for phrase_word in phrase_words] passphrase = ''.join(phrase_words) print(passphrase)

To make sure that the capitalization works correctly, we need to pass capitalize as an argument when running main.py. To achieve this, let’s edit the run configuration. Look for the Run widget at the top of the IDE window:

You can use the widget to select the desired run configuration, as well as to launch it in either run or debug mode. PyCharm has already created the main configuration when we clicked the gutter icon and launched the script. Click the configuration name to open the menu, and then select Edit configurations:

In the dialog that opens, specify --capitalize in the Parameters field:

Click OK to save the updated configuration. Then click the run icon in the widget.

Here’s the result:

For better readability, we can separate the words in our passphrases. Using special characters as separators will serve a double purpose, as it will let us generate passphrases that comply with specific password complexity requirements.

Edit the second-to-last line of the main() function as follows:

def main(capitalize: bool = False): ... passphrase = separator.join(phrase_words)

PyCharm highlights separator with a red squiggly line, because the function doesn’t have this parameter yet. Hover the mouse over it and select Create parameter ‘separator’ in the popup. Then specify ‘’ as its default value, because we don’t want to add any separator by default.

Let’s also specify str as the parameter type. Here’s what you should get:

def main(capitalize: bool = False, separator: str = ''): ... passphrase = separator.join(phrase_words) print(passphrase)

Now, you’ll definitely want to check out the result. Don’t forget to update the run configuration first. Click the Run widget, select Edit configurations, and add the new parameter in the Parameters field:

Run the configuration to see the result:

Now you can separate words in your passphrases with special characters and numbers. You can even use several symbols to satisfy the password requirements of various websites, for example “#4” or “%7”.

Make them harder to crack

The longer the passphrase, the more attempts are needed for a successful brute force attack. Let’s include an extra word in our passphrases.

First, we’ll prepare a fifth word list containing adverbs and put it in the project directory. Add the long parameter of bool type to the signature of the main() function. Depending on this parameter (which is optional and set to False by default), we will add another word list to word_bank:

def main(capitalize: bool = False, separator: str = '', long: bool = False): ... word_bank = [sub_nouns, verbs, adjectives, obj_nouns] if long: adverbs = read_words('adverbs.txt') word_bank.append(adverbs) ...

This time, let’s run the script by using the built-in terminal. Press ⌥F12/ Alt+F12 and type the following command in the Terminal tool window that opens:

python main.py --capitalize --separator "1_" --long

You should get something similar to the following:

Prepare the tool for use Define short option names

If you have used CLI tools before, you know that they usually let the user specify arguments with only one letter. Let’s add this functionality to our tool as well. For better code readability, let’s reformat the function signature, so that each parameter is on a separate line:

def main( capitalize: bool = False, separator: str = '', long: bool = False ): ...

Then replace the default value of each parameter with typer.Option(<default_value>, <long_name>, <short_name>):

Here’s the final signature of main():

def main( capitalize: bool = typer.Option(False, '--caps', '-c'), separator: str = typer.Option('', '--separator', '-s'), long: bool = typer.Option(False, '--long', '-l') ): ...

Now we can specify all options together. The separator (‘-s’) should go last, because it requires a string after it:

Document the options

By default Typer also adds the --help option. Let’s see how it works now:

We can understand which parameters exist and what their long and short names are. How about adding comments to explain what they actually do? Add help for each parameter of main() as follows:

def main( capitalize: bool = typer.Option(False, '--caps', '-c', help='Capitalize each word.'), separator: str = typer.Option('', '--separator', '-s', help='Separate words with the given symbol.'), long: bool = typer.Option(False, '--long', '-l', help='Make the passphrase longer by including an adverb.') ): ...

Now --help produces much more useful information:

You may want to use the passphrase generator without PyCharm, for example in the system terminal. In this case, you should install Typer to your system interpreter by using the following command:

python3 -m pip install --user typer Summary

In this tutorial, you have learned how to:

  • Create projects in PyCharm Community Edition.
  • Develop user-friendly CLI tools with Python and Typer.
  • Use quick-fixes and live templates to write code faster and avoid errors.
  • Debug your code.
  • Run your code in PyCharm by using run configurations and the terminal.
Categories: FLOSS Project Planets

Lullabot: Questions to Ask When Choosing a Drupal Hosting Platform

Planet Drupal - Wed, 2023-05-10 11:01

Every website needs a host, and a fantastic website on a mismatched hosting platform can become a terrible website. You've spent a lot of time and money on your website (or websites). Deciding where to host should not be an afterthought. 

Complex websites with content management, media management, and authenticated users have more complex hosting requirements than simple static websites. If your project warrants a CMS like Drupal, you need to ensure your hosting platform matches.

Categories: FLOSS Project Planets

Real Python: Python News: What's New From April 2023

Planet Python - Wed, 2023-05-10 10:00

Spring is in bloom, bringing new and exciting developments in the Python world. The last preview release of Python 3.12 before the feature freeze, a new major version of pandas, pip and PyPI improvements, and PyCon US 2023 are a few of them.

Grab a cup of your favorite beverage, sit back comfortably in your chair, and enjoy a fresh dose of Python news from the past month!

Join Now: Click here to join the Real Python Newsletter and you'll never miss another Python tutorial, course update, or post.

Python 3.12.0 Alpha 7 Is Now Available

Python 3.12.0 alpha 7 became available to the public on April 4, marking the final alpha version before the planned transition to the beta phase, which will begin a partial feature freeze. Beyond this point, most development efforts will focus on fixing bugs and making small improvements without introducing significant changes in the codebase. But existing features could be changed or dropped until the release candidate phase.

While we’re still a few months away from the final release in October, we already have a pretty good idea about the most notable features that should make it into Python 3.12:

But you don’t have to wait until the fall to get your hands on these upcoming features. You can check them out today by installing a pre-release version of Python, remembering that alpha and beta releases are solely meant for testing and experimenting. So, never use them in production!

If you happen to find something that isn’t working as expected, then don’t hesitate to submit a bug report through Python’s issue tracker on GitHub. Testing pre-release versions of Python is one of the reasons why they’re available to early adopters in the first place. The whole Python community will surely appreciate your help in making the language as stable and reliable as possible.

Note: For a full list of features implemented in the Python 3.12.0 alpha 7 release, have a glimpse at its changelog, which includes links to the respective GitHub tickets.

The Python 3.12.0 alpha 7 release brings us one step closer to the final version, but there’s still a lot of work to be done. These ongoing efforts may sometimes affect the official release schedule, so keep an eye on it and stay tuned for more updates in the coming months.

pandas 2.0 Receives a Major Update With PyArrow Integration

The popular Python data analysis and manipulation library pandas has recently released its latest version, pandas 2.0.0, followed by a patch release shortly after. These updates finalize a release candidate that became available a few months ago.

Historically, pandas has relied on NumPy as its back end for storing DataFrame and Series containers in memory. This release introduces an exciting new development in the form of optional PyArrow engine support, providing the Apache Arrow columnar data representation. However, nothing is changing by default, as the developers behind pandas aim to accommodate their large user base and avoid introducing breaking changes.

You now have the option to request the PyArrow back end instead of NumPy, as you can see in the following code snippets:

>>>>>> import pandas as pd >>> pd.Series([1, 2, None, 4], dtype="int64[pyarrow]") 0 1 1 2 2 <NA> 3 4 dtype: int64[pyarrow] >>> df = pd.read_csv("file.csv", engine="pyarrow", dtype_backend="pyarrow") >>> df.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 21 entries, 0 to 20 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 21 non-null date32[day][pyarrow] 1 transaction_no 21 non-null int64[pyarrow] 2 payment_method 21 non-null string[pyarrow] 3 category 21 non-null string[pyarrow] 4 item 21 non-null string[pyarrow] 5 qty 21 non-null double[pyarrow] 6 price 21 non-null string[pyarrow] 7 subtotal 21 non-null string[pyarrow] 8 comment 21 non-null string[pyarrow] dtypes: date32[day][pyarrow](1), double[pyarrow](1), int64[pyarrow](1), string[pyarrow](6) memory usage: 1.8 KB Read the full article at https://realpython.com/python-news-april-2023/ »

[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

Categories: FLOSS Project Planets

Python for Beginners: Tuple vs List in Python: Syntax, Definition, and Performance

Planet Python - Wed, 2023-05-10 09:00

In Python, tuples and lists are similar data structures apart from mutability. This article discusses Python tuple vs list to compare the syntax, definition, mutability, and performance of both data structures. 

Table of Contents
  1. Tuple vs List Definition
  2. Tuple vs List Syntax
  3. Tuple vs List Mutability
  4. Python Tuple vs List Performance
  5. When to Use Tuple vs List in Python?
  6. Conclusion
Tuple vs List Definition

A Python list is a mutable data structure that we use to store elements in a sequential manner. We use a list to store data when we need random access to the elements.

A tuple is an immutable data structure that we use to store elements. A tuple in Python has all the properties of a list except mutability. 

Tuple vs List Syntax

Tuple and List have different syntaxes. We use square brackets to define a list. On the other hand, parentheses are used to define a tuple. You can observe this in the following example.

myList=[1,2,4,5,6,6,7,8,99,33,4324,2,672] myTuple=(1,2,4,5,6,6,7,8,99,33,4324,2,672)

Similarly, we use the list() function to create a list whereas the tuple() function to create a tuple from an existing collection object such as a set. You can observe this in the following example.

mySet={1,2,3,4,5} myList=list(mySet) myTuple=tuple(mySet) Tuple vs List Mutability

A python tuple is immutable whereas a list is mutable. If you try to change a tuple by any means, the program will run into an error.

  • We cannot add an element to a Python tuple. On the other hand, we can add elements as well as other container objects to an existing list. 
  • We can delete elements from a list. On the contrary, we cannot delete any element from an existing Python tuple.
Python Tuple vs List Performance

If we traverse a tuple and a list, traversing a tuple is more efficient than traversing a list. 

  • The performance of a tuple in this case is at least 10 percent better than a Python list.
  • A tuple has a fixed size. So, it contains occupies only the space needed for its elements. On the other hand, a list occupies almost double the space needed by its elements. This makes Python lists inefficient compared to tuples.

Considering the above points, we can say that a Python tuple has better performance than a list.

For example, 

  • Traversing a list containing 13 elements takes almost 209 ns ± 36 ns per loop when we do nothing except traverse the list.
  • Traversing a Python tuple with the same number of elements takes 191 ns ± 16.3 ns which is a considerably lower time. 

You can observe this in the following example.

Python Tuple vs List Performance When to Use Tuple vs List in Python?

If you don’t need to change the data in the sequence after defining it, you should use a Python tuple. If you need to add, update, or delete elements from a sequence, you should use a list in Python.


In this article, we had a discussion about tuple vs list in Python to have a look at the definition, syntax, and performance of both data structures. To learn more about Python programming, you can read this article on for loop vs while loop in Python. You might also like this article on if vs elif vs else if in Python.

I hope you enjoyed reading this article. Say tuned for more informative articles.

Happy learning!

The post Tuple vs List in Python: Syntax, Definition, and Performance appeared first on PythonForBeginners.com.

Categories: FLOSS Project Planets

LN Webworks: Top Drupal LMS Features for Your Ed-Tech Business

Planet Drupal - Wed, 2023-05-10 03:56

Since its inception as an open-source Content Management System (CMS) in 2001, Drupal has grown into a technology that is trusted by many major corporations and governments around the world. The platform is constantly updated with the latest digital technologies by a community of more than 124k contributors. Drupal is not just a platform; it's a community made up of individuals who are passionate about open-source development. With Drupal Development Services, businesses can leverage the capabilities of this platform to develop custom solutions to fulfill specific requirements. This dedication has led to alternative solutions such as Learning Management Systems that are built on Drupal's backbone. We will examine the features of Drupal LMS for edtech businesses in this article.

Categories: FLOSS Project Planets

LN Webworks: Top 7 Drupal LMS Features for Your Ed-Tech Business

Planet Drupal - Wed, 2023-05-10 03:56

Since its inception as an open-source Content Management System (CMS) in 2001, Drupal has grown into a technology that is trusted by many major corporations and governments around the world. The platform is constantly updated with the latest digital technologies by a community of more than 124k contributors. Drupal is not just a platform; it's a community made up of individuals who are passionate about open-source development. With Drupal Development Services, businesses can leverage the capabilities of this platform to develop custom solutions to fulfill specific requirements. This dedication has led to alternative solutions such as Learning Management Systems that are built on Drupal's backbone. We will examine the features of Drupal LMS for edtech businesses in this article.

Categories: FLOSS Project Planets

PreviousNext: Catch PreviousNext at DrupalSouth 2023 in Wellington

Planet Drupal - Wed, 2023-05-10 02:28

Need help planning your visit to DrupalSouth Wellington next week? Here’s the complete rundown of sessions our PreviousNext colleagues will be presenting! Will we see you there?

by kim.pepper / 10 May 2023

With not long to go, we hope you’re looking forward to DrupalSouth 2023 as much as we are! 

Several of our PreviousNext colleagues will be presenting over the two days in Wellington, so here’s a summary of what you can expect to hear.

Creating the optimal editorial experience with Layout Builder

Speaker: Daniel Veza

Time: Wednesday 17th May 12:00-12:30
Room: Main Theatre
Track: Drupal Development

Layout Builder can be intimidating. But it doesn’t have to be! Discover modules that enhance and control the Layour Builder experience, keeping the front end consistent.

See Daniel’s session in the DrupalSouth schedule

Getting the most from your CI/CD experience

Speaker: Karl Hepworth

Time: Wednesday 17th May 12:00-12:30
Room: Track 1
Track: Web Tools & Technologies

How do you get the most from your CI/CD experience? 

Karl will dive into a maturity model that evaluates how far you are into the DevOps experience and look at the opportunities to be had and where your journey will take you.

See Karl’s session in the DrupalSouth schedule

Drupal Hosting Security Panel

Speaker: Kim Pepper; plus panellists Mike Richardson, Nick Schuch, Nick Santamaria, Scott Leggett

Time: Wednesday 17th May 13:30-14:00
Room: Main Theatre
Track: Web Tools & Technologies

Get your tough questions ready! 

The Drupal Hosting Security Panel brings together some of Drupal’s hosting experts, including PNXers Kim Pepper and Nick Schuch.

See the hosting security panel in the DrupalSouth schedule

How much does a polar bear weigh?

Speaker: Fonda Duffy

Time: Wednesday 17th May 13:30-13:45
Room: Track 2
Track: Showcases & Project Management

If you don’t know how that joke ends, Fonda may be able to help in her talk about the role of icebreakers in building and maintaining team connections.

See Fonda’s session in the DrupalSouth schedule

Vue JS for React JS developers and vice versa

Speaker: Lee Rowlands

Time: Wednesday 17th May 14:15-14:45
Room: Track 1
Track: Web Tools & Technologies

In React, you call useState to store state, in Vue, you use a ref. 

In React, you use a ref to keep track of something between renders, in Vue, you also use a ref for that. 

Confused? Come along to hear Lee compare React and Vue, and learn they're not that different.

See Lee’s session in the DrupalSouth schedule

Building an API with GraphQL 4

Speaker: Adam Bramley

Time: Wednesday 17th May 15:00-15:30
Room: Track 1
Track: Drupal Development

The GraphQL Drupal module’s out-of-the-box toolkit for writing GraphQL APIs is powerful, but it can also be hard to get your head around the concepts. 

In his session, Adam will cover how to get started and how all those puzzle pieces fit together.

See Adam’s session in the DrupalSouth schedule

The road to zero friction testing - getting the most out of Drupal Testing Traits

Speaker: Michael Strelan

Time: Thursday 18th May 10:00-10:30
Room: Main Theatre
Track: Drupal Development

Join Michael for a journey along the road to zero friction testing, aka getting the most out of Drupal Testing Traits. 

In his session, he'll show you real-world approaches from large client projects that make writing new tests a breeze. With some basic foundations in place, adding new tests can become smooth like butter.

See Michael’s session in the DrupalSouth schedule

Next-level Search API

Speaker: Saul Willers

Time: Thursday 18th May 13:00-13:30
Room: Main Theatre
Track: Drupal Development

How can you achieve next-level Search API? 

In his session, Saul will explore some of the lesser-known or "enterprise" features that can extend Search API and help solve the problems you face.

See Saul’s session in the DrupalSouth schedule

A Case Study On Building A Cloud Native Platform

Speaker: Nick Schuch

Time: Thursday 18th May 13:00-13:30
Room: Track 1
Track: Web Tools & Technologies

Nick will present a case study for building a cloud-native platform. 

Join him for a walk-through of how the Skpr hosting platform came to be and the lessons we learned along the way.

See Nick’s session in the DrupalSouth schedule

Code Contribution Sprint

Time: Friday 19th May 09:00 - 15:00
Location: 93 Cuba Street, Te Aro, Wellington 6011

Find out how to get involved in the Code Sprint


Don't forget to check our blog over the coming weeks as we share more on these topics!

Categories: FLOSS Project Planets

Django Weblog: Announcing DjangoCon Africa 2023

Planet Python - Wed, 2023-05-10 02:00

The African Django community is excited to announce the first DjangoCon Africa event, taking place this year in Zanzibar, Tanzania, from 6th - 11th November 2023. The first event since the global pandemic postponed our planning in 2020. We are thrilled to convene, support one another and give back to the African Python web community now that travel and health safety guidelines have normalized.

DjangoCon Africa 2023 will be held at the State University of Zanzibar where we have three meeting rooms, one auditorium, 15 minutes away from food and activities, and convenient access to students, professionals, and international travelers.

About DjangoCon Africa

DjangoCon Africa will include 3 days of single-track talks, 2 days of workshops and sprints, and one day of touring for international visitors.

The event will also include a Django Girls workshop to be held the weekend before DjangoCon Africa. To make the conference as inclusive as possible, the event will offer financial aid to members of under-represented communities in software to ensure they can also attend.

The CFP, which is open to all, will also be announced as soon as the month of June.


The success of DjangoCon Africa lies hugely in the sponsorship of organizations and individuals within the Python/Django community. We are appealing to organizations and individuals to help us make DjangoCon Africa possible by sponsoring the event.

If you are interested in sponsoring DjangoCon Africa 2023, please contact the team at sponsors@djangocon.africa.

Categories: FLOSS Project Planets