FLOSS Project Planets

PyCoder’s Weekly: Issue #496 (Oct. 26, 2021)

Planet Python - Tue, 2021-10-26 15:30

#496 – OCTOBER 26, 2021
View in Browser »

Writing Idiomatic Python

What are the programming idioms unique to Python? This course is a short overview for people coming from other languages and an introduction for beginners to the idiomatic practices within Python. You’ll cover truth values, looping, DRY principles, and the Zen of Python.

Notes From the Meeting on Python GIL Removal Between Python Core and Sam Gross

“During the annual Python core development sprint we held a meeting with Sam Gross, the author of nogil, a fork of Python 3.9 that removes the GIL. This is a non-linear summary of the meeting.”

Analyze Code-Level Application Performance Across Your Entire Environment With Datadog APM

Datadog’s distributed tracing and APM generates flame graphs from real requests, enabling you to visualize app performance and pinpoint hard-to-reproduce problems in your production code. Without switching tools, you can pivot to related logs and metrics for full context. Try Datadog APM free →
DATADOG sponsor

PEP 660: Editable Installs for pyproject.toml Based Builds (Wheel Based)

“Now that PEP 517 provides a mechanism to create alternatives to setuptools, and decouple installation front ends from build backends, we need a new mechanism to install packages in editable mode.”

Django 4.0 Beta 1 Released

Check out the work-in-progress development release notes for more details.

PyCon US 2022: Conference Website Launched

PyCon US 2022 takes place in Salt Lake City, Utah from April 27, 2022 to May 5, 2022.

Vicky Twomey-Lee Awarded the PSF Community Service Award for Q3 2021


Discussions What Is Your Most Controversial Python-Related Opinion?

“I like lambdas.”

Python Jobs Full Stack Software Engineer Django/Postgres/React (Washington D.C.)


Senior Software Engineer (Washington D.C.)


Senior Python Engineer @ Moody's AI & ML Center of Excellence (New York, NY, USA)


Senior Software Engineer (Washington D.C.)


Full Stack Developer (Anywhere)

Level 12

Software Engineer (Anywhere)

1Point21 Interactive

More Python Jobs >>>

Articles & Tutorials The Composition Over Inheritance Principle

“In Python as in other programming languages, this grand principle encourages software architects to escape from Object Orientation and enjoy the simpler practices of Object Based programming instead.”

Using the “not” Boolean Operator in Python

In this step-by-step tutorial, you’ll learn how Python’s “not” operator works and how to use it in your code. You’ll get to know its features and see what kind of programming problems you can solve by using “not” in Python.

How to Quickly Label Data for Machine Learning

With Toloka, you can control the accuracy and speed of data labeling to develop high performing ML models.  Our platform supports annotation for image classification, semantic segmentation, object detection, named entity recognition, sentiment analysis, speech recognition, text classification →
TOLOKA AI sponsor

Using the len() Function in Python

In this tutorial, you’ll learn how and when to use the len() Python function. You’ll also learn how to customize your class definitions so that objects of a user-defined class can be used as arguments in len().

PEP 670 [Draft]: Convert Macros to Functions in the Python C API

“Converting macros and static inline functions to regular functions makes these regular functions accessible to projects which use Python but cannot use macros and static inline functions.”

A NASA TV Still Frame Viewer in Python

Spacestills is a Python program for viewing NASA TV still frames. It’s a learning project based on the PySimpleGUI GUI framework.

A New, Free Python Code Quality & Security Scanner With Real-Time Scanning

Like Grammarly for your code. Scan your Python code for quality & security issues, and get fix advice in your IDE. Get started with Snyk for free.
SNYK.IO sponsor

Storing Data on a Cassette Using Arduino and Python (Differential Manchester Encoding)


What the global Statement Really Means in Python


Building a Recommendation Engine Inside Postgres With Python and Pandas


Forgot to Set Up a Custom Exception Hook? Perhaps It Is Not Too Late


Projects & Code noaa-apt-decoder: Decoding NOAA Weather Satellite Images Using Python


nMigen: Python Toolbox for Building Complex Digital Hardware


traviscli: Semantically Version Your Python Project on TravisCI

GITHUB.COM/HASII2011 • Shared by Humberto Sanchez II

Ordained: An Opinionated Template for Python Packages

BRYAN WOOD • Shared by Bryan Wood

staircase: Data Analysis and Manipulation With Mathematical Step Functions

STAIRCASE.DEV • Shared by Riley Clement

django-dynamic-admin-forms: Add Simple Interactions to Django Admin


fork-purger: Delete All of Your Forked Repositories on Github

GITHUB.COM/REDNAFI • Shared by Redowan Delowar

DearPyGui 1.0.0: A GPU Accelerated Python GUI Framework


Events Plone Conference 2021 Online

October 23 to November 1, 2021

Weekly Real Python Office Hours Q&A (Virtual)

October 27, 2021

PyData Global 2021

October 28 to October 31, 2021

PythOnRio Meetup

October 30, 2021

Melbourne Python Users Group

November 1, 2021

PyCon Chile

November 5 to November 8, 2021

deploy by DigitalOcean

November 16 to November 17, 2021

Happy Pythoning!
This was PyCoder’s Weekly Issue #496.
View in Browser »

[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]

Categories: FLOSS Project Planets

Bounteous.com: Supercharging Drupal Platforms With the Power of Acquia

Planet Drupal - Tue, 2021-10-26 14:09
Drupal is a powerful content management platform, and Acquia offers a suite of world-class digital marketing solutions. Together, they create the leading open digital experience platform.
Categories: FLOSS Project Planets

Paolo Amoroso: How to Add Code Syntax Highlighting to Blogger

Planet Python - Tue, 2021-10-26 12:01

On my blog I always wanted to format source code in Python and a couple more languages, but couldn’t find a convenient way. Until I read a tutorial on adding syntax highlighting to Blogger blogs like mine.

The Blogger post composer actually provides the monospace Courier font that may be used for source code, but it works well only for inline text.

If I apply the Courier font to a block of code, the composer renders each line as a separate paragraph. This leaves too much vertical space that makes the code look ugly. A workaround is to switch to the HTML view in the composer and wrap the block within <pre> ... </pre> tags, which insert the correct line spacing. However, the code doesn’t stand out on the page and there’s room for improving its scannability and visual impact.

Fortunately, Blogger is an old dog I can teach new tricks to, like the setup the tutorial I found presents.

A Python code snippet with syntax highlighting rendered by highlights.js in a post of the Moonshots Beyond the Cloud blog.

The setup relies on highlight.js, an open-source JavaScript library for syntax highlighting of source code in a couple hundred languages with dozens of styles. All it takes is adding three lines to the HTML header of the Blogger theme, and wrapping code blocks within <pre><code> ... </code></pre> in the HTML view of the composer.

I’ll explain how I configured my blog for syntax highlighting and how I apply the formatting to code blocks. 

Getting highlight.js

There are several ways of using highlight.js and I went with the most straightforward.

The first, onetime step is to edit the blog’s header to add HTML code to fetch the library when a browser loads a page of the blog. I edited the HTML source of the blog theme and inserted these lines toward the end of the <head> section:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/default.min.css" integrity="sha512-3xLMEigMNYLDJLAgaGlDSxpGykyb+nQnJBzbkQy2a0gyVKL2ZpNOPIj1rD8IPFaJbwAgId/atho1+LBpWu5DhA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js" integrity="sha512-Pbb8o120v5/hN/a6LjF4N4Lxou+xYZ0QcVF8J6TWhBbHmctQWd8O6xTDmHpE/91OjPzCk4JRoiJsexHYg4SotQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

The first two lines fetch the components of highlights.js from the cdnjs CDN. The third line calls the library’s entry point.

This configuration step is covered in the usage instructions page of the highlights.js documentation under “Basic usage” > “In the browser”. The sample code there is generic and needs to be fleshed out with links to the latest version of the library. The third line of the sample code, <script>hljs.highlightAll();</script>, calls the library and I copied it as is to the blog header as the third line of my configuration snippet above.

The simplest way of linking to the latest version, which is what I did, is to fetch the library from a CDN such as cdnjs.

Section “Fetch via CDN” on the same instructions page includes a code snippet with up-to-date links, which shouldn't be used as is. Why? Because the snippet is vulnerable to downloading compromised versions of the library.

Subresource integrity can address this security issue. Here’s how. I clicked the link next to the name of the cdnjs CDN, again on the same instructions page of the highlights.js documentation. The link leads to a cdnjs tool that generates code snippets with the appropriate digests for checking subresource integrity. The entries I needed are those for the files default.min.css and highlight.min.js.

I finally put together the three pieces in my snippet, i.e. the two lines for fetching the library and the third to call it, and added them to the blog header.

I prefer light designs, so the default light theme of highlights.js works well for me, blends nicely with the design of my Blogger theme, and requires no additional configuration. The library comes with dozens of light and dark themes, though.

Once configured, highlights.js requires no other setup, and the blog is ready to format code blocks with syntax highlighting.

Formatting code blocks

To add a block of code to a post, I paste it into the composer at the right spot. Then I switch to the HTML view and wrap the code within <pre><code> ... </code></pre>, taking care of removing any <p> tags. For longer blocks it’s easier to insert a placeholder where the block should be and paste the full code there in the HTML view, thus saving the effort of removing the tags.

Highlights.js auto detects the language and no further action is usually necessary.

Besides ordinary Python, there are a couple more options of the class attribute I can add to the <code> tag, one for profiler results and another for REPL sessions. For example, wrapping a block within <pre><code class="language-python-repl">...</code></pre> formats a block of a Python REPL session.

As for inline code, I still select it in the composer and apply the Courier font. This is good enough for running text, and it matches the way inline code is typically formatted without highlighting on other sites. Besides, highlights.js works only with blocks.

Code samples

To test highlights.js I applied syntax highlighting to the code blocks of an old post about Spacestills, a NASA TV still frame viewer I wrote in Python. The result looked good, so here is a longer Python example, the main function of Spacestills that runs the PySimpleGUI event loop:

def main():
"""Run event loop."""
window = sg.Window('Spacestills', LAYOUT, finalize=True)
current_still = refresh(window)

delta = DELTA
next_reload_time = datetime.now() + timedelta(seconds=delta)

