Feeds
Brett Cannon: In response to the Changelog #526
In episode 526 of the Changelog podcast entitled, "Git with your friends", they discussed various tools involving git (disclaimer: I have been on the podcast multiple times and had dinner with the hosts of the podcast the last time they were in Vancouver). Two the projects they discussed happened to be written in Python. That led Jerod to say:
The Python one gives me pause as well, just because I don’t know if it’s gonna go right.🤨
Jerod and Adam know I tend to run behind in listening to my podcasts, so they actually told me to listen to the podcast and let them know what I thought, hence this blog post (they also told me to write a blog post when I asked where they wanted "my rant/reply", so they literally asked for this 😉).
To start, Jerod said:
If it’s pip install for me, I just have anxiety… Even though it works most of the time. It’s the same way – and hey, old school Rubyist, but if I see your tool and I see it’s written in Ruby, I’m kind of like “Uhm, do I want to mess with this?” And that’s how I am with Python as well. Their stories are just fraught.To me, that&aposs a red flag that Jerod is installing stuff globally and not realizing that he should be using a virtual enivonrment to isolate his tools and their dependencies. Now, I consider asking non-Python developers to create virtual environments to be a lot, and instead I would recommend using pipx. That allows one to install a Python-based tool in a very straightforward manner using pipx install into their .local directory. I also expect pipx to be available from all the major OS package managers, so installing it (and implicitly Python) shouldn&apost be too difficult.
If you don&apost want the tool you are running to be installed "permanently", pipx run will create a virtual environment in a temp directory so your system can reclaim the space when it wants to. This also has a side-effect of grabbing a newer version of the tool on occasion as the files will occasionally be deleted.
Another option is if projects provide a .pyz file. When projects do that, they are giving users a zip file that is self-contained in terms of Python code, such that you can just pass that to your Python interpreter to run something (e.g. python tool.pyz). That avoids any installation overhead or concerns over what Python interpreter you have installed at any point since you point any Python interpreter at the .pyz file (compatibility permitting).
For the pipx scenario we probably need projects to take the lead to write their documentation about this as non-Python developers quite possibly don&apost know about either option. The .pyz solution involves the project itself to build something as part of its release process which is also a bigger ask.
Jerod did provide a little bit of clarification later about what his concerns were:
Yeah. I have no problem with Ruby-based things. But if you say gem-install this tool, I’m like “You know what? I don’t really trust my Ruby environment over the course of years on my Mac”, and I’m the same way with Python. Whereas with Go, and with Rust, it seems - and JavaScript had the same bad story for me, but Deno with TypeScript is showing some new opportunities to have universal binaries, which is cool… I’m just way more likely to say “If you can just grab a binary, drop it in your path and execute it, I will do that 100 times a day.” But if your tool says PIP install, or it says gem install, or says npm install, I’m kind of like “Do I want to mess with this?” That’s just my sense.So that does tie into the above guess that Jerod isn&apost using virtual environments. But you could stretch this out and say Jerod is even concerned that his Python interpreter will change or disappear, breaking any code he installed for that. In that instance, pipx run is rather handy as it will implicitly install Python if you got it from your OS package manager. You can also install Python explicitly instead of relying on it coming installed in the OS (which is now a Unix thing since macOS stopped shipping Python by default).
There is also the option of turning your Python tool into a standalone application. You can use things like Briefcase for GUI apps and PyApp for CLI apps. But this does make releasing harder as the project is now being asked to maintain builds for various operating systems instead of simply relegating that job to Python itself.
Now, Adam wanted even less work to do in order to get a tool:
if it’s on Linux, it should be in Apt, or whatever your [unintelligible 00:45:04.05] Yum, or pick your – it should be a package. Or you should have to update your registry with whatever package directory you want to use, and apt update, and get that, and install. That’s my feelings. I don’t like to PIP install anything if I don’t have to.The trick with this is that you, the tool developer, do not have direct control as to whether an OS package manager picks up your tool to be packaged. Since you don&apost control that distribution mechanism there is no guarantee that you can get your tool into the package manager you want (e.g., Homebrew can choose to reject your project for inclusion).
The other problematic part is there&aposs multiple OS package managers to get into, and that&aposs even if you restrict yourself to the "major" Linux distributions:
And that&aposs not covering the BSDs:
Windows:
or macOS:
And so supporting that installation flow of just installing from an OS package manager takes work as you&aposre now coordinating your tool with multiple OSs which all have their own metadata format, requirements for inclusion, ways to be told about updates, etc. It&aposs not a small lift to make happen if you want a large swath of coverage for your project.
Hopefully this has allievated some of Jerod&aposs concerns and shown Adam that his ask isn&apost small. 😉 But what&aposs the best approach for a Python tool project to take?
Unfortunately I don&apost know if there&aposs a simple answer here. For instance, if people were to use PyApp to build a self-contained binary, would people download it and actually use it, or would they be like Adam and just look for what&aposs available from their OS package manager? Where is the best cost:benefit ratio for each of the options suggested above where it warrants complicating your release process? I think documenting pipx and making a .pyz, if possible, available do make sense. But as to whether standalone binaries make sense or if it&aposs a better use of time to try and get into the package managers I honestly don&apost know.
PyCoder’s Weekly: Issue #579 (May 30, 2023)
#579 – MAY 30, 2023
View in Browser »
In this tutorial, you’ll learn what a callable is in Python and how to create callable instances using the .__call__() special method in your custom classes. You’ll also code several examples of practical use cases for callable instances in Python.
REAL PYTHON
“Typically, Django allows sorting a queryset by any attribute on the model or related to it in either ascending or descending order. However, what if you need to sort the queryset following a custom sequence of attribute values?”
REDOWAN DELOWAR
Semgrep is trusted by hundreds of thousands of developers at top companies, such as GitLab, Snowflake, Slack, and many more, to ensure the security of their code (SAST) and dependencies (SCA). Add your project in 1 minute and see for yourself →
SEMGREP sponsor
This article covers the importance and use of decorators in your code. It introduces you to both function and class decorators and helps you write your own.
TONIE VICTOR
In March and April 2023, PyPI received three subpoenas for user data from the US Department of Justice. This blog post covers what was requested and how the PyPI is working to clarify what they retain and can make available in the future. See the associated Hacker News discussion.
PYPI.ORG
This blog post from Jakub talks about how writing code in Rust has informed a more rigorous approach to his Python. He now uses types more frequently, absorbing the strictness of Rust in his Python coding style. Associated Hacker News conversation
JAKUB BERANEK
In this video course, you’ll learn how to create a Python package for your project and how to publish it to PyPI, the Python Package Repository. Quickly get up to speed on everything from naming your package to configuring it using setup.cfg.
REAL PYTHON course
Trusted by 2000+ developers from 120+ countries. Proxify provides software developers with an effortless, fast, and reliable way to find high-paying remote job opportunities. Join the most developer-friendly community today and start working on engagements with Top clients in the USA & EU →
PROXIFY sponsor
In this video course, you’ll learn all about the k-nearest neighbors (kNN) algorithm in Python, including how to implement kNN from scratch. Once you understand how kNN works, you’ll use scikit-learn to facilitate your coding process.
REAL PYTHON course
David expounds on why we should appreciate the features of other languages and how they enable the creativity of their developers, even if we don’t like those features ourselves.
DAVID HANSSON
Including a Golang package in Python using Gopy: A simple way to leverage the power of Golang packages in Python applications.
ARJUN MAHISHI • Shared by Prathamesh
CSV, JSON, Parquet — which data format should you use for your Pandas data? Itamar compares them and makes recommendations.
ITAMAR TURNER-TRAURING
In this article, you learn about bit manipulation and how to solve problems efficiently using it in Python.
ANURAG VERMA
GITHUB.COM/HAKANCELIKDEV • Shared by Hakan Çelik
ChatSQL: Convert Plain Text to SQL Through ChatGPTGITHUB.COM/ADEMAKDOGAN • Shared by Adem AKDOGAN
pyserde: Dataclass Based Serialization Library pyscan: Rust Based Python Dependency Vulnerability Scanner guidance: Language for Controlling Large Language Models Events DjangoCon Europe 2023 May 29 to June 3, 2023
DJANGOCON.EU
May 31, 2023
REALPYTHON.COM
June 1, 2023
MEETUP.COM
June 2 to June 5, 2023
PYDATA.ORG
June 3 to June 4, 2023
PYLAPAZ.ORG
Happy Pythoning!
This was PyCoder’s Weekly Issue #579.
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 ]
Four Kitchens: A more modern, sustainable approach to higher ed websites with YaleSites
Senior Engineer
As a tech lead, Jim works with clients through the full project cycle, translating their business requirements into actionable development work and working with them to find technical solutions to their challenges.
January 1, 1970
Running the digital experience is a large-scale operation for most higher ed institutions. Whether your architecture was established five or 15 years ago, the departments, offices, and entities you need to manage may add up to hundreds or even thousands of websites. And each new addition is increasingly challenging to maintain.
Some sites use shared modules, while others do not. If you want to make an update to one website, you have to cross your fingers and hope it doesn’t break something on 500 others. Every day, another stakeholder presents a new request in support of an upcoming project.
Facing all these compounding issues, the IT department at Yale understood that a lift-and-shift of their existing sites was impossible. Upgrading their digital platform presented an opportunity to reset their architecture and processes to start fresh.
In a preview of our upcoming presentation at DrupalCon 2023, here’s what happened next — and what your institution can learn from it.
Why reinvention makes sense for higher ed institutionsUniversities are facing significant challenges related to budgets, economic uncertainty, and reduced admissions applications. The pandemic introduced further uncertainty balanced with an increased need to sharpen digital presentations.
As one of the most prestigious institutions in the world, Yale needed to find a new, more sustainable way to manage its digital needs. The institution had stretched the limits of a very mature Drupal 7 site with more than a decade’s worth of modules, themes, and custom code.
It was difficult for the IT team to test with confidence, because they manage more than 1,100 sites that were all created in different ways. In addition, the more impressive a new site looked, the more other offices and departments wanted to emulate it.
The unintended consequences of an overtaxed website platformWith the university’s website system at critical mass, Yale’s teams lacked incentive to add new features to its legacy platform. Consequently, some larger departments found the platform inflexible, leading them to Wix and Squarespace for new projects. If the university didn’t find a workable platform solution, it ran the risk of increased site errors, design inconsistencies, and a diminished user experience.
Resetting Yale’s approach to digital required a sizable upfront capital investment. As the work comes to fruition, the organization is gaining a flexible, scalable platform that will benefit every department into the next decade — and beyond.
YaleSites: A transformational approach to higher ed websitesYaleSites is the product of years of examining the university’s needs. Through our previous work with the institution’s cybersecurity office and the Schwarzman Center, we developed a new platform that incorporated the following elements:
A unified brand identity and design systemYaleSites offers many departments the ability to create unique digital experiences that are aligned with the institution’s overall design. Instead of a conventional CMS, Yale’s team uses a customized drag-and-drop page builder drawn from a library of proven components powered by Emulsify.
The YaleSites Welcome page Inclusive and accessible development for all customers and devicesInstitutions like Yale need to offer an equitable digital experience for every audience. YaleSites upholds and prioritizes the university’s accessibility standards by making sure every content block follows best practices for usability and accessibility.
User-focused experience and designYaleSites prioritizes the needs of the organization’s audience and its end users. Across the organization, content authors of every skill level can access a full library of templates, starter kits, and media libraries to produce what they need.
Adding blocks in the YaleSites administrative interface. Standardized practices for developmentThe organization’s development process has been streamlined. Rather than asking “What do you need in a website?”, work begins with the question, “How can our tools help with your strategy?” Developers don’t have to reinvent the wheel for a new site. Instead, they have the support of a system that’s performant, on-brand, and secure.
Sustainable governanceWe implemented YaleSites with an eye toward thoughtful and sustainable growth. Universities often set digital priorities based on the loudest or most powerful voices in the organization. Now, Yale uses processes that enable them to focus on the organization’s most pressing needs. Plus, a core group meets regularly to collect feedback, respond to requests, and adjust priorities as needed.
Shifting from a project-based to a product-based perspectiveAfter launching YaleSites, the institution will enter the maintenance phase of protecting its system. The university’s new platform required a significant financial investment — now it must invest in the long-term work of governance.
The success of Yale’s platform hinges on a seismic internal shift. YaleSites isn’t a project that concludes with a specific end date. It’s a product that the organization must refine and support in perpetuity.
Since YaleSites is a product, its resources are finite. For example, if IT plans to add six new features in a quarter, any new request is a negotiation. Something may need to get bumped from the product roadmap. Rather than rushing a new feature into development for a short-term need, the organization follows a multiyear roadmap and measures the needs against all of the priorities in the queue.
Eliminate deadline pressure by focusing on constant improvementThinking long-term about your organization’s website removes the need to squeeze as many improvements as possible into a project’s deadline. Following the principles of Agile development frees your team from solving every use case before launch. Instead, you can launch a minimally functional feature like an events calendar, see how people use it, and refine how it works according to actionable feedback.
YaleSites allows the institution to implement site improvements with confidence. Rather than working on whatever makes sense in the moment, they see their work progress from ideation to development, testing, and release.
From the flexibility of its digital tools to a more managed, Agile-driven approach to website improvements, YaleSites marks a dramatic shift for the better. If this sounds like a shift that would benefit how your organization works, we should talk. We can help you view your site and its planning from a new perspective.
Megan Bygness Bradley and the Yale team contributed to this post.
The post A more modern, sustainable approach to higher ed websites with YaleSites appeared first on Four Kitchens.
Stack Abuse: How to Split String on Multiple Delimiters in Python
Among the plenty of string operations, splitting a string is a significant one, offering the capability to divide a large, composite text into smaller, manageable components. Typically, we use a single delimiter like a comma, space, or a special character for this purpose. But what if you need to split a string based on multiple delimiters?
Imagine a situation where you're dealing with text data punctuated with various separators, or you're parsing a complex file with inconsistent delimiters. This is where Python's ability to split strings on multiple delimiters truly shines.
In this article, we'll give you a comprehensive overview of the different techniques of multi-delimiter string splitting in Python. We'll explore core Python methods, regular expressions, and even external libraries like Pandas to achieve this.
The str.split() Method can Split Strings on Only One DelimiterThe str.split() method is Python's built-in approach to dividing a string into a list of substrings. By default, str.split() uses whitespace (spaces, tabs, and newlines) as the delimiter. However, you can specify any character or sequence of characters as the delimiter:
text = "Python is a powerful language" words = text.split() print(words)Running this code will result in:
['Python', 'is', 'a', 'powerful', 'language']In this case, we've split the string into words using the default delimiter - whitespace. But what if we want to use a different delimiter? We can pass it as an argument to split():
text = "Python,is,a,powerful,language" words = text.split(',') print(words)Which will give us:
['Python', 'is', 'a', 'powerful', 'language']While str.split() is highly useful for splitting strings with a single delimiter, it falls short when we need to split a string on multiple delimiters. For example, if we have a string with words separated by commas, semicolons, and/or spaces, str.split() cannot handle all these delimiters simultaneously.
Advice: Reading our guide "Python: Split String into List with split()" will help you gain a deeper understanding of the split() method in Python.
In the upcoming sections, we will explore more sophisticated techniques for splitting strings based on multiple delimiters in Python.
Using Regular Expressions - the re.split() MethodTo tackle the issue of splitting a string on multiple delimiters, Python provides us with the re (Regular Expressions) module. Specifically, the re.split() function is an effective tool that allows us to split a string using multiple delimiters.
Regular expressions (or regex) are sequences of characters that define a search pattern. These are highly versatile, making them excellent for complex text processing tasks.
Consider the following string:
text = "Python;is,a powerful:language"If you want to extract words from it, you must consider multiple delimiters. Let's take a look at how we can use re.split() to split a string based on multiple delimiters:
import re text = "Python;is,a powerful:language" words = re.split(';|,| ', text) print(words)This will give us:
['Python', 'is', 'a', 'powerful', 'language']We used the re.split() method to split the string at every occurrence of a semicolon (;), comma (,), or space ( ). The | symbol is used in regular expressions to mean "or", so ;|,| can be read as "semicolon or comma or space".
This function demonstrates far greater versatility and power than str.split(), allowing us to easily split a string on multiple delimiters.
Advice: You can find more about Python regular expressions in our "Introduction to Regular Expressions in Python".
In the next section, we'll take a look at another Pythonic way to split strings using multiple delimiters, leveraging the translate() and maketrans() methods.
Using translate() and maketrans() MethodsPython's str class provides two powerful methods for character mapping and replacement: maketrans() and translate(). When used in combination, they offer an efficient way to replace multiple delimiters with a single common one, allowing us to use str.split() effectively.
The maketrans() method returns a translation table that can be used with the translate() method to replace specific characters. So, let's take a look at how to utilize those two methods to fit our needs.
First of all, we need to create a translation table that maps semicolons (;) and colons (:) to commas (,):
text = "Python;is,a powerful:language" # Create a translation table mapping ';' and ':' to ',' table = text.maketrans(";:", ",,")Then we use the translate() method to apply this table to our text. This replaces all semicolons and colons with commas:
# Apply the translation table text = text.translate(table)Finally, we can use str.split(',') to split the text into words and print extracted words:
# Now we can split on the comma words = text.split(',') print(words)This will result in:
['Python', 'is', 'a powerful', 'language']Note: This approach is particularly useful when you want to standardize the delimiters in a string before splitting it.
In the next section, we'll explore how to utilize an external library, Pandas, for splitting strings on multiple delimiters.
Leveraging the Pandas LibraryPandas, a powerful data manipulation library in Python, can also be used for splitting strings on multiple delimiters. Its str.split() function is capable of handling regex, making it another effective tool for this task.
While the built-in string methods are efficient for smaller data, when you're working with large datasets (like a DataFrame), using Pandas for string splitting can be a better choice. The syntax is also quite intuitive.
Here's how you can use Pandas to split a string on multiple delimiters:
import pandas as pd # Create a DataFrame df = pd.DataFrame({'Text': ['Python;is,a powerful:language']}) # Use the str.split() function with a regex pattern df = df['Text'].str.split(';|,|:', expand=True) print(df)This will give us:
0 1 2 3 4 0 Python is a powerful languageWe first created a DataFrame with our text. We then used the str.split() function, passing in a regex pattern similar to what we used with re.split(). The expand=True argument makes the function return a DataFrame where each split string is a separate column.
Note: Although this method returns a DataFrame instead of a list, it can be highly useful when you're already working within the Pandas ecosystem.
Performance ComparisonWhen choosing a method to split strings on multiple delimiters, performance can be an important factor, especially when working with large datasets. Let's examine the performance of the methods we've discussed.
The built-in str.split() method is quite efficient for smaller data sets and a single delimiter, but its performance suffers when used with multiple delimiters and large datasets due to the necessary extra processing.
The re.split() method is versatile and relatively efficient, as it can handle multiple delimiters well. However, its performance might also degrade when dealing with huge amounts of data, because regular expressions can be computationally intensive.
Using translate() and maketrans() can be an efficient way to handle multiple delimiters, especially when you want to standardize the delimiters before splitting. However, it involves an extra step, which can affect performance with large datasets.
Finally, while the Pandas library offers a very efficient and flexible method to split strings on multiple delimiters, it might be overkill for simple, small tasks. The overhead of creating a DataFrame can affect performance when working with smaller data, but it excels in handling large datasets.
In conclusion, the best method to use depends on your specific use case. For small datasets and tasks, Python's built-in methods might be more suitable, while for larger, more complex data manipulation tasks, Pandas could be the way to go.
ConclusionString splitting, especially on multiple delimiters, is a common yet crucial operation in Python. It serves as the backbone in many text processing, data cleaning, and parsing tasks. As we've seen, Python provides a range of techniques for this task, each with its own strengths and weaknesses. From the built-in str.split(), to the versatile Regular Expressions, the character mapping translate() and maketrans() methods, and even the external Pandas library, Python offers solutions suitable for any complexity and size of data.
It's important to understand the different methods available and choose the one that best suits your specific requirements. Whether it's simplicity, versatility, or performance, Python's tools for string splitting can cater to various needs.
We hope this article helps you become more proficient in handling and manipulating strings in Python.
Chromatic: Drupal 7 End-of-Life Ep 08: Building a Bridge to Drupal 7 with Matt Glaman
The Three of Wands: Intro to cattrs 23.1.0
Instead of my usual Twitter and Fediverse threads, for this release of cattrs I figured I&aposd try something different. A blog post lets me describe the additions in more detail, provide context and usage examples, and produces a permanent record that can be linked to from the relevant places, like a GitHub release page and the cattrs changelog.
cattrs is a library for transforming Python data structures, the most obvious use case being de/serialization (to JSON, msgpack, YAML, and other formats).
Tagged Unionscattrs has supported unions of attrs classes for a long time through our default automatic disambiguation strategy. This is a very simple way of supporting unions using no extra configuration. The way it works is: we examine every class in the union, find unique, mandatory attribute names for each class, and generate a function using that information to do the actual structuring. (Other unions are supported via manually-written hooks.)
But what if one of your classes has no unique attributes, or you just want to be able to tell the union member from a glance at the payload? Now you can use the tagged unions strategy.
This strategy adds a field into the unstructured payload, defaulting to _type but configurable, which inserts a piece of data (by default the name of the class, but again configurable) to help with structuring.
This strategy isn&apost the default so you&aposll have to import it and configure it on a union-by-union basis.
from attrs import define from cattrs import Converter from cattrs.strategies import configure_tagged_union @define class A: a: int @define class B: a: str c = Converter() configure_tagged_union(A | B, c) c.unstructure(A(1), unstructure_as=A|B) # {"a": 1, "_type": "A"} c.structure({"a": 1, "_type": "A"}, A|B) # A(1)A useful feature of configure_tagged_union is that you can give it a default member class. This is a good way of evolving an API from a single class to a union in a backwards-compatible way.
from attrs import define @define class Request: @define class A: field: int payload: A c = Converter() c.structure({"payload": {"field": 1}}, Request) # Request(A(1)) # Next iteration: @define class Request: @define class A: field: int @define class B: field: int payload: A | B c = Converter() configure_tagged_union(A | B, c, default=A) # No type info means `A` c.structure({"payload": {"field": 1}}, Request) # Still Request(A(1))Improved Validation Errorscattrs has had a detailed validation mode for a few versions now, and it&aposs enabled by default. In this mode, structuring errors are gathered and propagated out as an ExceptionGroup subclass, essentially creating a tree of errors mirroring the desired data structure. This ExceptionGroup can then be printed out using normal Python tooling for printing exceptions.
Still, sometimes you need a more succinct representation of your errors; for example if you need to display it to a user or return it to a web frontend. So now we have a simple transformer function available:
from attrs import define from cattrs import structure, transform_error @define class Class: a_list: list[int] a_dict: dict[str, int] try: structure({"a_list": ["a"], "a_dict": {"str": "a"}}, Class) except Exception as exc: print(transform_error(exc)) [ &aposinvalid value for type, expected int @ $.a_list[0]&apos, "invalid value for type, expected int @ $.a_dict[&aposstr&apos]" ]As you see, we generate a list of readable(-ish) error messages, including a path to every field. This can be customized, or you can copy/paste the transform_error function and just alter it directly if you require absolute control. Learn more here.
Typed Dictscattrs now supports TypedDicts on all supported Python versions. Due to spotty TypedDict functionality in earlier Pythons, I recommend you use TypedDict from typing_extensions when running on 3.9 or earlier. This is the reason cattrs now depends on typing_extensions on those versions.
from typing import TypedDict from datetime import datetime from cattrs.preconf.json import make_converter converter = make_converter() class MyDict(TypedDict): my_datetime: datetime converter.structure({"my_datetime": "2023-05-01T00:00:00Z"}, MyDict) # {&aposmy_datetime&apos: datetime.datetime(2023, 5, 1, 0, 0, tzinfo=datetime.timezone.utc)}Generic TypedDicts are supported on 3.11+ (a language limitation), and totalities, Required and NotRequred are supported regardless.
The TypedDict implementation leverages the existing attrs/dataclasses base so it inherits most of the features. For example, structuring and unstructuring hooks can be customized to rename or omit keys. Here&aposs an example with the forbid_extra_keys functionality:
from typing import TypedDict from cattrs import Converter from cattrs.gen.typeddicts import make_dict_structure_fn class MyTypedDict(TypedDict): a: int c = Converter() c.register_structure_hook( MyTypedDict, make_dict_structure_fn(MyTypedDict, c, _cattrs_forbid_extra_keys=True) ) c.structure({"a": 1, "b": 2}, MyTypedDict) # Raises an exceptionNew Markdown DocsThe docs have been rewritten using Markdown and MyST! We can finally link like civilized people and not animals, so I&aposll be going through the docs and making them more interconnected. The theme has also been tweaked to be more airy and (in my opinion) better looking. The new docs are live at https://catt.rs now.
MiscThere are many more smaller changes in this release; I suggest inspecting the actual changelog. A quick shout out to the include_subclasses strategy by Matthieu Melot!
What&aposs NextSo I don&apost actually know exactly what&aposll end up in the next version of cattrs since I don&apost work via a strict roadmap and I can&apost predict what folks will contribute.
What I think will probably happen is the creation of some sort of OpenAPI/jsonschema and cattrs wrapper library. It&aposs something folks have expressed interest in, and I already have the bones of it in the uapi project.
I&aposll also continue work on fleshing out the cattrs.v validation subsystem. This will probably go hand-in-hand with efforts in attrs and Mypy making operations on class attributes type-safe.
I&aposll also almost certainly expand both our union strategies to additionally handle enums and literals automatically, enabling true sum type support by default.
Real Python: Getting the First Match From a Python List or Iterable
At some point in your Python journey, you may need to find the first item that matches a certain criterion in a Python iterable, such as a list or dictionary.
The simplest case is that you need to confirm that a particular item exists in the iterable. For example, you want to find a name in a list of names or a substring inside a string. In these cases, you’re best off using the in operator. However, there are many use cases when you may want to look for items with specific properties. For instance, you may need to:
- Find a non-zero value in a list of numbers
- Find a name of a particular length in a list of strings
- Find and modify a dictionary in a list of dictionaries based on a certain attribute
In this video course, you’ll explore how best to approach all three scenarios.
[ 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 ]
Tag1 Consulting: On 20 Years of Drupal: an interview with Matthew Saunders
In continuing our 20 years of Drupal series, Tag1 Consulting's, Managing Director Michael Meyers interviews leaders from the Drupal Community who have been instrumental in creating one of the largest open-source communities and one of the most popular Content Management Systems that powers over 3% of the Internet. In this installment, join us for our talk with prolific contributor Matthew Saunders. Currently at Pfizer, Matthew shares his journey into technology by way of the Arts, where he discovered his passion for technology after becoming a Webmaster for an experimental dance company back in 1995. With over 15 years of continuous involvement in the Drupal Community - former board member of the Drupal Association and long-time organizer of Drupalcamp Colorado, we hope you will enjoy this trip down memory lane. --- For a transcript of this video, see On 20 Years of Drupal with Matthew Saunders. --- Photo by Jason Hafso on Unsplash
Read more michaelemeyers Tue, 05/30/2023 - 06:15Matt Glaman: Factories and dependency injection
Last week I wrote about dependency injection anti-patterns in Drupal. These anti-patterns occur when your service's constructor has logic that interacts with the injected dependent services beyond assigning them to properties. These anti-patterns include creating a new object from a factory or retrieving an object from a stack. However, Symfony's service container supports defining services built from factories. This can streamline your code and follow best practices when using dependency injection. Drupal uses this factory service design pattern for cache bins, loggers, and the HTTP client service.
Stack Abuse: How to Remove Whitespaces from a String in Python
In programming, data often doesn't come in a neat, ready-to-use format. This is particularly true when we deal with strings, which often need to be cleaned, formatted, or manipulated in some way before they can be used effectively. One common issue we encounter is the presence of unwanted whitespaces - extra spaces, tabs, or newlines that can interfere with the way the string is processed or displayed.
Whitespace is like the "empty space" in our data. It might not seem like much, but in programming and data analysis, it can often lead to errors, incorrect results, or simply make data harder to read and analyze. That's why it's important to understand how to manage and control whitespaces in our strings.
In this article, we will explore different techniques to remove whitespaces from strings in Python, including using built-in string methods like strip(), replace(), and join(), and also delve into more advanced concepts like regular expressions and list comprehensions.
Whitespaces in PythonIn Python, and most other programming languages, whitespace refers to characters that are used for spacing and do not contain any printable glyphs. They include spaces ( ), tabs (\t), newlines (\n), and others. In Python strings, these characters can exist at the beginning, end, or anywhere within the string.
Consider the following example:
str_with_whitespace = ' Hello, World! 'The string ' Hello, World! ' has leading and trailing whitespaces.
Although they might seem innocuous, these whitespaces can cause a variety of issues. For instance, they might interfere with string comparison operations or cause problems when trying to format your output neatly:
print(' Hello, World! ' == 'Hello, World!') # Output: FalseTherefore, understanding how to remove or manipulate these whitespaces is a crucial aspect of handling strings in Python. In the following sections, we'll explore various methods and techniques to effectively remove these whitespaces from our Python strings.
Ways to Remove Whitespaces from Strings in PythonPython provides various ways to remove whitespaces from strings. We'll explore several methods, each with its own advantages and use cases.
Using strip(), rstrip(), and lstrip() MethodsPython string method strip() removes leading and trailing whitespaces. If you only want to remove spaces from the left or right side, you can use lstrip() and rstrip(), respectively:
str_with_whitespace = ' Hello, World! ' # Using strip() method print(str_with_whitespace.strip()) # Output: 'Hello, World!' # Using lstrip() method print(str_with_whitespace.lstrip()) # Output: 'Hello, World! ' # Using rstrip() method print(str_with_whitespace.rstrip()) # Output: ' Hello, World!'Note: These methods do not remove whitespace that is in the middle of the string.
Advice: For a more comprehensive overview of the strip(), rstrip() and lstrtip() in Python, read our "Guide to Python's strip() Method".
Using replace() MethodThe replace() method can be used to replace all occurrences of a substring. This can be used to remove all whitespaces in a string by replacing them with nothing.
str_with_whitespace = ' Hello, World! ' # Using replace() method print(str_with_whitespace.replace(' ', '')) # Output: 'Hello,World!'This method removes all spaces, even those within the string.
Advice: If you need a deeper understanding of the replace() method in Python, read our article "Replace Occurrences of a Substring in String with Python".
Using Regular ExpressionsFor more complex whitespace removal, we can use regular expressions via the re module in Python. This can be used to replace multiple consecutive whitespaces with a single space:
import re str_with_whitespace = ' Hello, World! ' # Using re.sub() method print(re.sub('\s+', ' ', str_with_whitespace).strip()) # Output: 'Hello, World!'Here, re.sub('\s+', ' ', str_with_whitespace).strip() replaces all consecutive whitespaces with a single space and then removes leading and trailing whitespaces.
Advice: Read more about regular expressions in Python in "Introduction to Regular Expressions in Python".
Using List ComprehensionList comprehensions provide a concise way to create lists based on existing lists. They can be used to remove all whitespaces in a string:
str_with_whitespace = ' Hello, World! ' # Using list comprehension print(''.join(char for char in str_with_whitespace if not char.isspace())) # Output: 'Hello,World!'In this example, we created a new string by joining all non-whitespace characters.
Advice: You can dive deeper into the concept of list comprehension in Python by reading our guide "List Comprehension in Python".
Using join() and split() MethodsThe join() and split() methods can be used together to remove all whitespaces in a string. split() splits the string into words, and join() joins them together without spaces:
str_with_whitespace = ' Hello, World! ' # Using join() and split() methods print(' '.join(str_with_whitespace.split())) # Output: 'Hello, World!'In this example, ' '.join(str_with_whitespace.split()) splits str_with_whitespace into words and joins them together with a single space.
ConclusionThroughout this article, we've explored a variety of methods to remove whitespaces from strings in Python, including using built-in string methods like strip(), replace(), and join(), as well as more advanced techniques involving regular expressions and list comprehensions.
While each method has its own advantages, the best one to use depends on your specific needs and the nature of the data you're working with. The key is to understand these different methods and know how to use them when needed.
To enhance your understanding and practice these methods, we encourage you to experiment with them. Try creating your own strings with various types of whitespaces and see how effectively you can remove them using the techniques discussed.
Talk Python to Me: #417: Test-Driven Prompt Engineering for LLMs with Promptimize
Python Bytes: #338 Scripting iOS with Python
Tryton News: News from the Tryton Unconference 2023 in Berlin
The Tryton Unconference 2023 in Berlin has come to an end. We had a great time and shared lots of information, work and fun. We would also like to thank all the wonderful people in the conference, the organisers and sponsors and the Tryton Foundation for making this event happen after a break of several years.
First DayIn case you weren’t able to participate during the Unconference, or you want to look-up a talk, you can watch the videos from the first day. Many thanks to @tbruyere who made this possible, and has been doing so for many years. Also, the slides from the talks will soon be available at Tryton - Presentations & Papers.
We also have some photos taken during a few of the talks:
The results were collected in pads are have been copied and spellchecked below in this newsletter.
Please note all the collected results are only individual opinions or the consensus of the discussion group which collected them. All collected topics and results are draft documents for working on later.
Slot: Marketing TrytonModeration: Stefan, Writing: Udo
Follow-up discussion: https://discuss.tryton.org/t/tryton-marketing-masterpost/
What is a Marketing?
- Tryton is a brand
- Tryton is a company
What is part of the Tryton Brand?
- Offering a product
- Has a community
- Has a design for being recognized
Communication:
- Who is the target user/customer group for the Tryton brand?
- Re-User: Implementer/Integrator/Customizer
- End-user
- Product owner
- Decision maker
- Consultants
- Developer
Which media addresses which target user group?
- Tryton news
- Social media
- Homepage
- Public advertising
- Discuss forum
How to start with Tryton?
- Get Tryton Page: 2 clicks away hidden on start page
- Check if Tryton is good with ISO25010
Start with the Homepage
- Structuring, design and content
- Function description for each icon:
– E.g. Sales Button, click, video showing sale process.
– Screenshots of more complex customisations. - Videos, screenshots and keywords
- press-collection-zip with pictures and general information
Find a common denominator which attracts all stakeholders:
- At the first visit, everyone likes to quickly get an idea of the look & feel and functionality of Tryton.
- not addressing documentation, but giving a feeling about the following questions:
– Is Tryton a real application used in companies?
– Could Tryton be a solution for me and my company?
– How does it look and feel to use Tryton?
– Will Tryton fit my expectations?
Also a feature list with some screenshots showing features.
A CSV/XLS file including features as a list to make them comparable to other systems.
The feature list could answer the questions:
- How much does it fit my needs/requirements/expectations?
- What is already there and what is missing?
- How it compares to other software?
Then some screenshots each with a paragraph explaining a real specific customization to show Tryton’s customizability.
The screenshots and explanations should give a feeling that it is possible to customize Tryton, even if the basis is very simple.
Merge Request: association module (!217) · Merge requests · Tryton / Tryton · GitLab
Member Workflow:
- Draft
- Rejected
- Running to → rename to „Member“? - ask @dave
- Quitted
- Expelled
other factors?
-
paid / didn’t pay
-
Donations (Report)
-
book on the matching account and create an appropriate report
-
Dominique’s Key Points:
– Have a members module providing membership-workflow and fees, everything else can be crowd-funded by requesters.
– Record voluntary work hours and report to some institution to get money
– Record members work hours which members are obligated to provide
Ongoing discussion: https://discuss.tryton.org/t/add-in-heptapod-a-location-to-push-the-nonofficial-module/
Aims:
- List item
- Make it attractive to Collaborate
- Avoid duplicate work
- Trustworthy source
- Make modules more accessible and visible
- Promoting Tryton as a whole
- Place / Space where a Community can grow
Contrib-Modules:
- Central point with services
- Issue tracking and Merge requests
- Some Translation will happen
- CI / testing → Labels on projects
- packaged (PyPI, release, whatever)
- not part of the Docker image
- provide an easy way to build a Docker image containing custom selected contrib-modules
- Repo/project template
- No Mono-Repo
- No requirement for having one module per repo
Ideas for Rules:
- to be implemented within reasonable time
- must support TLS version
- must have a test suite
- must have have our CI steps
- Handed on to the community
- sibling project of Tryton core
- Foundation pays the costs
Core Modules:
- Generic, on general use
- Minimum requirements
- GPL-compatible license
- Test Suite
- Integration with each other
- Pass Cedric’s review
Follow-up discussion: https://discuss.tryton.org/t/user-interface-masterpost/
The main focus today is the usage of Tryton on small mobile devices like smartphones
TECHNOLOGY
As there are desktop client (GTK) and web client (Sao), the web client is the ideal technology for us, because it is responsive to different sizes of screens and is running in a standard browser usable on each device. Producing native apps is complex and expensive.
CUSTOM CODE - SPECIAL USE CASES
For some use cases, a developer needs custom layouts (e.g. calendar) or special extensions (point of sale, stock picking, scan supplier invoices) to integrate in the web client. This can already be done by
- injecting custom code in the Web-UI
- this code can extend the existing framework like a additional module (as we know with Tryton modules)
- using vue.js (JavaScript)
- using custom CSS (so one can adopt the layout event closer to the needs of the project)
SAO COLUMS RESIZING
Actually, resizing of columns is missing. As it is a pain for the user, we should add this function.
- it can be done by adding a corresponding extension (using JavaScript and CSS)
- Kalenis also does that, but they use “react”.
Follow up discussion: Resize List View Column with Handle
LIST VIEW
On small devices, only 1 column is possible to show. Perhaps with more information underneath the main content (e.g. the city underneath the name of the party in the party list). See Mobility for tablets and smartphones - #5 by s.vogel :
- we’ll integrate fields to define the “weight” of data field (in other words semantic info, e.g. like numbering-string)
- so we can define which is the most important column to show in the smartphone list. and what columns/data comes underneath.
- the CSS then can take in account this weight and can apply a good text format.
Follow up discussion: Mobile List View
FORM VIEW
Here the view is already responsive:
- we define to go on step by step optimize ugly situations as long as a generic solution can be found.
- some of us would like an easy way to modify a layout, perhaps on the layout directly by turning on a layout-edit-mode and then add and delete and reposition things. We understand that this is complex to achieve, because functionality could be broken. There are various ways of doing it already in a proper way (custom module or in the views-administration part of Tryton)
Follow up discussion: Optimize Form View
Slot: Project Community OrganizationGOALS
- Have a place where the community can grow
- Give room to people so they can work
- Governments to contribute modules to core or outside the code
- Responsibility for decisions. What decisions?
- Not only focus on code quality. There are other things to take into account.
PROBLEMS / MISUNDERSTANDINGS / FIGHTS
- There were fights in the past.
- The foundation works for its own
- The community doesn’t see what the foundation does. The foundation doesn’t
- Where is the control of the foundation (> quality management?)
- Foundation was created to protect the community and the eco-system. The foundation was not created to run the community
- There are statutes and there it is written that the foundation is responsible for the well being of the community
- Idea was to give some kind a visible head of the community
- Short time ago, a lot of the directors didn’t do anything. There was nothing to tell. So it looks like, that the foundation is in-transparent.
- One has to write down what has to do.
- Wolf shall really start with introducing meetings.
- the newsletter team are interested in news about events and meetings and projects and so on.
- Wolf has a lot of interesting questions that others don’t ask. It’s important that somebody does it.
- Some find it attractive the community is not too organized.
- Unconference should have had a bit of organization. Perhaps one or two checklists was great.
- The project was originally set up by Cedric and then invited other people. Now, the foundation was introduced to take over.
- Is there an ethical card (>see discuss rules)
- Role of Cedric. Gatekeeper for technical part. Focus on technical quality. Help on technical documentation. Only express his own opinion. He is also accepting other ideas, although he doesn’t agree. He is not stubborn.
- Better looking for an understanding of why Cedric proposes his opinion. He pushes one to work harder and find better contributions.
- Contributors unfortunately not are all of the same quality. If the requirements are too high, it is difficult for new contributors participate.
- Also accept lower quality commits? At the moment, such repository does not exist yet.
- At the moment too many things have to be discussed and that lowers down working speed and sometimes it is annoying.
- Cedric is very fast in answering what makes impossible to participate. On the other hand works goes on fast.
- On discuss, the answer should take in account the kind of question and the knowledge of the one who asked the question.
- Give more room to the discussions. Not close the discussions too early.
- One is frustrated in committing which does not solve anything.
- It was good in having specialists for certain topics. Some kind like coaches or experts. It was good to have more opinions than a technical view.
- If one asks process-questions in discussions, you might get a technical answer. In discuss, one doesn’t know what the question is for (process, new feature, evolution, bug). The problem is, there the questions can’t be assigned to existing projects.
FOUNDATION
- for 5 years a director is elected and then looks for a following person
- supporters can kick out a director
- one can become a supporter just by writing an email to the foundation
- there are no regularities
- the foundation is not the leader
- the foundation is only helping
GROUPING / RESPONSIBILITIES
We have discussed the creation of several community groups to work as a team on the different tasks of the foundations. Here are some ideas and people that are already volunteering.
- Meetings, Events (Wolf)
- Welcome newcomer
- Technical News
- Unconference organization (Check Lists)
- Newsletter (Udo, Sergi, Dave)
- Commits organization ()
- Thanking for the contribution
- Checking the contribution and question for approving.
- Helping in improving
- free workload of core team
- Commits authorization / Gatekeeper (Cedric)
- User Interface ()
Feel free to raise your hand if you are interested on joining some groups.
WEBSITE
- Even better addressing decision makers.
INCLUSION / DIVERSITY
- There is room for others as can be seen when looking at the people working actively.
- Shall get more diverse.
- Shall better search the points to get together instead of looking for the negative points.
- less fighting
CODE QUALITY
- Is important. It is correct to focus on it.
- Modularity is important and it is also correct to focus on it
CONCLUSION
- Cedric will step a bit, except other answer is wrong or important things are missing.
The how? what? who? when? and where? about maintaining Tryton.
Problem: The codebase of the Tryton project is getting larger and larger over the years. Also the user base and with it the questions, discussion and demand for help grows. With the maintenance of Tryton we reach limits. The idea is to include more people in maintenance tasks.
Brainstorming ideas how to organize maintenance:
- In code review use suggestions when you have an idea for a better solution instead of comment.
- Triage, qualify and preview MR and issues.
- Collect isolated maintenance tasks, responsibilities and jobs which can be done by others.
- Describe and document maintenance tasks and jobs.
- Propose, debate and collect rules
- Vote for rule sets and changes
- lower the entry for a person to get a responsibility in the project maintenance
- Documentation about tasks, jobs and responsible persons is important for everyone interested in Tryton
- Use the wiki functionality of Discourse, try to allow ordinary members to make their post a wiki.
- Tryton application documentation: Use for each module/version a discuss page to collect user feedback.
Follow-up discussion: Link modules documentation to discource and vice versa - #2 by 2cadz
1 post - 1 participant
Peoples Blog: Drupal LMS Features for Your Education Business
Russ Allbery: Review: The Mimicking of Known Successes
Review: The Mimicking of Known Successes, by Malka Older
Series: Mossa and Pleiti #1 Publisher: Tordotcom Copyright: 2023 ISBN: 1-250-86051-2 Format: Kindle Pages: 169The Mimicking of Known Successes is a science fiction mystery novella, the first of an expected series. (The second novella is scheduled to be published in February of 2024.)
Mossa is an Investigator, called in after a man disappears from the eastward platform on the 4°63' line. It's an isolated platform, five hours away from Mossa's base, and home to only four residential buildings and a pub. The most likely explanation is that the man jumped, but his behavior before he disappeared doesn't seem consistent with that theory. He was bragging about being from Valdegeld University, talking to anyone who would listen about the important work he was doing — not typically the behavior of someone who is suicidal. Valdegeld is the obvious next stop in the investigation.
Pleiti is a Classics scholar at Valdegeld. She is also Mossa's ex-girlfriend, making her both an obvious and a fraught person to ask for investigative help. Mossa is the last person she expected to be waiting for her on the railcar platform when she returns from a trip to visit her parents.
The Mimicking of Known Successes is mostly a mystery, following Mossa's attempts to untangle the story of what happened to the disappeared man, but as you might have guessed there's a substantial sapphic romance subplot. It's also at least adjacent to Sherlock Holmes: Mossa is brilliant, observant, somewhat monomaniacal, and very bad at human relationships. All of this story except for the prologue is told from Pleiti's perspective as she plays a bit of a Watson role, finding Mossa unreadable, attractive, frustrating, and charming in turn. Following more recent Holmes adaptations, Mossa is portrayed as probably neurodivergent, although the story doesn't attach any specific labels.
I have no strong opinions about this novella. It was fine? There's a mystery with a few twists, there's a sapphic romance of the second chance variety, there's a bit of action and a bit of hurt/comfort after the action, and it all felt comfortably entertaining but kind of predictable. Susan Stepney has a "passes the time" review rating, and while that may be a bit harsh, that's about where I ended up.
The most interesting part of the story is the science fiction setting. We're some indefinite period into the future. Humans have completely messed up Earth to the point of making it uninhabitable. We then took a shot at terraforming Mars and messed that planet up to the point of uninhabitability as well. Now, what's left of humanity (maybe not all of it — the story isn't clear) lives on platforms connected by rail lines high in the atmosphere of Jupiter. (Everyone in the story calls Jupiter "Giant" for reasons that I didn't follow, given that they didn't rename any of its moons.) Pleiti's position as a Classics scholar means that she studies Earth and its now-lost ecosystems, whereas the Modern faculty focus on their new platform life.
This background does become relevant to the mystery, although exactly how is not clear at the start.
I wouldn't call this a very realistic setting. One has to accept that people are living on platforms attached to artificial rings around the solar system's largest planet and walk around in shirt sleeves and only minor technological support due to "atmoshields" of some unspecified capability, and where the native atmosphere plays the role of London fog. Everything feels vaguely Edwardian, including to the occasional human porter and message runner, which matches the story concept but seems unlikely as a plausible future culture. I also disbelieve in humanity's ability to do anything to Earth that would make it less inhabitable than the clouds of Jupiter.
That said, the setting is a lot of fun, which is probably more important. It's fun to try to visualize, and it has that slightly off-balance, occasionally surprising feel of science fiction settings where everyone is recognizably human but the things they consider routine and unremarkable are unexpected by the reader.
This novella also has a great title. The Mimicking of Known Successes is simultaneously a reference a specific plot point from late in the story, a nod to the shape of the romance, and an acknowledgment of the Holmes pastiche, and all of those references work even better once you know what the plot point is. That was nicely done.
This was not very memorable apart from the setting, but it was pleasant enough. I can't say that I'm inspired to pre-order the next novella in this series, but I also wouldn't object to reading it. If you're in the mood for gender-swapped Holmes in an exotic setting, you could do worse.
Followed by The Imposition of Unnecessary Obstacles.
Rating: 6 out of 10
My work in KDE for May 2023
I can’t believe it’s already the end of May! This month turned out a little meatier than last month I think, but I still have a large backlog of merge requests and TODOs to go through.
Plasma #Now when there isn’t enough space to display the QR code in the clipboard applet, there is a clearer message of what to do next.
Screenshot of the new message in action.On the topic of QR codes, the menu is now a menu of radio buttons and not checkboxes which didn’t make sense because it’s an exclusive option.
You can’t have two different codes being displayed after all.There is now a separator above the “Close” action in the window menu!
It now matches other context menus with this action, e.g. the Task ManagerI added a metadata extractor for Krita files, which means certain information about your Krita artwork can show up in Dolphin, Baloo and other programs that can take advantage of it! This includes helpful information such as canvas width, height and creation date.
A slightly outdated screenshot, but showing off some of the metadata it can extractSoon, the Language and Region settings will support the $LANGUAGE environment variable. This only affects users who did not configure the language explicitly from KDE, like those coming from another computing environment. We already supported loading your pre-existing language from $LANG. Included in that merge request is a fix that stops an erroneous warning message telling you that your language isn’t supported, even though it clearly is.
Plasma SDK #For new users of the Plasma SDK, there is now a clearer and more helpful message when you start plasmoidviewer without an applet specified.
$ plasmoidviewer An applet name or path must be specified, e.g. --applet org.kde.plasma.analogclockI proposed making the icon name selectable, because I can’t stop myself from clicking on it!
Screenshot of selecting the icon name in Cuttlefish. Gamepad KCM #Jeremy Whiting has been hard at work improving the backend code, and I finally took a shot at creating a proper art prototype of the controller that will be featured in the KCM.
Concept art of the controller, not finalized yet.This will be the base image for the different controller types, and it will change depending on what controller we detect. Neither of us are experts in Inkscape, so we plan for the this to be easily tweakable by actual designers who do not need to know the fine details of the KCM. This is possible because we’re also developing an Inkscape extension to automate exporting SVG files into QML templates that describe button, trigger positions and so on.
The concept is already working in the KCM, but it looks a little off right now and isn’t ready for showcasing yet :-)
Tokodon #Many users (including myself) have been experiencing crashes because of the video support added in the last release. QtMultimedia - the library we used for video support - in Qt5 is frustratingly buggy, but has improved in Qt6. Unfortunately, we still have a few more months before KDE Gear applications like Tokodon can switch to Qt6 only and we need a solution for the crashes now. I started porting Tokodon’s video support to mpv which is also used in PlasmaTube!
Playing videos and GIFs should be less crashy, but with worse scrolling performance. However, I worked hard to make sure this only affects auto-play, so if you don’t that option enabled then you shouldn’t notice a difference. This change is almost ready and should appear in the next release, but it lacks testing on Android.
You can now change certain account preferences, but the selection is limited due to lack of a proper API. These are preferences that were supported before, but now you can change them from within Tokodon.
The preferences you can tweak in TokodonAnd a whole slew of smaller stuff, some which are appearing in the next bugfix release:
- Link previews are no longer broken.
- When switching between toplevel pages (Home, Explore, etc), clear the entire page stack instead of part of it.
- The duplicate account bug should finally be fixed!
- Fix icons on non-KDE environments, such as GNOME.
For the current and future contributors, I started working on better and more detailed documentation. The first two areas I covered was timeline models and the account classes!
In terms of starting even more future work, I started implementing QtKeychain support, and rewriting the current, and buggy, account saving mechanism with KConfig. This will hopefully land in the next release, and fix a whole slew of nagging security and account duplication bugs.
qqc2-desktop-style #If you’ve been noticing that qqc2-desktop-style on Plasma 6 is spitting out some weird stuff in your logs:
Warning: file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33:13: Unable to assign [undefined] to bool (file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33, ) Warning: file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33:13: Unable to assign [undefined] to bool (file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33, ) Warning: file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33:13: Unable to assign [undefined] to bool (file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33, ) Warning: file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33:13: Unable to assign [undefined] to bool (file:///home/josh/kde6/usr/lib/qml/org/kde/desktop/private/MobileCursor.qml:33, )I fixed that! It also needs these ECM changes to work. It turns out ECMQmlModule didn’t handle singleton types, and other nagging problems that qqc2-desktop-style needed. I’ve been dabbling in this module for the past month or so so it’s exciting to be able to help here.
Kiten #I took some time to improve the codebase of our Japanese reference tool Kiten, because it seems to have not been very active the past few years. I think it was written before we used C++11. I found a bunch of places where 0 was used to set pointers to null!
I started replacing the old foreach macro, use auto to prevent duplicate types and other modern C++ gardening tasks.
Websites and Documentation #The go.kde.org Matrix redirector update is now merged, which I started in February. This means NeoChat is now preferred right below Element Web (which is still pointed towards https://webchat.kde.org/). Thanks to Thiago Sueto, the Community Wiki has been updated already and I sent two merge requests to update kde.org and the footer.
The updated matrix.to redirector!To finish off more February work, I got around to working on the two big pieces of API documentation improvements for KDE Frameworks 6. If you don’t remember, I wanted to add import statements for components meant to be used in Qt Quick. Doxygen already gives us hints for C++ headers, so QML users shouldn’t be left in the dust. For example, how are you even supposed to use this component?
This is a real example. Not all components are like this, fortunately.In order to accomplish this, subclasses of QQuickItem need to have their doc comments modified. The first library to get this treatment is plasma-framework, see the merge requests for PlasmaCore, PlasmaQuick and hiding ToolTipDialog.
For regular QML-based components, doxyqml (the tool to auto-generate QML documentation, because Doxygen lacks support for the language) needed to spit these out too. The merge request to add import statements is cleaned up, the tests fixed and ready for final review!
Ah! I had to import that module!I also spent some time cleaning up the Community wiki, which just means I roam around and make sure links aren’t dead and the formatting looks nice. If you’re interested in some wiki improvement, join us in #kde-www and the Issue board!
Packaging #I was recently researching how well Tokodon works out of the box on other desktop environments. It turns out 90% of issues with Kirigami applications can be solved by installing breeze-icons and qqc2-desktop-style! We might be enforcing this soon, so if you are in charge of packaging Kirigami applications, please make add them as weak or required dependencies! I will probably start filing packaging bugs soon.
In terms of KDE packaging issues in distributions, I opened up two this month:
- On Fedora, Tokodon depends on QtMultimedia and will fail to launch.
- On Arch Linux, add khtml as an optional dependency for HTML preview.
I’m also attending Akademy this year in Thessaloniki! My passport was delivered this month, which is strangely hard to get in the USA (currently).
redstrate @redstrate@mastodon.artI finally got the passport today! Pretty happy that I no longer have to worry about this little book :bunhdgoogly:
9:19 PM • May 18, 2023 (UTC)I booked my accommodations last week, so I’m excited to see everyone in-person in July! This is my first time traveling outside of the North American continent, and to Europe no less. I’ll be documenting my experience traveling and at Akademy, but I’m not sure what format it’ll be in yet.
Shirish Agarwal: Pearls of Luthra, Dahaad, Tetris & Discord.
Pearls of Luthra is the first book by Brian Jacques and I think I am going to be a fan of his work. This particular book you have to be wary of. While it is a beautiful book with quite a few illustrations, I have to warn that if you are somebody who feels hungry at the very mention of food, then you will be hungry throughout the book. There isn’t a single page where food isn’t mentioned and not just any kind of food, the kind of food that is geared towards sweet tooth. So if you fancy tarts or chocolates or anything sweet you will right at home. The book also touches upon various teas and wines and various liquors but food is where it shines in literally. The tale is very much like a Harry Potter adventure but isn’t as dark as HP was. In fact, apart from one death and one ear missing rest of our heroes and heroines and there are quite a few. I don’t want to give too much away as it’s a book to be treasured.
DahaadDahaad (the roar) is Sonakshi Sinha’s entry in OTT/Web Series. The stage is set somewhere in North India while the exploits are based on a real life person called Cyanide Mohan who killed 20 women between 2005-2009. In the web series however, the antagonist’s crimes are done over a period of 12 years and has 29 women as his victims. Apart from that it’s pretty much a copy of what was done by the person above. It’s a melting pot of a series which quite a few stories enmeshed along with the main one. The main onus and plot of the movie is about women from lower economic and caste order whose families want them to be wed but cannot due to huge demands for dowry. Now in such a situation, if a person were to give them a bit of attention, promise marriage and ask them to steal a bit and come with him and whatever, they will do it. The same modus operandi was done by Cynaide Mohan. He had a car that was not actually is but used it show off that he’s from a richer background, entice the women, have sex, promise marriage and in the morning after pill there will be cynaide which the women unwittingly will consume.
This is also framed by the protagonist Sonakshi Sinha to her mother as her mother is also forcing her to get married as she is becoming older. She shows some of the photographs of the victims and says that while the perpetrator is guilty but so is the overall society that puts women in such vulnerable positions. AFAIK, that is still the state of things. In fact, there is a series called ‘Indian Matchmaking‘ that has all the snobbishness that you want. How many people could have a lifestyle like the ones shown in that, less than 2% of the population. It’s actually shows like the above that make the whole thing even more precarious
Apart from it, the show also shows prejudice about caste and background. I wouldn’t go much into it as it’s worth seeing and experiencing.
TetrisTetris in many a ways is a story of greed. It’s also a story of a lone inventor who had to wait almost 20 odd years to profit from his invention. Forbes does a marvelous job of giving some more background and foreground info. about Tetris, the inventor and the producer that went to strike it rich. It also does share about copyright misrepresentation happens but does nothing to address it. Could talk a whole lot but better to see the movie and draw your own conclusions. For me it was 4/5.
DiscordDiscord became Discord 2.0 and is a blank to me. A blank page. Can’t do anything. First I thought it was a bug. Waited for a few days as sometimes webservices do fix themselves. But two weeks on and it still wasn’t fixed then decided to look under. One of the tools in Firefox is Web Developer Tools ( CTRL+Shift+I) that tells you if an element of a page is not appearing or at least gives you a hint. To me it gave me the following –
Content Security Policy: Ignoring “'unsafe-inline'” within script-src or style-src: nonce-source or hash-source specified
Content Security Policy: The page’s settings blocked the loading of a resource at data:text/css,%0A%20%20%20%20%20%20%20%2… (“style-src”). data:44:30
Content Security Policy: Ignoring “'unsafe-inline'” within script-src or style-src: nonce-source or hash-source specified
TypeError: AudioContext is not a constructor 138875 https://discord.com/assets/cbf3a75da6e6b6a4202e.js:262 l https://discord.com/assets/f5f0b113e28d4d12ba16.js:1ed46a18578285e5c048b.js:241:118
What is being done is dom.webaudio.enabled being disabled in Firefox.
Then on a hunch, searched on reddit and saw the following. Be careful while visiting the link as it’s labelled NSFW although to my mind there wasn’t anything remotely NSFW about it. They do mention using another tool ‘AudioContext Fingerprint Defender‘ which supposedly fakes or spoofs an id. As this add-on isn’t tracked by Firefox privacy team it’s hard for me to say anything positive or negative.
So, in the end I stopped using discord as the alternative was being tracked by them
Last but not the least, saw this about a week back. Sooner or later this had to happen as Elon tries to make money off Twitter.
Memory Disks
Not a moment after I had walked out the door to catch a train to Berlin for the KDE e.V. board sprint (May 2023), there was a local power failure which took down my in-house IT. That wouldn’t be so bad, except it did not come back up. Cue gnashing of teeth from the people who stayed at home (but, really, should have been able to hack into the router to fix it).
What Went Wrong- The Pine H6 which provides DNS and DHCP to the house, did not come up. I’ve seen it before – a power droop leaves the eMMC discombobulated, and no amount of cajoling will get it back unless you pick the eMMC off the board and futz with it in a different machine.
- The modem relies on the Pine H6 and does not provide fallback of its own (which would have allowed easy configuration of static IP and DNS, anyway).
- My workstation, which I thought was configured with static IP, was set to DHCP instead, so it didn’t get an address at all.
Fixing fallback DNS and my workstation IP was simple.
Fixing the H6 was slightly more involved.
Why Was eMMC Involved At AllOriginally the H6 also ran QuasselCore and some other services. These write to disk and are persistent. I had had bad experiences with write endurance of micro-SD cards. As in, they’re lousy in write-intensive scenarios and wear out quickly.
I figured eMMC such as used in the PineBook would be a better candidate for writable storage.
Since originally setting this up, I have stopped using QuasselCore. So the write-intensive and potentially large data-storage needs are gone. But the eMMC configuration lives on in my H6, which is disastrous when a power droop leaves it discombobulated.
Fixing The eMMCOn boot in FreeBSD I kept getting controller timeouts and device-read timeouts on the eMMC block device. The filesystem would not mount, and I would eventually get dropped down to single-user mode. Unfortunately, in single-user mode, you need to use the serial console to talk to the board (if I expect people at home to hack the router, maybe I should expect them to deal with serial ports too).
I am, frankly, not sure what I did right. I picked the eMMC off the H6, stuck it to an adapter which I had just received with the VisionFive V2, and dd‘ed the whole device to /dev/null. Since it did not throw any read errors or timeouts, I put it back on the H6 and wished for good luck.
Note to self: on the Pine H6, the EXP connector has pin 6 = GND, 7 = TX (goes to RX on the USB-to-serial), 8 = RX. Those are the easiest to count-out pins. Also, they’re bent on my board from all the connecting-and-disconnecting I do.
Making The eMMC UnnecessaryOriginally I added the eMMC for write-intensive large data sets, but those have gone away on this machine. So what’s left? Maybe 64MB of data that gets written or updated – the DNS log, DHCP leases, maybe a cache. But none of that is very big, and none of it needs to be persistent across (rare!) reboots. All the writable data on the system lives in /var.
FreeBSD supports a variety of diskless operation modes, so I went looking what is possible there. Turns out /var on diskless systems can be treated specially, and that is just what I need.
In rc.conf there are dozens of system-configuration variables that you can set. It’s still old-school SysV initialization, and I like it like that. Here is what I added to /etc/rc.conf:
varmfs=YES varsize=256M varmfs_flags='-S -k /var.md/'The configuration says to use a memory-disk for /var, that it should be 256MiB large (plenty, and still acceptable within the 3GiB memory size of the H6), without softupdates (a BSD UFS tweak) and using /var.md as “skeleton”. That means that the memory disk is populated from the contents of /var.md when it is created.
With this setup, I have writable storage that is not persistent and that does not wear our the SD card, with minimal impact on the rest of the system – and it is simple to switch back if necessary.
Python Software Foundation: The Python Language Summit 2023: Burnout is Real
The first known case of burnout in the field of open-source software, van Rossum speculated, may have been Charles Babbage, who gave up the post of Lucasian Professor of Mathematics (the “Chair of Newton”) at Cambridge University in 1839.
“In 1839 the demands of the Analytical Engine upon my attention had become so incessant and so exhausting, that even the few duties of the Lucasian Chair had a sensible effect in impairing my bodily strength. I therefore sent in my resignation.”
-- Charles Babbage, “Passages from the Life of a Philosopher” (Chapter 4)
Van Rossum described how the Python community had been hit multiple times by core developers, suffering from burnout, suddenly disappearing for extended periods of time. Van Rossum told the story of one core developer, previously one of the most prolific contributors to CPython, who had abruptly ceased contributing around a decade ago. He had hardly been heard from since.
Van Rossum himself, he recounted, had felt so burned out by the acrimonious debate around PEP 572 (proposing the “walrus operator”, :=), that it led to him stepping down from his post as Benevolent Dictator For Life (“BDFL”) of Python in 2018. Decisions about the language were ceded to a democratically elected Steering Council, which has governed Python ever since.
Burnout, van Rossum noted, was often connected to conflict – and it often didn’t matter whether or not you ended the conflict victorious. Merely having the conflict at all could be exhausting.
Van Rossum’s talk itself was fairly short, but was followed by a lengthy discussion among the assembled core developers on the experiences they’d had with burnout, and strategies that could be employed to tackle it.
Several attendees in the room commented that learning to recognise burnout in yourself was an important skill. Some participants in the discussion described times when they had suddenly realised that things that had previously been enjoyable had morphed into a source of stress. One core developer told the story of a conference they had organised, at which they had felt such extreme stress that they were unable to think of any of the things that had gone well. Instead, they found themselves fixated on all of the minor things that had gone wrong.
Learning to recognise burnout in others was perhaps an even harder problem to solve. Van Rossum noted that the developers most susceptible to burnout were generally those who were most active and engaged with the community. But how can you distinguish between somebody devoting their time to CPython because of the intense enjoyment they found in contributing to the project, somebody who might have formed an unhealthy addiction to open source, and somebody who was only continuing to contribute out of a misplaced sense of obligation?
Some developers spoke of strategies they used to decompress. Brett Cannon described how he periodically takes “open source breaks”, in which he forces himself to spend a period of time without looking at his GitHub notifications or thinking about his open-source commitments. Mariatta Wijaya spoke about how she found mentoring other Python programmers to be deeply healing. All agreed that it was crucial to talk to friends and relatives when you were feeling close to burnout.
It was agreed that the Python community needed to do better in many ways. We needed to become better, as a community, at understanding when other people said that they were unable to complete something they had previously committed to. And perhaps we needed to normalise questions such as, “Hey, you’ve been super productive and responsive for too long. When do you think you’ll burn out?”
Russell Keith-Magee remarked that systems with single points of failure were bound to lead to situations of intense stress. These systems would inevitably, at some point, fail. The transition from a single BDFL (with an indefinite term) to a five-member Steering Council with one-year terms had been a very positive change in that regard, Keith-Magee said. But there were still places in CPython development where there were single points of failure. Examples included various esoteric platforms where support from CPython depended on a single core developer being able to give up their time to review PRs relating to the platform.
Carol Willing agreed with Keith-Magee, pointing out that no matter who you were, you were rarely the only person who could do a certain task. You might be the person who could do it fastest or best – but sometimes, it was important to “see the people, and share the joy”.
Łukasz Langa spoke about his role as part of the current Code of Conduct Working Group, to which any violations of the Python Code of Conduct can be reported. Langa remarked that being part of the Working Group had brought to the fore parts of the community which he had previously been mostly unaware of. He encouraged everybody in the room to report toxic members of the community who were discouraging or aggressive online.
Speaking personally, for a moment: I tried to take an open-source break earlier this year, when I felt myself close to burning out on some of my open-source commitments. I can’t say it was fully successful – my addiction to GitHub was too great for me to resist glancing at my notifications occasionally. But it was helpful, and re-energising, to spend some time doing a creative activity that bore with it a 0% risk of people shouting at me on the internet about it:
Talking Drupal: Talking Drupal #401 - HTTP Headers
Today we are talking about HTTP Headers with our hosts.
For show notes visit: www.talkingDrupal.com/401
Topics- What are HTTP Headers
- Why are they important
- Exploring headers
- Types of headers
- What can you discover from headers
- Modifying headers
- Tools to validate
- Content Security Policy (CSP)
- Dries’ Header Evaluation Tool
- Mozilla Header Documentation
- Good overview of CSP
- Nic’s Header Blog Post
Nic Laflin - www.nLighteneddevelopment.com @nicxvan John Picozzi - www.epam.com @johnpicozzi Stephen Cross - stephencross.com @stephencross Martin Anderson-Clutz - @mandclu
MOTW CorrespondentMartin Anderson-Clutz - @mandclu Content-Security-Policy Adds a Content-Security-Policy header which allows your Drupal site to inform browsers of trusted sources for JavaScript, CSS, and other external resources.