while True:
event, values = window.read(timeout=100)
if event in (sg.WIN_CLOSED, 'Exit'):
elif ((event == '-RELOAD-') or
(values['-AUTORELOAD-'] and timeout_due(next_reload_time))):
current_still = refresh(window, values['-RESIZE-'])
if values['-AUTORELOAD-']:
next_reload_time = next_timeout(delta)
elif event == '-RESIZE-':
current_still = change_aspect_ratio(
window, current_still, current_still.new_size())
elif event == '-SAVE-':
filename = sg.popup_get_file(
'File name', file_types=[('PNG', '*.png')], save_as=True,
title='Save image', default_extension='.png')
if filename:
saved = save(current_still, filename)
if not saved:
sg.popup_ok('Error while saving file:', filename, title='Error')
elif event == '-UPDATE_DELTA-':
# The current cycle should complete at the already scheduled time. So
# don't update next_reload_time yet because it'll be taken care of at the
# next -AUTORELOAD- or -RELOAD- event.
delta, valid = validate_delta(values['-DELTA-'])
if not valid:

del window

Next, let’s format a short function taken from Suite8080, a suite of Intel 8080 Assembly cross-development tools I’m writing in Python. The function processes the mov mnemonic in the assembler:

# mov: 0x40 + (8-bit first register offset << 3) + (8-bit second register offset)
# mov m, m: 0x76 (hlt)
def mov():
check_operands(operand1 != '' and operand2 != '')
# 0x40 = 64
opcode = 64 + (register_offset8(operand1) << 3) + register_offset8(operand2)
pass_action(1, opcode.to_bytes(1, byteorder='little'))

Finally, some code in a different language. This is the source of the hello world Intel 8080 Assembly program for CP/M that’s part of Suite8080:

; Hello world for CP/M

org 100h
bdos equ 0005h ; BDOS entry point
wstrf equ 09h ; BDOS function: write string

mvi c, wstrf
lxi d, message
call bdos

message: db 'Greetings from Suite8080.$'

Highlights.js supports only ARM, AVM, and x86 Assembly but not Intel 8080 (too bad such a bleeding edge chip is missing), so this time it didn’t detect the language. However, the result still looks reasonably good and I’m ready to publish more code.

This post by Paolo Amoroso was published on Moonshots Beyond the Cloud.

Categories: FLOSS Project Planets

Drupal Association blog: Drupal Association At-Large Board Election 2021 - winner announced

Planet Drupal - Tue, 2021-10-26 11:09

The Drupal Association would like to congratulate our newest At-Large board member:

Mike Herchel.

Mike Herchel is a front-end developer that’s been developing with Drupal for over 13 years. He is the primary organizer and lead developer for the Olivero initiative, which aims to create a new default front-end theme for Drupal core. Mike is also the maintainer of the Drupal Quicklink module, and is a primary organizer for Florida DrupalCamp.

Mike works as a senior front-end developer for Lullabot, where he co-hosts the Lullabot Podcast. He’s passionate about web performance, usability, and accessibility. You can often find him speaking on these subjects at DrupalCamps, DrupalCons, and various other web development conferences.

Upon accepting the nomination, Mike replied, "I'm thrilled to have the privilege to join the board of the Drupal Association! During this time, I intend to advocate for better usability on Drupal.org and focus on smaller scale Drupal websites to help make our community as strong, diverse, and thriving as possible."

Thank you to all 2021 candidates

On behalf of all the staff and board of the Drupal Association, and I’m sure the rest of the Drupal community, I would like to thank all of those people who stood for the election this year. It truly is a big commitment to contribution and one to be applauded. Thank you for your willingness to serve, and I hope you’ll consider participating again in 2022!

Detailed Voting Results

There were 8 candidates in this year’s At-Large board member election.

504 voters cast their ballots out of a pool of 2,472 eligible voters.

Under Approval Voting, each voter can give a vote to one or more candidates. The final total of votes was as follows:

Candidate Votes Mike Herchel 277 Imre Gmelig Meijling 227 Surabhi Gokte 199 Will Huggins 138 Kana Tadadjo Patrick Jaures 132 Joshua Fernandes 105 Brad Czerniak 92 Dmitry Porokhnya 29
Categories: FLOSS Project Planets

GNU Guix: From ‘guix environment’ to ‘guix shell’

GNU Planet! - Tue, 2021-10-26 11:00

There are times when what looked like the right design choice some years back comes out as an odd choice as time passes. The beloved guix environment tool is having that fate. Its command-line interface has become non-intuitive and annoying for the most common use cases. Since it could not be changed without breaking compatibility in fundamental ways, we devised a new command meant to progressively replace it; guix shell—that’s the name we unimaginatively ended up with—has just landed after a three-week review period, itself a followup to discussions and hesitations on the best course of action.

This post introduces guix shell, how it differs from guix environment, the choices we made, and why we hope you will like it.

The story of guix environment

The guix environment command started its life in 2014, when Guix was a two-year old baby and the whole community could fit in a small room. It had one purpose: “to assist hackers in creating reproducible development environments”. It was meant to be similar in spirit to VirtualEnv or Bundler, but universal—not limited to a single language. You would run:

guix environment inkscape

… and obtain an interactive shell with all the packages needed to hack on Inkscape; in that shell, the relevant environment variables—PATH, CPATH, PKG_CONFIG_PATH, and so on—would automatically point to a profile created on the fly and containing the compiler, libraries, and tools Inkscape depends on, but not Inkscape itself.

Only a year later did it become clear that there are cases where one would want to create an environment containing specific packages, rather than an environment containing the dependencies of packages. To address that, David Thompson proposed the --ad-hoc option:

guix environment --ad-hoc inkscape -- inkscape

… would create an environment containing only Inkscape, and would then launch the inkscape command in that environment. Many features were added over the years, such as the invaluable --container option, but these two modes, development and “ad hoc”, are the guts of it.

Fast forward six years: today, there’s consensus that the name --ad-hoc is confusing for newcomers and above all, that the “ad hoc” mode should be the default. This is the main problem that guix shell addresses.

Doing what you’d expect

Changing the default mode from “development environment” to “ad hoc” is technically easy, but how to do that without breaking compatibility is harder. This led to lengthy discussions, including proposals of mechanisms to choose between the new and old semantics.

In the end, keeping the guix environment name while allowing it to have different semantics was deemed dangerous. For one thing, there’s lots of material out there that demoes guix environment—blog posts, magazine articles, on-line courses—and it would have been impossible to determine whether they refer to the “new” or to the “old” semantics. We reached the conclusion that it would be easier to use a new command name and to eventually deprecate guix environment.

With guix shell, the default is to create an environment that contains the packages that appear on the command line; to launch Inkscape, run:

guix shell inkscape -- inkscape

The --ad-hoc option is gone! Likewise, to spawn an ephemeral development environment containing Python and a couple of libraries, run:

guix shell python python-numpy python-scipy -- python3

Now, if you want, say, the development environment of Inkscape, add the --development or -D option right before:

guix shell -D inkscape

You can add Git and GDB on top of it like so:

guix shell -D inkscape git gdb

(Note that -D only applies to the immediately following package, inkscape in this case.) It’s more concise and more natural than with guix environment. As can be seen in the manual, all the other options supported by guix environment remain available in guix shell.

Short-hands for development environments

A convention that’s become quite common is for developers to provide a guix.scm at the top of their project source tree, so that others can start a development environment right away:

guix environment -l guix.scm

The guix.scm file would contain a package definition for the project at hand, as in this example. This option is known as -f in guix shell, for consistency with other commands, and the equivalent command is:

guix shell -D -f guix.scm

Since all Guix commands accept a “manifest” with -m, another option is to provide a manifest.scm file and to run:

guix shell -m manifest.scm

“Wouldn’t it be nice if guix shell would automatically follow these conventions when not given any argument?”, some suggested. As in the case of Bundler, direnv, or typical build tools from Meson to Make, having a default file name can save typing and contribute to a good user experience for frequently-used commands. In this spirit, guix shell automatically loads guix.scm or manifest.scm, from the current directory or an ancestor thereof, such that entering a project to hack on it is as simple as:

cd ~/my/project/src guix shell

Worry not: guix shell loads guix.scm or manifest.scm if and only if you have first added its directory to ~/.config/guix/shell-authorized-directories. Otherwise guix shell warns you and prints a hint that you can copy/paste if you want to authorize the directory.

Caching environments

With that in place, guix shell can pretty much fill the same role as direnv and similar tools, with one difference though: speed. When all the packages are already in store, guix shell can take one to a few seconds to run, depending on the package set, on whether you’re using a solid state device (SSD) or a “spinning” hard disk, and so on. It’s acceptable but prohibitively slow for direnv-like use cases.

To address that, guix shell maintains a profile cache for the -D -f guix.scm and -m manifest.scm cases. On a hot cache, it runs in 0.1 second. All it has to do is fork a shell with the right environment variable definitions; it does not talk to guix-daemon, and it does not even read guix.scm or manifest.scm (it’s possible to forcefully update the cache with --rebuild-cache).

That makes guix shell usable even for short-lived commands like make:

guix shell -- make

Hopefully it’ll change the way we use the tool!

The shell doctor

While revamping this command-line interface, the idea of a “shell doctor” came up. In interactive use, guix shell sets environment variables and spawns a shell, but it’s not uncommon for the shell to mess up with the whole environment. Why? Because, contrary to documented practice, it’s quite common for users to define or override environment variables in the startup files of non-login shells, ~/.bashrc for Bash, ~/.zshrc for Zsh. Instead, environment variable definitions should go to the startup file of login shells—~/.bash_profile, ~/.profile, or similar. But let’s face it: it’s a subtle distinction that few of us know or care about.

As a result, users of Guix, especially on distros other than Guix System, would often be disappointed when running guix environment --pure and yet find that PATH contains non-Guix entries, that there’s a bogus LD_LIBRARY_PATH definition, and whatnot. Now, they can call the doctor, so to speak, to obtain a diagnosis of the health of their shell by adding the --check flag:

guix shell --check python python-numpy

The command creates an environment containing Python and NumPy, spawns an interactive shell, checks the environment variables as seen by the shell, and prints a warning if PATH or PYTHONPATH in this case have been overridden. It does not tell users where the problem comes from—it cannot guess—but it tells them if something’s wrong, which is a first step.

Of course, the best way to sidestep these problems is to pass --container, which gives a fresh, isolated environment that does not contain those startup files. That’s not always an option though, for instance on systems lacking support for unprivileged user namespaces, so --check comes in handy there.

Try it!

Just run guix pull to get this shiny new guix shell thingie!

If you don’t feel ready yet, that’s OK: guix environment won’t disappear overnight. We have a written commitment to keep it around until May, 1st 2023. Though overall, we hope you’ll find the guix shell interface easier to use and compelling enough that you’ll be willing to switch overnight!

About GNU Guix

GNU Guix is a transactional package manager and an advanced distribution of the GNU system that respects user freedom. Guix can be used on top of any system running the Hurd or the Linux kernel, or it can be used as a standalone operating system distribution for i686, x86_64, ARMv7, AArch64 and POWER9 machines.

In addition to standard package management features, Guix supports transactional upgrades and roll-backs, unprivileged package management, per-user profiles, and garbage collection. When used as a standalone GNU/Linux distribution, Guix offers a declarative, stateless approach to operating system configuration management. Guix is highly customizable and hackable through Guile programming interfaces and extensions to the Scheme language.

Categories: FLOSS Project Planets

Python for Beginners: Python Decorators

Planet Python - Tue, 2021-10-26 10:44

Python provides us with many constructs for performing different tasks. While programming, sometimes we may need to modify the working of a function.  But we may not be allowed to change the source code of the function as it might be in use in its original form in the program. In such cases, Python decorators can be used. 

In this article, we will study what Python decorators are, how we can create decorators, and how we can use them to modify the functionalities of other functions in python. 

Table of Contents
  1. What is a Python decorator? 
  2. Concepts required to understand decorators 
    1. First class objects 
    2. Nested Functions 
    3. Free Variables
  3. How to create Python Decorators?
    1. Create Python Decorators By passing functions as arguments to another function
    2. Create Python Decorators Using @ sign 
  4. Conclusion
What is a Python decorator? 

Python decorators are functions or other callable objects that can be used to add functionalities to another function without modifying its source code. A decorator in python accepts a function as an input argument, adds some functionalities to it and returns a new function with the modified functionalities. 

Implementation of decorators in python requires knowledge of different concepts such as first class objects and nested functions. First, we will take a look at these concepts so that we do not face problems in understanding the implementation of python decorators.

Concepts required to understand decorators  First class objects 

In Python, first class objects are those objects that 

  • can be passed to a function as a parameter. 
  • can be returned from a function. 
  • can be assigned to a variable.  

All the variables that we use in our programs are first class objects, whether it be a primitive data type, a collection object or objects defined using classes.

Here I want to emphasize that functions in python are also first class objects and we can pass a function as an input parameter or we can return a function from a function.

For Example, let us look at the following source code.

Here, we have defined a function add() that takes two numbers as input and prints their sum. We have defined another function random_adder() that takes a function as input, randomly generates two numbers and calls the input function add() with the randomly generated numbers as input.

import random def add(num1, num2): value = num1 + num2 print("In the add() function. The sum of {} and {} is {}.".format(num1, num2, value)) def random_adder(func): val1 = random.randint(0, 10) val2 = random.randint(0, 100) print("In the random_adder. Values generated are {} and {}".format(val1, val2)) func(val1, val2) # execute random_adder(add)


In the random_adder. Values generated are 1 and 14 In the add() function. The sum of 1 and 14 is 15.

From the code and output, you can observe that the function add() has been passed to the random_adder() function as input and the random_adder() function calls the add() function that prints the output.

We can also return a function from another function or callable object. For instance, we can modify the above source code and define a function operate() inside the random_adder() function. The operate() function performs the entire operation done by the random_adder() function in the previous source code. 

Now, we can return the operate() function from the random_adder() function and assign it to a variable named do_something. In this way, we will be able to execute the operate() function outside the random_adder() function by calling the variable do_something as follows.

import random def add(num1, num2): value = num1 + num2 print("In the add() function. The sum of {} and {} is {}.".format(num1, num2, value)) def random_adder(func): print("In the random_adder.") def operate(): val1 = random.randint(0, 10) val2 = random.randint(0, 100) print("In the operate() function. Values generated are {} and {}".format(val1, val2)) func(val1, val2) print("Returning the operate() function.") return operate # execute do_something = random_adder(add) do_something()


In the random_adder. Returning the operate() function. In the operate() function. Values generated are 3 and 25 In the add() function. The sum of 3 and 25 is 28. Nested Functions 

Nested functions are the functions defined inside another function. For example, look at the following source code.

Here, we have defined a function add() that takes two numbers as input and calculates their sum. Also, we have defined the function square() inside add() that prints the square of the “value” calculated in the add() function.

def add(num1, num2): value = num1 + num2 print("In the add() function. The sum of {} and {} is {}.".format(num1, num2, value)) def square(): print("I am in square(). THe square of {} is {}.".format(value, value ** 2)) print("calling square() function inside add().") square() # execute add(10, 20)


In the add() function. The sum of 10 and 20 is 30. calling square() function inside add(). I am in square(). THe square of 30 is 900. Free Variables

We know that a variable can be accessed in the scope in which it has been defined. But, In the case of nested functions, we can access the elements of the enclosing function when we are in the inner function. 

In the above example, you can see that we have defined the variable “value” inside the add() function but we have accessed it in the square() function. These types of variables are called free variables.

But why the name free variables?

Because it can be accessed even if the function in which it has been defined has completed its execution. For example, look at the source code given below.

def add(num1, num2): value = num1 + num2 print("In the add() function. The sum of {} and {} is {}.".format(num1, num2, value)) def square(): print("I am in square(). THe square of {} is {}.".format(value, value ** 2)) print("returning square() function.") return square # execute do_something = add(10, 20) print("In the outer scope. Calling do_something.") do_something()


In the add() function. The sum of 10 and 20 is 30. returning square() function. In the outer scope. Calling do_something. I am in square(). THe square of 30 is 900.

Here, Once the add() function returns the square() function, it completes its execution and is cleared from the memory. Still, we can access the variable “value” by calling the square() function that has been assigned to the variable do_something

Now that we have discussed the concepts needed for implementing python decorators, Let’s dive deep and look how we can implement decorators.

How to create Python Decorators?

We can create python decorators using any callable object that can accept a callable object as input argument and can return a callable object. Here, we will create decorators using functions in Python.

For a function to be a decorator, it should follow the following properties.

  1. It must accept a function as an input.
  2. It must contain a nested function.
  3. It must return a function.

First, we will define a function add() that takes two numbers as input and prints their sum. 

def add(num1, num2): value = num1 + num2 print("The sum of {} and {} is {}.".format(num1, num2, value)) # execute add(10, 20)


The sum of 10 and 20 is 30.

Now, we have to define a decorator in such a way that the add() function should also print the product of the numbers along with the sum. For this, we can create a decorator function.

Let us first define a function that takes the add() function as input and decorates it with the additional requirements.

def decorator_function(func): def inner_function(*args): product = args[0] * args[1] print("Product of {} and {} is {} ".format(args[0], args[1], product)) func(args[0], args[1]) return inner_function

Inside the decorator_function(), we have defined the inner_function() that prints the product of the numbers that are given as input and then calls the add() function. The decorator_function() returns the inner_function().

Now that we have defined the decorator_function() and the add() function, let us see how we can decorate the add() function using the decorator_function(). 

Create Python Decorators By passing functions as arguments to another function

The first way to decorate the add() function is by passing it as an input argument to the decorator_function(). Once the decorator_function() is called, it will return inner_function() that will be assigned to the variable do_something. After that, the variable do_something will become callable and will execute the code inside the inner_function() when called. Thus, we can call do_something to print the product and the sum of the input numbers.

def add(num1, num2): value = num1 + num2 print("The sum of {} and {} is {}.".format(num1, num2, value)) def decorator_function(func): def inner_function(*args): product = args[0] * args[1] print("Product of {} and {} is {} ".format(args[0], args[1], product)) func(args[0], args[1]) return inner_function # execute do_something = decorator_function(add) do_something(10, 20)


Product of 10 and 20 is 200 The sum of 10 and 20 is 30. Create Python Decorators Using @ sign 

A simpler way to perform the same operation is by using the “@” sign. We can specify the name of the decorator_function after the @ sign before the definition of the add() function. After this, whenever the add() function is called, It will always print both the product and sum of the input numbers.

def decorator_function(func): def inner_function(*args): product = args[0] * args[1] print("Product of {} and {} is {} ".format(args[0], args[1], product)) return func(args[0], args[1]) return inner_function @decorator_function def add(num1, num2): value = num1 + num2 print("The sum of {} and {} is {}.".format(num1, num2, value)) # execute add(10, 20)


Product of 10 and 20 is 200 The sum of 10 and 20 is 30.

In this method, there is a drawback that you cannot use the add() function to just add the numbers. It will always print the product of the numbers along with their sum. So, choose the methodology by which you are going to implement the decorators by properly analyzing your needs.


In this article, we have discussed what python decorators are and how we can implement them using functions in Python. To learn more about python programming, you can read this article on list comprehension. You may also like this article on the linked list in Python.

The post Python Decorators appeared first on PythonForBeginners.com.

Categories: FLOSS Project Planets

PyCon: PyCon US 2022 Call for Proposals is open!

Planet Python - Tue, 2021-10-26 10:31

It's that time! PyCon US 2022’s Call for Proposals has officially opened for Talks, Tutorials, Posters, and Charlas. We are excited to gather in person again in Salt Lake City, UT, where all of our speakers will present their topics in person at the Salt Palace Convention Center. PyCon US is made by you, so we want you and your ideas at PyCon US!

Please make note of the important deadline for submissions:

  • All proposals are due December 20, 2021 AoE

We need beginner, intermediate, and advanced proposals on all sorts of topics. We also need beginner, intermediate, and advanced speakers to give said presentations. You don’t need to be a 20-year veteran who has spoken at dozens of conferences. On all fronts, we need all types of people. That’s what this community is comprised of, so that’s what this conference’s schedule should be made from.

For more information on where and how to submit your proposal, visit the main Speaking page on the PyCon US 2022 website.

We've provided some guidelines, tips, and advice on the types of proposals you can submit, so please be sure to check the following pages for more information:

Time to start brainstorming, drafting, and submitting - we can't wait to see all of your great ideas in the coming months! 

Categories: FLOSS Project Planets

Gábor Hojtsy: Seven days to go until Drupal 8 EOL: start using Composer!

Planet Drupal - Tue, 2021-10-26 10:00

With seven days to go until Drupal 8's end of life (on November 2, 2021), now is a good time to take stock of your Drupal 8 sites' modules. Use Upgrade Status to check for environment and module compatibility with Drupal 9.

Various people in the Upgrade Status issue queue are concerned about the module requiring Composer though. While Drupal 8 or 9 do not require Composer to work, getting any extension installed on your site that depends on third party components is a sizeable challenge without Composer. With Drupal 8 core dependent on various third party components, it was inevitable that a dependency manager will be needed to build Drupal sites. Upgrade Status itself does require various third party components to check for deprecated API uses and even to locate your Drupal site root. So you cannot avoid using Composer to even check for Drupal 9 compatibility.

If you are not using Composer yet, the best case scenario is you use this opportunity to convert your Drupal site to a Composer based solution. If you started your Drupal 8 site from 8.8.0 or later, the file structure is already ready for Composer. For Drupal sites started on prior versions, the move is more work, as explained in the guide.

In case you are not ready to convert your site to Composer yet, but still want to get a Drupal 9 upgrade readiness check, you need to set up a separate, parallel site with Composer just for this purpose. Your existing site content or configuration does not matter for Upgrade Status checks, you only need to replicate the enabled projects on the site you use.

Install Composer first. It is best to use Composer 2 because it will be much faster and will use significantly less memory, but you should have no problem installing Upgrade Status with Composer 1 either. After that, run these commands to create a new Drupal site from Composer, add core developer dependencies and add this module as a requirement.

$ composer create-project 'drupal/recommended-project:~8.9' d9readiness
$ cd d9readiness
$ composer show drupal/core | grep versions
$ composer require --dev drupal/core-dev:[copy version above]
$ composer require drupal/upgrade_status

Then, copy all of your custom and contributed projects to the web/modules, web/themes, and web/profiles folders. (You could use Composer to add at least the contributed ones, but since you are not planning to use this build for anything else, this will be the quickest way). Finally, visit /admin/reports/upgrade-status, and run the report.

This should help you get a summary of where your site is at. I would suggest you plan for converting to a composer based setup and use composer for dependency management going forward. You will only need composer on your development environment and can still use your usual workflow to push your fully built codebase from there.

Categories: FLOSS Project Planets

Real Python: Writing Idiomatic Python

Planet Python - Tue, 2021-10-26 10:00

What programming idioms are unique to Python? This course is both a short overview for people coming from other languages as well as an introduction for programming beginners to the idiomatic practices within Python.

In this course, you’ll learn:

  • How to access and interpret The Zen of Python
  • How to set up a script
  • How to test truth values
  • How to swap variables in-place
  • How to create Pythonic for loops

[ 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

Mediacurrent: Debugging Composer Dependency Conflicts

Planet Drupal - Tue, 2021-10-26 09:29

Are you ready to upgrade to Drupal 9? If you're moving from a Drupal 8 site, it needs to be reviewed and updated to remove any deprecated code that will no longer be compatible with Drupal 9. Luckily, there are a few ways to check existing codebases for deprecated code, get a glimpse of what changes need to be made, and even apply the fixes automatically.

We have other blog posts that go into details about how to plan, prepare, and fix issues with deprecated code in preparation for Drupal 9, so we won’t go into those details here, but rather walk through a Composer issue we recently ran into while trying to get Drupal Check and Rector utilities added to perform our own code deprecation checks.

We hope that this blog post helps others with similar Composer issues figure out ways to understand and debug these cryptic errors and be aware of some options and things to try in fixing them.

The Conflict

The issue we faced was where a developer had already added the Drupal Check utility a while back, and when adding Rector, you may get Composer conflict messages like this:

"Your requirements could not be resolved to an installable set of packages.

Problem 1

    - rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19] but these conflict with your requirements or minimum-stability.     - Installation request for palantirnet/drupal-rector ^0.5.1 -> satisfiable by palantirnet/drupal-rector[0.5.1].     - Conclusion: remove nikic/php-parser v4.0.2     - Conclusion: don't install nikic/php-parser v4.0.2     - palantirnet/drupal-rector 0.5.1 requires rector/rector-prefixed <0.7.19 -> satisfiable by rector/rector-prefixed[v0.3.5, v0.6.10, v0.6.12, v0.6.13, v0.6.14, v0.6.2, v0.6.4, v0.6.5, v0.6.7, v0.6.8, v0.6.9, v0.7.0, v0.7.1, v0.7.10, v0.7.11, v0.7.12, v0.7.13, v0.7.14, v0.7.15, v0.7.16, v0.7.17, v0.7.18, v0.7.2, v0.7.3, v0.7.4, v0.7.5, v0.7.6, v0.7.7, v0.7.8, v0.7.9].     - rector/rector-prefixed v0.6.10 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.12 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.13 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.14 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.2 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.4 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.5 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.7 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.8 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.6.9 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.0 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.1 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.10 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.11 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.12 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.13 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.14 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.15 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.16 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.17 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.18 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.2 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.3 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.4 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.5 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.6 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.7 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.8 conflicts with nikic/php-parser[v4.0.2].     - rector/rector-prefixed v0.7.9 conflicts with nikic/php-parser[v4.0.2].     - Installation request for nikic/php-parser 4.0.2 -> satisfiable by nikic/php-parser[v4.0.2]. Installation failed, reverting ./composer.json to its original content.

This can be pretty scary to look at and digest what it all means. But, let’s just start at the top.

Step 1

The first problem stated is:

- rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19] but these conflict with your requirements or minimum-stability.

So, first, let's look at the composer.json file. We only really care about the “require-dev” section, since we’re only dealing with the development utility scripts Drupal Check and Rector in this example, but these same investigation and debugging steps in Composer can apply similarly to items in the “require” section as well, like Drupal modules and their dependencies.

"require-dev": {    "drupal/drupal-extension": "^3.4",    "drush-ops/behat-drush-endpoint": "^8.2.4",    "mediacurrent/ci-scripts": "~1.2",    "mediacurrent/ci-tests": "dev-master",    "mediacurrent/mis_vagrant": "^5.1.0",    "mglaman/drupal-check": "^1.0",    "nikic/php-parser": "4.0.2",    "phpro/grumphp": "^0.11.6",    "phpstan/phpstan": "0.11.9",    "webflo/drupal-core-require-dev": "^8.8.1" },

Notice how there is a strict version set for the phpstan package? What’s happening is the Rector tool is trying to add a dependency package, rector/rector-prefixed v0.3.5, but that requires phpstan ^0.11.19 (so 0.11.19 or greater). And because we have a strict 0.11.9 for phpstan in composer.json, it can’t add what it needs.

A first attempt to fix this would be to try installing a version of phpstan that it wants, so we can try something like:

composer require --dev phpstan/phpstan:^0.11.19

After running that, it looks better, but still some issues:

Your requirements could not be resolved to an installable set of packages.

Problem 1

 - Can only install one of: nikic/php-parser[v4.0.2, 4.3.x-dev].     - Can only install one of: nikic/php-parser[4.3.x-dev, v4.0.2].     - Can only install one of: nikic/php-parser[4.3.x-dev, v4.0.2].     - phpstan/phpstan 0.11.19 requires nikic/php-parser ^4.2.3 -> satisfiable by nikic/php-parser[4.3.x-dev].     - Installation request for phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19].     - Installation request for nikic/php-parser 4.0.2 -> satisfiable by nikic/php-parser[v4.0.2].

That issue is caused because of more strict package versions in composer.json -- especially with the nikic/php-parser package.

"nikic/php-parser": "4.0.2"

This version constraint is causing this issue:

- phpstan/phpstan 0.11.19 requires nikic/php-parser ^4.2.3 -> satisfiable by nikic/php-parser[4.3.x-dev]. Step 2

Upon further inspection in the repo and commit history, we’ve concluded that the previous developer added those packages manually to the composer.json file (well, Composer-required them), but they shouldn’t have been added in that way, since they should be letting Composer manage them as dependencies.

Sometimes when debugging Composer dependencies we try one strategy and if that doesn't work we revert back and try something different.

Now that it seems that these packages were added manually to the projects in error, we can pull them out of the codebase and let Composer manage them as dependencies in a way it needs.

Remove the phpstan package from composer.json:

composer remove phpstan/phpstan

It looks like this removed the package from composer.json, and updated the package to a newer version because phpstan is still a dependency of Drupal-check’s constraint set at ^0.11.9. And 0.11.12 is the latest version in that constraint.

But, it’s still not going to be good enough, because remember Drupal Rector rector-prefixed package needs at least 0.11.19 per the ^0.11.19 constraint.

Step 3

Remove the php-parser package from composer.json:

composer remove nikic/php-parser

It looks like it removed the php-parser package from composer.json, and updated the package to v4.4.0

Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 0 installs, 1 update, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating nikic/php-parser (v4.0.2 => v4.4.0): Loading from cache

That’s fine, we’ll just let Composer manage the dependencies itself, but we’ve cleaned up the composer.json of packages that shouldn’t have been there and were conflicting.

Let’s see if we can get Drupal Rector added now that the conflicting packages are removed:

composer require --dev palantirnet/drupal-rector

Nope, still some of the same issues as in the beginning:

Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages.

  Problem 1

    - Installation request for palantirnet/drupal-rector ^0.5.1 -> satisfiable by palantirnet/drupal-rector[0.5.1].     - Conclusion: remove phpstan/phpstan 0.11.12     - Conclusion: don't install phpstan/phpstan 0.11.12     - rector/rector-prefixed v0.3.5 requires phpstan/phpstan ^0.11.19 -> satisfiable by phpstan/phpstan[0.11.19].     - palantirnet/drupal-rector 0.5.1 requires rector/rector-prefixed <0.7.19 -> satisfiable by rector/rector-prefixed[v0.3.5, v0.6.10, v0.6.12, v0.6.13, v0.6.14, v0.6.2, v0.6.4, v0.6.5, v0.6.7, v0.6.8, v0.6.9, v0.7.0, v0.7.1, v0.7.10, v0.7.11, v0.7.12, v0.7.13, v0.7.14, v0.7.15, v0.7.16, v0.7.17, v0.7.18, v0.7.2, v0.7.3, v0.7.4, v0.7.5, v0.7.6, v0.7.7, v0.7.8, v0.7.9].     - Can only install one of: phpstan/phpstan[0.11.19, 0.11.12].     - rector/rector-prefixed v0.6.10 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.12 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.13 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.14 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.2 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.4 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.5 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.7 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.8 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.6.9 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.0 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.1 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.10 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.11 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.12 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.13 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.14 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.15 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.16 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.17 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.18 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.2 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.3 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.4 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.5 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.6 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.7 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.8 conflicts with phpstan/phpstan[0.11.12].     - rector/rector-prefixed v0.7.9 conflicts with phpstan/phpstan[0.11.12].     - Installation request for phpstan/phpstan (locked at 0.11.12) -> satisfiable by phpstan/phpstan[0.11.12]. Installation failed, reverting ./composer.json to its original content. Step 4

So let’s dive deeper. Looking at the Drupal Check’s composer.json, we can see phpstan is listed as a dependency, so why are we including phpstan in our own composer.json?

"phpstan/phpstan": "^0.12"

Well, that’s on the latest (master) version of Drupal check:


Running this command, we can see the version of Drupal check we're currently running is:
./vendor/bin/drupal-check --version

Drupal Check 1.0.13

So, let’s check this version’s composer.json instead:


We can see it’s still 

"phpstan/phpstan": "^0.11.9" Update phpstan Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 0 installs, 1 update, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating phpstan/phpstan (0.11.12 => 0.11.19): Loading from cache

Now we have the right version we’re needing for Drupal Rector.

Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 3 installs, 0 updates, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Installing rector/rector-prefixed (v0.3.5): Loading from cache   - Installing jawira/case-converter (v1.2.0): Loading from cache   - Installing palantirnet/drupal-rector (0.5.1): Loading from cache


So that seems fishy -- because Drupal Check has a dependency of phpstan ^0.12, but we already have a phpstan 0.11.9 in our composer.json file. Why do we even have phpstan listed in our “require-dev”?

So next, we’re going to try unwinding some things and see if we can get this working.

Step 5

Let’s first remove Drupal Check:

composer remove phpstan/phpstan

This results in a few updates, most notably phpstan being updated to 0.11.12, which matches to the ^0.11.9 constraint set forth for the version of Drupal check we’re using.

Updating dependencies (including require-dev)                                                                          Package operations: 0 installs, 13 updates, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating ocramius/package-versions (1.4.0 => 1.4.2): Loading from cache   - Updating symfony/debug (v3.4.39 => v3.4.40): Loading from cache   - Updating symfony/finder (v3.4.39 => v3.4.40): Loading from cache   - Updating symfony/console (v3.4.39 => v3.4.40): Loading from cache   - Updating nette/utils (v3.0.1 => v3.1.1): Loading from cache   - Updating nette/schema (v1.0.0 => v1.0.2): Loading from cache   - Updating nette/finder (v2.5.1 => v2.5.2): Loading from cache   - Updating nette/robot-loader (v3.2.0 => v3.2.3): Loading from cache   - Updating nette/php-generator (v3.2.3 => v3.3.4): Loading from cache   - Updating nette/neon (v3.0.0 => v3.1.2): Loading from cache   - Updating nette/di (v3.0.1 => v3.0.3): Loading from cache   - Updating nette/bootstrap (v3.0.0 => v3.0.1): Loading from cache   - Updating phpstan/phpstan (0.11.9 => 0.11.12): Loading from cache

And we know that this php-parser package was added manually as well, similar to how phpstan was added manually, so we can remove it too. There is no reason to add these dependency packages manually, we can just let Composer manage them.

composer remove nikic/php-parser Running that results in this output: Updating dependencies (including require-dev)                                                                          Package operations: 0 installs, 1 update, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating nikic/php-parser (v4.0.2 => v4.4.0): Loading from cache

Using Composer why nikic/php-parser, we can see why the nikic/php-parser package is needed

phpstan/phpstan                    0.11.12  requires  nikic/php-parser (^4.0.2)

phpstan/phpstan-deprecation-rules  0.11.2   requires  nikic/php-parser (^4.0)

psy/psysh                          v0.9.9   requires  nikic/php-parser (~1.3|~2.0|~3.0|~4.0)

Step 6

Let's upgrade Drupal check

composer update mglaman/drupal-check --with-dependencies Updating dependencies (including require-dev)                                                                          Package operations: 0 installs, 3 updates, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating phpstan/phpstan (0.11.12 => 0.11.19): Loading from cache   - Updating symfony/yaml (v3.4.39 => v3.4.40): Loading from cache   - Updating mglaman/drupal-check (1.0.13 => 1.0.14): Loading from cache

Ah ha! It looks like we’re now on the right version of phpstan 0.11.19 that will support us in adding the Drupal Rector

Let’s try adding Drupal Rector again now:

composer require --dev palantirnet/drupal-rector Updating dependencies (including require-dev)                                                                          Package operations: 3 installs, 0 updates, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Installing rector/rector-prefixed (v0.3.5): Loading from cache   - Installing jawira/case-converter (v1.2.0): Loading from cache   - Installing palantirnet/drupal-rector (0.5.1): Loading from cache

Remember back to the first Composer issue we looked at with the “rector/rector-prefixed” package? We can now see that Rector was successfully able to add it.

Gathering patches for dependencies. This might take a minute.   - Installing rector/rector-prefixed (v0.7.18): Loading from cache   - Installing jawira/case-converter (v1.2.0): Loading from cache   - Installing palantirnet/drupal-rector (0.5.1): Loading from cache

And there are currently no other Composer issues being thrown at us.

The Final Step for a Clean Solution

We discovered that local dependencies were being locked to a specific version and by removing those, Composer was able to correctly reconcile the dependencies for these packages. This is somewhat dependent on and specific to your own build processes and environments, but you should be set to run Drupal Check and Rector and begin your journey and preparations for Drupal 9.

Final cleanest, best solution in our opinion...

Packages added manually, but should have just been added as dependencies and managed by Composer:

composer remove phpstan/phpstan composer remove nikic/php-parser Updated drupal-finder composer update webflo/drupal-finder Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 0 installs, 1 update, 0 removals Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating webflo/drupal-finder (1.1.0 => 1.2.0): Loading from cache composer update mglaman/drupal-check --with-dependencies Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 0 installs, 5 updates, 7 removals   - Removing phpstan/phpdoc-parser (0.3.5)   - Removing nette/schema (v1.0.2)   - Removing nette/robot-loader (v3.2.3)   - Removing nette/php-generator (v3.3.4)   - Removing nette/di (v3.0.3)   - Removing nette/bootstrap (v3.0.1)   - Removing mglaman/phpstan-junit (0.11.2) Gathering patches for root package. Gathering patches for dependencies. This might take a minute.   - Updating phpstan/phpstan (0.11.12 => 0.12.23): Loading from cache   - Updating phpstan/phpstan-deprecation-rules (0.11.2 => 0.12.2): Loading from cache   - Updating symfony/yaml (v3.4.39 => v3.4.40): Loading from cache   - Updating mglaman/phpstan-drupal (0.11.10 => 0.12.3): Loading from cache   - Updating mglaman/drupal-check (1.0.13 => 1.1.1): Loading from cache composer require --dev palantirnet/drupal-rector

Still not confident about your preparedness to upgrade, or short on time or team capacity? We can help you get ready for Drupal 9

Categories: FLOSS Project Planets

Codementor: How to Receive and Respond to Incoming SMS Messages in Python with Flask and Plivo

Planet Python - Tue, 2021-10-26 09:24
Sending an outbound message (https://www.plivo.com/blog/send-sms-in-python/?utmsource=codementor&utmmedium=external-blog&utmcampaign=receive-sms-in-flask&utmcontent=SMS) using the Plivo SMS...
Categories: FLOSS Project Planets

IslandT: Create the UI of Calculator with Tkinter

Planet Python - Tue, 2021-10-26 07:37

Simple Calculator is a python project which I have uploaded to Github under the repository name mustcoded/simplecalculator.

In the above repository, you can find the UI framework of this calculator under the main.py file. I will continue to add more files into this repository that include the module to do the calculation, the module to keep all the inputs and etc.

Below is the first version of the calculator UI and I will update the next version of main.py file directly under the above repository.

This is how the calculator UI looks like…you can modify the UI to suit your own need with the below framework!

I will update this user interface constantly on github

The first version of the main.py file is as follows:-

# A calculator application import tkinter as tk import tkinter.font win = tk.Tk() win.title('Simple Calculator') win.resizable(0,0) def insert(): pass entryFrame = tkinter.Frame(win,highlightthickness=1) entryFrame.grid(column=0, row=0, padx=5, pady=5) # entry number box entry = tkinter.StringVar(entryFrame, value='0') calculatorFont = tkinter.font.Font( family = "American Typewriter", size = 23, weight = "bold") entry_txt = tkinter.Entry(entryFrame, textvariable=entry, font=calculatorFont, justify=tkinter.RIGHT) entry_txt.grid(column=0, row=0) entry_txt.focus() frame0 = tkinter.Frame(win) frame0.grid(column=0, row=1, padx=3,pady=5) frame1 = tkinter.Frame(win) frame1.grid(column=0, row=2, padx=3,pady=5) mcButton = tkinter.Button(frame0, text="MC", width=6, height=1,command=insert) mcButton.grid(column=0, row=0, pady=1, padx=1) mrButton = tkinter.Button(frame0, text="MR",width=6, height=1, command=insert) mrButton.grid(column=1, row=0, pady=1, padx=1) mplusButton = tkinter.Button(frame0, text="M+",width=6, height=1,command=insert) mplusButton.grid(column=2, row=0, pady=1, padx=1) mminusButton = tkinter.Button(frame0, text="M-",width=6, height=1,command=insert) mminusButton.grid(column=3, row=0, pady=1, padx=1) msButton = tkinter.Button(frame0, text="MS", width=6, height=1,command=insert) msButton.grid(column=4, row=0, pady=1, padx=1) mxButton = tkinter.Button(frame0, text="M*",width=6, height=1,command=insert) mxButton.grid(column=5, row=0, pady=1, padx=1) percentageButton = tkinter.Button(frame1, text="%", width=10, height=3, command=insert) percentageButton.grid(column=0, row=1, padx=3,pady=3) ceButton = tkinter.Button(frame1, text="CE",width=10, height=3, command=insert) ceButton.grid(column=1, row=1, padx=3,pady=3) cButton = tkinter.Button(frame1, text="C",width=10, height=3,command=insert) cButton.grid(column=2, row=1, padx=3,pady=3) dButton = tkinter.Button(frame1, text="&lt;-",width=10, height=3,command=insert) dButton.grid(column=3, row=1, padx=3,pady=3) deButton = tkinter.Button(frame1, text="1/x", width=10, height=3, command=insert) deButton.grid(column=0, row=2, padx=3,pady=3) powButton = tkinter.Button(frame1, text="x\u00b2", width=10, height=3, command=insert) powButton.grid(column=1, row=2, padx=3,pady=3) squareRootButton = tkinter.Button(frame1, text="\u221Ax\u0305\u0305",width=10, height=3,command=insert) squareRootButton.grid(column=2, row=2, padx=3,pady=3) divideButton = tkinter.Button(frame1, text="\u00F7",width=10, height=3,command=insert) divideButton.grid(column=3, row=2, padx=3,pady=3) sevenButton = tkinter.Button(frame1, text="7", width=10, height=3, command=insert) sevenButton.grid(column=0, row=3, padx=3,pady=3) eightButton = tkinter.Button(frame1, text="8", width=10, height=3, command=insert) eightButton.grid(column=1, row=3, padx=3,pady=3) nineButton = tkinter.Button(frame1, text="9",width=10, height=3,command=insert) nineButton.grid(column=2, row=3, padx=3,pady=3) timesButton = tkinter.Button(frame1, text="x",width=10, height=3,command=insert) timesButton.grid(column=3, row=3, padx=3,pady=3) fourButton = tkinter.Button(frame1, text="4", width=10, height=3, command=insert) fourButton.grid(column=0, row=4, padx=3,pady=3) fiveButton = tkinter.Button(frame1, text="5", width=10, height=3, command=insert) fiveButton.grid(column=1, row=4, padx=3,pady=3) sixButton = tkinter.Button(frame1, text="6",width=10, height=3,command=insert) sixButton.grid(column=2, row=4, padx=3,pady=3) minusButton = tkinter.Button(frame1, text="-" ,width=10, height=3,command=insert) minusButton.grid(column=3, row=4, padx=3,pady=3) oneButton = tkinter.Button(frame1, text="1", width=10, height=3, command=insert) oneButton.grid(column=0, row=5, padx=3,pady=3) twoButton = tkinter.Button(frame1, text="2", width=10, height=3, command=insert) twoButton.grid(column=1, row=5, padx=3,pady=3) threeButton = tkinter.Button(frame1, text="3",width=10, height=3,command=insert) threeButton.grid(column=2, row=5, padx=3,pady=3) plusButton = tkinter.Button(frame1, text="+",width=10, height=3,command=insert) plusButton.grid(column=3, row=5, padx=3,pady=3) plusminusButton = tkinter.Button(frame1, text="+/-", width=10, height=3, command=insert) plusminusButton.grid(column=0, row=6, padx=3,pady=3) zeroButton = tkinter.Button(frame1, text="0", width=10, height=3, command=insert) zeroButton.grid(column=1, row=6, padx=3,pady=3) dotButton = tkinter.Button(frame1, text=".",width=10, height=3,command=insert) dotButton.grid(column=2, row=6, padx=3,pady=3) equalButton = tkinter.Button(frame1, text="=",width=10, height=3,command=insert) equalButton.grid(column=3, row=6, padx=3,pady=3) win.mainloop()

This UI takes me a while to complete, the next article will be the input engine part!

Categories: FLOSS Project Planets

OpenSense Labs: An in-depth study of Core Web Vitals

Planet Drupal - Tue, 2021-10-26 07:07
An in-depth study of Core Web Vitals Maitreayee Bora Tue, 10/26/2021 - 16:37

Am I not right if I say that today’s businesses prioritize customer-centric culture? I know that you would totally agree with me. So, when it comes to technology, the entrepreneurs ensure that their clients are provided seamless user experience in regards to their sites on the web. Here, I would like to mention the term, ‘Web Vitals’ which helps in quantifying the experience of your site, also enabling you to recognize opportunities to improve and get better with time. I am sure you must be familiar with this term. Therefore, in this article we will have a comprehensive study upon the topic, 'Core Web Vitals' which is a subset of the Web Vitals. This will be a good read for the site owners, developers or even marketers who look forward to enhancing their site quality and functionality.

Understanding the concept of Core Web Vitals

What are the Core Web Vitals? Core Web Vitals can be considered as a set of standardized metrics from Google which enable developers to understand the user's experience over a web page. Even though Core Web Vitals were initially created for developers, these tools can also be beneficial for site owners as they help in breaking down the user's real-world experience over a page. As discussed above, these Core Web Vitals are the subset of Web Vitals about which we will be closely looking in the coming sections. But before that you can take a chance of looking into some informative Core Web Vitals videos below for better understanding.



The three significant pillars of Core Web Vitals Source: Google

The Core Web Vitals comprises a set of three metrics that are well designed to identify user experience which can further help the site owners to improve their web services. These three metrics can be called as the significant pillars of Core Web Vitals. Moreover, each of these metrics help in providing their own perspective on various elements which impact users interaction and engagement with a website. They further enable breaking down the various different variables into smaller pieces that help site owners to recognize and fix any technical issues over their site. 

A very commonly found question is, “How do I pass Core Web Vitals”? Well the answer will be that you need to score really good for all the three metrics of Core Web Vitals which will be discussed below. Now, without waiting any further, I would now take you through the three main metrics or pillars of the Core Web Vitals. 

Largest Contentful Paint (LCP) Source: Google

Largest Contentful Paint (LCP) helps in measuring loading performance. It needs to occur within 2.5 seconds of when the page first starts loading. As site owners want pages on their site to load fast, and also enable the page to rank higher in Google in order to improve web user experience. The LCD focuses on measuring the loading time only for the content that is relevant to the users like: 

  • Images
  • Background images
  • Video poster images
  • Block-level text
First Input Delay (FID) Source: Google

First Input Delay (FID) helps in measuring the time between when the user interacts with a page, by making a click on a link or a button for example, and when the browser processes that click. The interactivity of a page is measured by this metric. Moreover, FID can’t be simulated as it totally depends on when a user clicks or interacts with a page and also how long that takes to be actioned. The site owners need to focus upon providing a good user experience with FID below 100 milliseconds. One more thing to be kept in mind is that FID is difficult to measure as this data can only be measured in the field. It further means that your score will depend on variables outside of your control, such as the device capacity of users and Internet speeds as experienced by your audience. 

Cumulative Layout Shift (CLS) Source: Google

Cumulative Layout Shift (CLS) helps in measuring the cumulative score of all unexpected layout shifts within the viewport which occur during a page’s entire lifecycle. It majorly focuses on measuring a page’s “visual stability” and is available for both field data and lab data. Also, the lower the CLS score, the better is the visual stability. So, the site owners shall try to provide a smooth user experience with FID below 100 milliseconds.

Significance of Core Web Vitals Metrics

In this section we will look at the important role that Core Web Vitals Metrics play in improving the overall user experience. To start with, Core Web Vitals help you in building faster sites that are smooth and pleasant to use by your visitors on any form of device and from any location. Most importantly, since Core Web Vitals have become a ranking factor as of mid-June 2021, we can certainly expect it to grow with the passing time. An improvement in LCP, FID, and CLS can affect your users and your rankings on mobile search results pages as well. Also, passing the Core Web Vitals assessment is possibly to result in fewer users retreating back to the SERP, because you’re providing a seamless user experience and Google possibly might start displaying a “Good Page Experience” badge in their search results. These can be called “indirect ranking factors,” as they influence searcher behavior (e.g., more clicks for pages that have this badge), which is then fed back into Google’s algorithms.

Apart from Core Web Vitals metrics, do you know about Core Web Vitals SEO? Core Web Vitals are significant for SEO, since it allows your site to gain more recognition and also keeps it well organized and clean. These vitals help in enhancing your website visibility and overall ranking in browsers. 

Tools to measure Core Web vitals

This section will describe some of the most popular tools built for developers and webmasters to measure Core Web Vitals. So, let’s begin.

Chrome User Experience Report

This Chrome User Experience Report helps in collecting real data from users as they browse the web, then shares it with developers via tools like PageSpeed Insights and Google Search Console. 

PageSpeed Insights 

PageSpeed Insights helps in analyzing the performance of your webpage and makes suggestions on how to increase its speed. It further reviews all three Core Web Vitals on both mobile and desktop browsers. 

Google Search Console

You will find Core Web Vitals inside Google Search Console for your web pages. Google Search Console helps in utilizing the data from the Chrome User Experience Report to make you aware of the issues throughout your website.

Chrome Web Vitals Extension

The Chrome Web Vitals Extension enables you to view Core Web Vitals while you browse the web or make edits to your web pages. Your competitors’ current scores can be reviewed by this extension. It can be seen using the web-vitals library along with field data from the Chrome User Experience Report.

web.dev Measure

web.dev Measure can be considered as an alternative to PageSpeed Insights. You can submit a URL, and this particular measure will report its Web Vitals based on lab data gathered using Lighthouse, in an interface which is slightly easier to navigate. 

Core web vitals from Drupal’s perspective

Now, take a look at the Core Web Vital score of Drupal. So, before disclosing the scores let me also tell you that the scores solely depend on actual website visits by users on the Google Chrome browser, and are considered as the real-world scores. The scores are well divided between desktop and mobile sites, and are also displayed as percentages of sites that achieved a good score for that specific metric. 

For Largest Contentful Paint (LCP), Drupal successfully took the first rank with a score of 47%. It means that 47% of mobile Drupal websites provided website visitors a satisfying user experience in regards to Largest Contentful Paint.

Source: Search Engine Journal 

For First Input Delay (FID), Drupal took the third rank with a score of 76%, leaving behind Joomla (71%) and Wix with a score of 46%. 

Source: Search Engine Journal 

And finally, for Cumulative Layout Shift (CLS), Drupal again succeeded in taking the first rank with a score of 70% offering a good quality CLS experience. It could perfectly beat one of the strongest CMS, WordPress with a good score difference of 13%. Therefore, Drupal has overall managed to maintain a decent rank in Core Web Vital score. 

Future of Core Web Vitals

By far we have seen the current scenario of Core Web Vitals but what about the future? How to improve Core Web Vitals? Well you and I will get to witness many changes over the next few years as Goggle will have its own updates and upgrades. Here’s what we have learnt so far. 

Core Web Vital tends to improve over time

While Google wishes to keep the amount of Core Web Vitals as low as possible, and the Web Vitals as easy to understand and measure since there is a possibility that the set will grow over time. Also, First Contentful Paint (FCP) is a prime candidate to be added for instance; you can view the Chrome Dev Summit recording from Feb 12 2021 and the “Exploring the future of Core Web Vitals recording from Dec 14 2020.

The weight of Cumulative Layout Shift (CLS) and tweaks to be improved

There is a possibility that CLS weight might be increased and also an enhancement in the handling of long-lived pages happens to take place, since layout shifts continue to be added to the CLS score after the interaction. 

Improvement in measuring animation performance

Since, user experience goes beyond initial page load, therefore Google is now looking into adding metrics that can measure animation performance. 

Enhancing  First Input Delay (FID) for better results

Lowering the FID time to 50-75ms could possibly measure the user experience more accurately. 

Facilitating Single Page Applications (SPAs) with much better assistance

While using SPAs, the app transitions do not have performance metrics because they do not have unique URLs. For instance, First Input Delay (FID) and Largest Contentful Paint (LCP) can be only measured upon initial load, but the Cumulative Layout Shift keeps on increasing with every interaction. Therefore, Google now looks into ways to better measure Web Vitals in SPAs. 

There can be a consideration of blocking traffic from non-target markets by the websites. The websites which receive an immense amount of traffic from non-target markets that also don’t have access to fast hardware and internet connections could consider stopping users from within these markets from accessing the website, therefore stopping a possible negative effect on their Core Web Vital scores. 

To know more on an overall SEO strategy including core web vitals, read this comprehensive guide on SEO in 2021.


The Core Web Vitals are the perfect metrics to measure the quality of experience across the web. You get to understand where you need to work upon your website to provide a better user experience to your visitors. With the growing time, you will get to see a much better version of these metrics that will further help you to engage your visitors to your interesting website. 

Articles Off
Categories: FLOSS Project Planets

Floating Panels in Plasma, Making Of, Part 3!

Planet KDE - Tue, 2021-10-26 06:04
Links should go here but it's like midnight, I'm super tired, I keep finishing these videos super late... I'll try to add them tomorrow morning as soon as I have 5 free minutes :( Stay in the loop: https://t.me/veggeroblog If you want to help me make these videos: Patreon: https://www.patreon.com/niccolove Youtube: https://www.youtube.com/channel/UCONH73CdRXUjlh3-DdLGCPw/join Paypal: https://paypal.me/niccolove My website is https://niccolo.venerandi.com and if you want to contact me, my telegram handle is [at] veggero.
Categories: FLOSS Project Planets

KDE Connect iOS Enters Public TestFlight Testing!

Planet KDE - Tue, 2021-10-26 04:00
KDE Connect iOS Enters Public TestFlight Testing! Another step in the further expansion of the KDE Connect ecosystem TL;DR: Get the public testing version of KDE Connect iOS by opening this TestFlight link on an iOS >= 15 device! Check out the source repository of KDE Connect iOS. Some screenshots of KDE Connect iOS:

After being picked up again earlier this year, the KDE Connect iOS project is now moving towards public beta testing with TestFlight to collect more user feedback and problem reports as the project inches further towards a full release sometime in the (near?) future.

Here are some key points from the README.md from the KDE Connect iOS repo:

Please feel free to give feedback/report bugs in the TestFlight version through:

- General information such as the number of app launches and crashes: enable Settings > Privacy > Analytics & Improvements > Share iPhone Analytics > Share with App Developers

- TestFlight's integrated screenshot feedback system: upon taking a screenshot of the app, tap "export" to see an option to send it as feedback to the developer (us).

KDE Bugzilla

Data Disclosure Notice:

- If you don't send ANY feedback AND have "Share with App Developers" disabled, the ONLY information that the KDE developers can access about you is the date that you've installed the TestFlight app.

- Enabling "Share with App Developers" discloses general information such as the number of app launches and crashes with the KDE Connect devs.

- Sending feedback through TestFlight's integrated screenshot feedback system OR TestFlight's integrated crash feedback system will disclose:

-- User email (if chosen to disclose)
-- Device Model
-- iOS version
-- Battery level
-- Cellular carrier (if applicable)
-- Time zone
-- Architecture
-- Connection Type (Wifi, etc.)
-- Free space on disk and total disk space available
-- Screen resolution
-- (For Crash feedback) stack trace leading to crash

- Sending feedback through KDE Bugzilla lets you manually disclose as much or as little information as you would like, but all information will have to be investigated manually.

TestFlight version known behaviour and problems:

- iOS is very much designed around foreground interactions. Therefore, background “daemon-style” applications don’t really exist under conventional means, so the behaviour where KDE Connect iOS is unresponsive in the background is more or less intended. There are technically some special categories and "hacky" methods to try to get it to run in the background, but in general, there is no intended/by-design method of keeping a "daemon-style" app running forever in the background. For more information, see this post on the Apple Dev Forums.

- Detailed information on what's not working and what changes took place between different versions and builds of KDE Connect iOS can be viewed in the TestFlight app in the "What to Test" section.

Lastly, please feel free to have a chat with the KDE Connect devs at the places below!

KDE Connect iOS's Official Repo

KDE Connect Development Telegram

IRC: #kdeconnect:kde.org & #kdeconnect:libera.chat

KDE Connect Mailing List

Categories: FLOSS Project Planets

UIUX Trends for Appliances & Electronics Product Lines

Planet KDE - Tue, 2021-10-26 02:00

Do you smell what's cooking? A new white paper is out with in-depth insights on the latest UIUX trends on hardware and software architectures to help pivot through smarter production for your product lines.

Categories: FLOSS Project Planets

Python Software Foundation: Vicky Twomey-Lee Awarded the PSF Community Service Award for Q3 2021

Planet Python - Tue, 2021-10-26 00:06

Vicky Twomey-Lee, software engineer, PyLadies Dublin founder, EuroPython Society emeritus board member, Coding Grace co-founder, Women Who Code Dublin director, and WITS member, have been awarded the Python Software Foundation 2021 Q3 Community Service Award.

RESOLVED, that the Python Software Foundation award the Q3 2021 Community Service Award to Vicky Twomey-Lee. Vicky has been a PSF Fellow since 2012 and a long-time volunteer to several PSF and Python spaces. 7 years ago she founded and continues to help organize the PyLadies Dublin chapter. Additionally, Vicky has been an active contributor to the PSF's Grant WG since the beginning and continues to provide helpful feedback and reviews. She also helps with EuroPython, Python Ireland, and past PyCon Ireland events.

We interviewed Vicky to learn more about her inspiration and work with the Python community. We also asked several of Vicky's associates - including Cheukting Ho, Steve Holden, Marc-Andre Lemberg, and Lais Carvalho to share more light about Vicky's community efforts and her impact on the community.

The Origin StoryWhat are your earliest memories of how you got into tech?
It was undoubtedly thanks to my dad. I remember when I was a few years old, and I woke up in the middle of the night, and I heard this "click-click" sound with a green glow lighting up my dad's face. He was big into tech. I think he was one of the few who imported computers for work and personal interests in the early 80s.
And as I got older,  I initially played games, but then I got to install programs and even upgrade hardware. My dad brought my younger brother and me to all the techie and game shows coming to our small city, Limerick.
Then in 1984, a very unique and memorable present my dad brought back from Hong Kong, a Nintendo Famicom, changed everything. I got into video games big time. Fast forward to my late teens. I was interested in graphics and was qualified to get into Graphic Design at one of the best art colleges at the time. Still, unfortunately, I had to repeat my final year in secondary school as my parents wanted me to go to university instead.
I didn't have enough Chinese to explain graphics design, so I studied Computer Systems at the University of Limerick.
Besides my studies, I experimented with HTML (there wasn't even CSS back then) during those dial-up days and then progressed to hosting and designing my own blogs at home.
And then, there was my first job at Sun Microsystem, where I met my husband - Michael Twomey - we were into the same things, and Python was the first language we got excited about, around 2002. We attended and ran Python-related events together (amongst other initiatives like diversity in tech and game jams).
We still get very excited about lots of geeky things, and in the last number of years, it was around electronics. Involvement with the Python communityWhat was your earliest involvement with the Python community?
When Python Ireland's first meetup started in 2004, I was an attendee along with Michael. When it got rebooted in 2005, the folks wanted to organize talks (note that Meetup and Eventbrite didn't exist back then), so I thought it shouldn't be too hard to find a space and get speakers.
Somehow I ended up taking the ball and running with it for over a decade, though I stepped back in 2016.
What drives and inspires you into volunteering your time and resources in the Python Community - PyLadies Dublin, Python Ireland, PyCon Ireland, and EuroPython?
It is the community because it helped me get to where I am today. Everyone was so friendly and explained things if you didn't understand.
What drives me? 
I think it is knowing that these groups can provide opportunities that have afforded me lots of weird and wonderful experiences and jobs. Like a researcher and curator for Dublin Science Gallery for an exhibition called GAME, part of a team to run a meetup of all meetups (my dream) called 404.ie at a fantastic venue. Connecting even more communities at the new hip, up-and-coming co-sharing space called Dogpatch Labs.
I know what it's like to feel lost and scared in a field I work and volunteer. I realize that I have a platform to help those who are curious and want to learn more, connect with others, and I want them to feel welcome and be part of the community.
And hopefully, in turn, some of them will pass that same sentiment on and welcome others into the community.
Yes, I get pushbacks, but I have my husband, family, and friends who look out for me. 
And I have to highlight my wonderful husband, Michael. He's been my rock, intervened when it got too much for me, picked up and tidied things away for me when I was talking to people before and after events.
And EuroPython is finally coming to Dublin!
That's the reason why we started up PyCon Ireland in 2010 (I chaired the first four editions). Since then, the Irish Python community has made it successful year on year, and the goal is in sight.
We are looking forward to seeing everyone in person (it was postponed twice due to Covid-19, so the third time's the charm) in Dublin, Ireland.
And the PSF Grants Workgroup?
I wanted to do more and was delighted to get invited to join the PSF Grants Workgroup. It was a small way for me to give back. I know what it's like to try and run something when you don't have any support. No one knows about your group/event, and starting from scratch is super hard.
I have learned a lot from the various communities worldwide on their needs for help to run their events.
How has your involvement within the Python community helped your career? 
I was learning to be a leader, mentor, organizer, and diversity in tech advocate. It helped me stay grounded as I saw all the excellent work done by the PSF, EuroPython, and PyLadies. 
It's pointed me in the direction of advocating for diversity in tech and the creative tech community and the importance of STEM in education.
So I have very different and unusual jobs as a result.
How has Covid affected your work with the Python community, and what steps are you taking to push the community forward during these trying times?
I've been working from home for a while, but with Covid-19, I learned how to stream. I had experience running live streams and podcasts with Dublin Maker, and I used these skills to run PyLadies Dublin remotely.
I already have skills in creating media and editing videos. I noticed I have a shorter attention span when watching videos, so I've shortened our events to 1 hour and opened opportunities to collaborate with international groups and invite speakers abroad.
I also realized not to fret if there's a low attendance during live events as people will (re)watch the videos in their own time. So not stressing about live attendance helped me produce a better experience for guests and viewers at our events.
Other problems I noticed are people with "zoom" fatigue, so people are a lot more understanding of mistakes. We are more patient and supportive. We are looking forward to in-person events again and are wondering how we will do a hybrid event.
Plus, learning and being in awe of what EuroPython organizers and teams have done in the past two editions.
It's always about learning, not being afraid to fail, and trying other things until it works for you. Of course, it's good to collaborate with others. You can't do everything on your own. With everything remote right now, it's an excellent opportunity to try different ways of running events.
Besides all that, I am working part-time with a company called Yard. And we are looking at how we can help tech communities rebuild their groups after Covid-19. So that's interesting for me on a personal level with all my various community groups.
Vicky Twomey-Lee Impact Story on the Python communityCheukting Ho, EuroPython, speaks on Vicky's contributions to the Python community in Dublin:
Besides being a fantastic leader in her community in Dublin, Vicky also helps other communities to connect. I would always reach out to her to invite more people to join my Python events.
Steve Holden supported Vicky's PSF fellow nomination and shared more on Vicky's impact:
By creating (and remaining a mainstay of) PyCon IE, Vicky gave Irish Python programmers the chance to see themselves as a community. Her other work to improve diversity and support the entry of more women into the tech field is also impacting.
Marc-Andre Lemburg nominated Vicky as a PSF fellow and has worked closely with her on the EuroPython Society Board since 2012. He speaks on Vicky's impact:
Vicky is highly positive, kind, and very supportive of people in the community and its organizations. She has made a real difference for Python in Ireland and helped seed the foundations of the community in Ireland.
Lais Carvalho from Python Ireland also speaks on Vicky's impact:
Vicky is a highly hardworking person interested in making the community as diverse and inclusive as possible. She works non-stop to accomplish such goals, to the point of mild exhaustion. Her impact has been significant with PyLadies, the Dublin Maker events, and Python Ireland.
The Python Software Foundation congratulates and celebrates Vicky Twomey-Lee.

Categories: FLOSS Project Planets

William Minchin: AutoLoader Plugin 1.0.2 for Pelican Released

Planet Python - Mon, 2021-10-25 22:29

AutoLoader is a plugin for Pelican, a static site generator written in Python.

AutoLoader is a “meta plugin” in that it doesn’t directly affect your Pelican site, but rather works to make your other plugins better. By way of background, Pelican 4.5 added the ability to autoload plugins that exist in the pelican.plugins namespace. This plugin allows you to extend this autoload ability to any arbitrary namespace. In particlar, it defaults to extending this ability to my minchin.pelican.plugins namespace, and thus will autoload my other plugins, if installed. It can also be used to add plugin autoloading to earlier version of Pelican.

Personally, these two abilities (to autoload my other plugins and to add autoloading to older versions of Pelican) are significant, because I am currently in the process of upgrading from Pelican 3.7 to the current version (4.7) and what was holding me back was the effort to move my plugins from their current minchin.pelican.plugins namespace. With AutoLoader, it makes it simple to upgrade my Pelican version, regardless of whether the plugins have (yet? ever?) moved namespaces. It also allows me to continue creating custom/personal versions of plugins in my namespace, particularly in cases where the original author is no longer updating their plugin.


The simplest way to install AutoLoader is to use pip:

pip install minchin.pelican.plugins.autoloader Configuration

If you are running Pelican 4.5 or newer, and haven’t manually defined PLUGINS in your pelicanconf.py site configuration file, nothing more is needed: AutoLoader will autoload itself :) Without further configuration, it will autoload any installed plugins in the minchin.pelican.plugins namespace (and Pelican itself will autoload any installed plugins in the pelican.plugins namespace).

If you are using a older version of Pelican (i.e. before v4.5) and/or you have defined PLUGINS, you’ll need to add AutoLoader to your list of plugins, like this:

# pelicanconf.py from minchin.pelican.plugins import autoloader PLUGINS = [ # others... autoloader, ]

If you want to add additional namespaces for AutoLoader to work from, define AUTOLOADER_NAMESPACES (as a list or other iterable) in your pelicanconf.py file. For example, if you want to autoload the pelican.plugins namespace (useful if you’re still using Pelican 3.7 or 4.2 or have defined PLUGINS, and the configuration this site is currently using):

# pelicanconf.py from minchin.pelican.plugins import autoloader AUTOLOADER_NAMESPACES = autoloader.DEFAULT_NAMESPACE_LIST + [ "pelican.plugins", # other namespaces ] This Release

v1.0.2 is the first public release. Earlier version numbers got “eaten” making sure the version pushed to PyPI would work as expected.

Known Issues
  • the release machinery used relies on invoke, which has not yet been updated to be compatible with Python 3.10. Beyond pushing out releases, this plugin should work with Python 3.10.
  • plugins activated by AutoLoader do not show running pelican-plugins. (pelican-plugins was a script added by Pelican 4.5 to show namespace plugins currently active). AutoLoader however should be itself listed (although likely as pelican.plugins.autoloader).
Forward Looking Thoughts

In my last plugin release post, I’d commented that there were “only 10 more plugins to go!” (i.e. to move to the pelican.plugins namespace, and presumably under the Pelican-Plugins organization on GitHub). This handily sidesteps those transitions from keeping me from upgrading Pelican on my personal site! I’m feeling much closer to getting this site upgraded to the current version of Pelican.

I plan on making releases of my other plugins shortly to rely on this and to update the installation instructions to that end.

Categories: FLOSS Project Planets

Russell Coker: Links October 2021

Planet Debian - Mon, 2021-10-25 22:23

Bloomburg has an insightful article about Juniper, the NSA, and the compromise of Netscreen [1]. It was worse than we previously thought and the Chinese government was involved.

Haaretz has an amusing story about security issues at a credit card company based on a series of major WTFs [2]. They used WhatsApp for communicating with customers (despite the lack of support from Facebook for issues like account compromise), stored it on a phone (they should have used a desktop PC), didn’t lock the phone down (should have been in a locked case and bolted down like any other financial security device), and allowed it to get stolen. Fortunately the thief was only after a free phone not the financial data stored on it.

David Brin wrote an insightful blog post “Should facts and successes matter in economics? Or politics?” [3] which is part of his series about challenging conservatives to bet on their policies.

Vice has an interesting article about a normal-looking USB-C to Lightning cable that intercepts data transfer and sends it out via an embedded Wifi AP [4]. Getting that into such a small space is an impressive engineering feat. The vendor already has a YSB-A to lightning cable with such features for $120 [5]. That’s too expensive to just leave them lying around and hope that someone with interesting data finds them, but it’s also quite cheap for a targeted attack.

Interesting article about tracking people via Bluetooth MAC address or device name [6]. Most of the research is based on a man riding a bike around Norway and passively sniffing Bluetooth transmissions. You can buy commercial devices that can receive Bluetooth from 1Km away. A recent version of Bluetooth has random Mac addresses but that still allows tracking by device name which for many people is their own name.

Cory Doctorow has a good summary of the ways that Facebook is rotten [7]. It’s worse than you think.

In 2019 almost all Facebook’s top Christian pages were run by foreign troll farms [8]. This is partly due to Christians being gullible, but Facebook is also to blame for this.

Cornell has an interesting article about using CRISPR to identify the gender of chicken eggs before they hatch [9]. This means that instead of killing roosters hatched from eggs for egg production they can just put those eggs for eating and save some money. Another option would be to genetically engineer more sexual dimorphism into chickens as the real problem is that hens for laying eggs are too thin to be good for eating so if you could have a breed of chicken with thin hens and fat cocks then all eggs could be hatched and the chickens used. The article claims that this is an ethical benefit of not killing baby roosters, but really it’s about saving 50 cents per egg.

Umair Haque wrote an insightful article about why everything will get more expensive as the externalities dating back to the industrial revolution have to be paid for [9].

Alexei Navalny (the jailed Russian opposition politician who Putin tried to murder) wrote an insightful article about why corruption is at the root of most world problems and how to solve it [10].

Cory Doctorow wrote an insightful article about breaking in to the writing industry which can apply to starting in most careers [11]. The main point is that people who have established careers have knowledge about starting a career that’s at best outdated and at most totally irrelevant. Learning from people who are at most one step ahead of you is probably best.

Peter Wehner wrote an insightful article for The Atlantic about the way churches in the US are breaking apart due to political issues [12]. Similar things appear to be happening in Australia for the same reason, conservative fear based politics which directly opposes everything in the Bible about Jesus is taking over churches. On the positive side this should destroy churches and the way churches are currently going they should be destroyed.

The Guardian has an article about the incidence of reinfection with Covid19 [13]. The current expectation is that people who aren’t vaccinated will probably get it about every 16 months if it becomes endemic (as it has in the US and will do in Australia if conservatives have their way). If the mortality rate is 2% each time then an unvaccinated person could expect a 15% chance of dying over the course of 10 years if there is no cumulative damage. However if damage to the heart and lungs accumulates over multiple courses of the disease then the probability of death over 10 years could be a lot higher.

Psyche has an interesting article by Professor Jan-Willem van Prooijeni about the way that conspiracy theories bypass rationality [14]. The way that entertaining stories bypass rationality is particularly concerning given the way Facebook and other social media are driven by clickbait.

Related posts:

  1. Links April 2021 Dr Justin Lehmiller’s blog post comparing his official (academic style)...
  2. Links August 2021 Sciencealert has an interesting article on a game to combat...
  3. Links July 2021 The News Tribune published an article in 2004 about the...
Categories: FLOSS Project Planets

KDE Plasma 5.23.2, Bugfix Release for October

Planet KDE - Mon, 2021-10-25 20:00

Tuesday, 26 October 2021. Today KDE releases a bugfix update to KDE Plasma 5, versioned 5.23.2.

Plasma 5.23 was released in October 2021 with many feature refinements and new modules to complete the desktop experience.

This release adds a week's worth of new translations and fixes from KDE's contributors. The bugfixes are typically small but important and include:

  • Plasma Browser Integration: [History Runner] Skip blob URLs. Commit.
  • [Folder View] Fix executing file without prompting. Commit. Fixes bug #435560
  • Desktop as folder: restore functionality of the “delete” action. Commit. Fixes bug #442765
View full changelog
Categories: FLOSS Project Planets