Planet Python

Subscribe to Planet Python feed
Planet Python - http://planetpython.org/
Updated: 22 hours 47 min ago

Tryton News: Newsletter January 2024

Mon, 2024-01-01 02:00

During the last month we mainly focused on fixing bugs, adjusting how things work, improving performance and adding new features.

Changes for the User Sales, Purchases and Projects

Related shipments and moves are now reset and cancelled when a purchase request is cancelled.

When creating a sale from an opportunity the sale now has default addresses and payment terms, if they are not defined on the opportunity.

The blanket agreement record names now contain the reference and will fallback to the id if there isn’t a number or a reference available, like we do for sales and purchases.

We added some UTM parameters to emails sent by the marketing modules. The following parameters were added:

  • utm_campaign
  • utm_medium
  • utm_source

The create purchase wizard on purchase requests now opens the newly created purchases.

Since Tryton defaults to the most used currency for new purchases, we’ve now updated it to also do the same for purchase requests.

Accounting, Invoicing and Payments

When using sale advance payments Tryton no longer sets the invoice date if the advance payment condition has no invoice delay. If you’d like the invoice date to default to today’s date, set a delay of 0.

Stock, Production and Shipments

On an unaltered system modification of product locations is now restricted to the Stock Administrator access group.

The progress of a move is now rounded to four digits.

Tryton now only checks if a lot is required when a move is going to the done state.

The stock location code is now included in the record name of a location.

We added a confirmation dialogue to the cancel- buttons on shipments.

When moving consumable products the default to-location is now preset with the default product location.

User Interface

The URL button is now hidden, when a URL field is empty, as disabling it did not prevent the user from clicking on it.

Each button in a list-view is now rendered read-only when the appropriate record is also read-only.

We improved the behaviour of button clicks. Now clicking rapidly on a button only launches the action once. This same behaviour has also been implemented for widget buttons.

Now labels are aligned to the start of the line on extra small screens.

On small screens we now hide the search widget on list views. A toolbar button shows the search widget on demand.


The workflow graphs for models no longer overlap and incorrectly share states.

More (click for more details) Documentation

We reworked parts of the Tryton documentation.

In validation error messages the record name is now prefixed with the word “record” in order to make the message clearer.

New Releases

We released bug fixes for the currently maintained long term support series
7.0 and 6.0, and for the penultimate series 6.8.

Changes for the System Administrator

For the Tryton desktop client we now support the arm64 darwin architecture allowing it to be built on Apple Silicon.

Changes for Implementers and Developers

The order of keys is now retained when changing a fields.Dictionary through an on_change method.

For selection and multiselection fields we now use the string version of the value in error messages.

Authors: @dave @pokoli @udono

1 post - 1 participant

Read full topic

Categories: FLOSS Project Planets

Doug Hellmann: imapautofiler 1.14.0 - sort-by-year action

Sun, 2023-12-31 10:52
What’s new in 1.14.0? add python 3.12 to test matrix add sort-by-year action
Categories: FLOSS Project Planets

Seth Michael Larson: 2023 year in review

Sat, 2023-12-30 19:00
2023 year in review AboutBlogNewsletterLinks 2023 year in review

Published 2023-12-31 by Seth Larson
Reading time: minutes

2023 was a great year! So much happened, but a few things in particular stood out to be when putting together this post.

I got married to my wife, Trina after 9 years of being together. We met in college and fell in love with each others' passion for adventure, food, and life. Our ceremonies included both of our cultures and we had family and friends from all over the globe together to celebrate with us.


"Vu Quy" or "tea ceremony" with family. Photo credit: Summer Street Photography

We were married near where we first met on the University of Minnesota east bank campus and the Mississippi river. The photo below is my favorite of the whole day:


Stone Arch Bridge with the Minneapolis downtown in the background. Photo credit: Summer Street Photography

I traveled to many new places this year and got to see friends everywhere I went. This was my first year traveling to New York, Florida, Texas, Rhode Island, and northern Nevada. Places I'm looking forward to exploring in 2024 include Japan, Seattle, and Pittsburgh (see you at PyCon US!)

Elastic had its first Engineering All Hands in-person since COVID to start off 2023 where I got to meet my long-time friend and colleague Quentin Pradet. Quentin and I have been working on open source together for over 5 years and this was our first opportunity to meet in person.


Quentin and I together at Elastic EAH 2023

After 3 great years at Elastic I was hired by the Python Software Foundation to be the Security Developer-in-Residence. I still have days when I think I'm dreaming, I'm so grateful I have the opportunity to work full-time serving a community I love.


Banner included in OpenSSF's announcement of my hiring.

This blog saw a huge burst of activity thanks to my new position where I publish weekly reports on what I've been working on. There were 34 new publications to the blog in 2023 (up from 12 in 2022), of those 24 were related to the Security Developer-in-Residence role.

The top posts by readership for this year were:

If I had to pick a favorite post outside of this list it would be “For You” is not for me discussing my current outlook on internet consumption. Look forward to more posts on the blog, hopefully continuing the trend that I'm on of shorter but more frequent publications.

Outside of software I plan to spend more time playing games (beat Pikmin 4 and Super Mario RPG is in-progress) and learning some hardware-hacking for retro gaming like Gameboy and GameCube modding.

Hope you all had a lovely 2023, looking forward to what we can do in 2024! 🥳

Thanks for reading! ♡ Did you find this article helpful and want more content like it? Get notified of new posts by subscribing to the RSS feed or the email newsletter.

This work is licensed under CC BY-SA 4.0

Categories: FLOSS Project Planets

Paolo Melchiorre: My 2023 in review

Sat, 2023-12-30 18:00

The review of my 2023, trying to remember all the things done in this year, in which more than anyone I met many fantastic people and visited new countries.

Categories: FLOSS Project Planets

Zero to Mastery: Python Monthly Newsletter 💻🐍

Sat, 2023-12-30 11:42
49th issue of Andrei Neagoie's must-read monthly Python Newsletter: Python Errors, Tools in Python Land, Architecting Monorepos, and much more. Read the full newsletter to get up-to-date with everything you need to know from last month.
Categories: FLOSS Project Planets

Matt Layman: Python, Markdown, and Tailwind: Best Buds!

Fri, 2023-12-29 19:00
You are rendering content with Python and want to show some Markdown, but you style your pages with Tailwind. With Tailwind’s built-in reset, how can you style the tags of your rendered HTML that come from Markdown? This article shows how that can be done. Specifically, I am assuming that you are working with Python’s Markdown package. I recently worked on a project where I needed to render some Markdown descriptions.
Categories: FLOSS Project Planets

PyPy: PyPy has moved to Git, GitHub

Fri, 2023-12-29 09:19

PyPy has moved its canonical repo and issue tracker from https://foss.heptapod.net/pypy/pypy to https://github.com/pypy/pypy. Obviously, this means development will now be tracked in Git rather than Mercurial.

Motivation

We still feel Mercurial is a better version control system. The named branch model and user interface are superior. But

  • foss.heptapod.net is not well indexed in google/bing/duckduckgo search, so people find it harder to search for issues in the project.

  • Since Heptapod has tightened its spam control, we get reports that users create issues only to have them flagged as spam.

  • Open Source has become synonymous with GitHub, and we are too small to change that.

  • Much of the current development comes as a reaction to fixing issues. Tracking interlocking issues is easier if all the code is on the same platform.

  • The FAQ presents two arguments against the move. Github notes solves much of point (1): the difficulty of discovering provenance of commits, although not entirely. But the main problem is point (2), it turns out that not moving to GitHub is an impediment to contribution and issue reporting.

  • People who wish to continue to use Mercurial can use the same method below to push to GitHub.

  • GitHub is more resource rich than foss.heptapod.net. We could add CI jobs to replace some of our aging buildbot infrastructure.

Method

The migration required two parts: migrating the code and then migrating the issues and merge requests.

Code migration 1: code and notes

I used a fork of git-remote-hg to create a local Git repo with all the changesets. Then I wanted to add a Git note to each commit with the branch it came from. So I prepared a file with two columns: the Git commit hash, and the corresponding branch from Mercurial. Mercurial can describe each commit in two ways: either the commit hash or by a number index. I used hg log to convert an index i to the Mercurial hash, and then git-hg-helper from git-remote-hg to convert the Mercurial hash to a Git hash:

$(cd pypy-git; git-hg-helper git-rev $(cd ../pypy-hg; hg log -r $i -T"{node}\n"))

Then I used hg log again to print the Mercurial branch for the index i:

$(cd pypy-hg; hg log -r $i -T'{branch}\n')

Putting these two together, I could loop over all the commits by their numerical index to prepare the file. Then I iterated over each line in the file, and added the Git note. Since the git note add command works on the current HEAD, I needed to checkout each commit in turn and then add the note:

git checkout -q <hash> && git notes --ref refs/notes/branch add -m branch:<branch>

I could then use git push --all to push to GitHub.

Code migration 2: prepare the branches

PyPy has almost 500 open branches. The code migration created all the branch HEADs, but git push --all did not push them. I needed to check them out and push each one. So I created a file with all the branch names

cd pypy-hg; hg branches | cut -f1 -d" " > branches.txt

and then push each one to the GitHub repo

while read branch; do git checkout branches/$branch && git push origin branches/$branch; done < branches.txt

Note that the branches were named branches/XXX by the migration, not branch/XXX. This confuses the merge request migration, more about that later.

Issue and merge request migration

I used the solution from node-gitlab-2-github which worked almost perfectly. It is important to do the conversion on a private repo otherwise every mention of a sucessfully mapped user name notifies the user about the transfer. This can be quite annoying for a repo the size of PyPy with 600 merge requests and over 4000 issues. Issues transfered without a problem: the script properly retained the issue numbers. However the script does not convert the Mercurial hashes to Git hashes, so the bare hashes in comments show up without a link to the commit. Merge requests are more of a problem:

  • The Mercurial named branch "disappears" once it is merged, so a merge request to a merged branch does not find the target branch name in Git. The conversion creates an issue instead with the label gitlab merge request.
  • For some reason, the branches created by git-remote-hg are called branches/XXX and not branch/XXX as expected by GitLab. This messes up the merge request/PR conversion. For some of the branches (open PRs and main target branches) I manually created additional branches without the es. The net result is that open merge requests became open PRs, merged merge requests became issues, and closed-not-merged merge requests were not migrated.
Layered conversions

PyPy already migrated once from Bitbucket to Heptapod. Many of the issues reflect the multiple transitions: they have lines like "Created originally on Bitbucket by XXX" from the first transition, and an additional line "In Heptapod" from this transition.

Credits

We would like to express our gratitude to the Octobus team who support Heptapod. The transition from Bitbucket was quite an effort, and they have generously hosted our developement since then. We wish them all the best, and still believe that Mercurial should have "won".

Next steps

While the repo at GitHub is live, there are still a few more things we need to do:

  • Documentation needs an update for the new repo and the build automation from readthedocs must be adjusted.
  • The wiki should be copied from Heptapod.
  • buildbot.pypy.org should also look at the new repo. I hope the code is up to the task of interacting with a Git repo.
  • speed.pypy.org tracks changes, it too needs to reference the new location
  • To keep tracking branches with Git notes on new commits, I activated a github action by Julian to add a Git branch note to each commit. Please see the README there for directions on using Git notes.
  • Some of the merge requests were not migrated. If someone wants to, they could migrate those once they figure out the branch naming problems.

Additionally, now is the time for all of you to prove the move is worthwhile:

  • Star the repo, let others know how to find it,
  • Help fix some of the open issues or file new ones,
  • Take advantage of the more familiar workflow to get involved in the project,
  • Suggest ways to improve the migration: are there things I missed or could have done better?
How will development change?

Heptapod did not allow personal forks, so we were generous with a commit bit to the main repo. Additionally, we (well, me) have been using a commit-directly-to-main workflow. We will now be adopting a more structured workflow. Please fork the repo and submit a pull request for any changes. We can now add some pre-merge CI to check that the PR at least passes the first stage of translation. The live and active branches will be:

  • main: what was "default" in Mercurial, it is the Python2.7 interpreter and the base of the RPython interpreter,
  • py3.9: the Python3.9 interpreter, which also includes all RPython changes from main. This is exactly like on Mercurial, and
  • py3.10: the Python3.10 interpreter, which also includes all RPython changes from main and all bugfixes from py3.9. This is exactly like on Mercurial.
Working between the repos Finding commits

If you want to figure out how a Mercurial commit relates to a Git commit, you can use git-hg-helper. You run it in the Git repo. It takes the full long hash from one repo and gives you the corresponding hash of the other repo:

$ git-hg-helper git-rev d64027c4c2b903403ceeef2c301f5132454491df 4527e62ad94b0e940a5b0f9f20d29428672f93f7 $ git-hg-helper hg-rev 4527e62ad94b0e940a5b0f9f20d29428672f93f7 d64027c4c2b903403ceeef2c301f5132454491df Finding branches

Branches migrated from Mercurial will have a branches prefix, not branch. While GitLab uses branch for its prefix, the git-remote-hg script uses branches. New work should be in a PR targeting main, py3.9 or py3.10.

Thanks for helping to make PyPy better.

Matti

Categories: FLOSS Project Planets

Real Python: The Real Python Podcast – Episode #185: 2023 Real Python Tutorial &amp; Video Course Wrap-Up

Fri, 2023-12-29 07:00

Three members of the Real Python team are joining us this week: Kate Finegan, Tappan Moore, and Philipp Acsany. We wanted to share a year-end wrap-up with tutorials, step-by-step projects, code conversations, and video courses that showcase what our team created this year.

[ 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

The Three of Wands: attrs iv: Zero-overhead Frozen attrs Classes

Fri, 2023-12-29 05:00

Here&aposs a quick and easy one.

attrs supports frozen classes. Frozen classes are cool for a multitude of reasons, but they&aposre a tiny bit slower to instantiate compared to non-frozen classes, because they need to perform some additional checks and avoiding these checks in the __init__ uses a tiny bit of time. (We&aposre talking slotted classes here; which are awesome and the default in attrs nowadays.)

But there&aposs a way to avoid this overhead and make frozen classes be the exact same speed as ordinary classes. The only caveat is: you have to use type-checking.

Create a file somewhere in your code base and put this in it:

from functools import partial from typing import TYPE_CHECKING if TYPE_CHECKING: from attrs import frozen else: from attrs import define frozen = partial(define, unsafe_hash=True)

Now import frozen from this module and use it just like you&aposd use attrs.define or attrs.frozen. You&aposre done!

This technique should also work for dataclasses, with a slight adjustment left as an exercize to the reader.

The eagle-eyed reader might notice that we&aposre actually bamboozling the type-checker: your classes won&apost actually be frozen at runtime. The kicker is: they don&apost actually need to be.

As long as you&aposre running one on your codebase, the typechecker is the actual thing that&aposll prevent you from mutating your instances. The unsafe_hash=True will make the classes hashable, and it&aposs only unsafe if you mutate them after construction, which you won&apost. I guess you&aposll have to be careful when using a REPL or a different context where a typechecker might not hold sway, but I think that&aposs not too big of an issue.

If you&aposre still unconvinced, I&aposll leave you with two final thoughts: the memory in your computer is, ultimately, mutable. What makes immutable data structures in other languages immutable is just the amount of hoops you have to jump through to apply a mutation. This also demonstrates a basic technique statically-compiled languages use to be fast: move part of the work out of runtime into a separate, pre-runtime step. Which is exactly what we&aposve done here.

Happy New Year!

Categories: FLOSS Project Planets

Talk Python to Me: #443: Python Bytes Crossover 2023

Fri, 2023-12-29 03:00
Special crossover episode of Python Bytes to wrap up 2023. Topics include: <br/> <br/> <ol> <ul><strong>Michael #1</strong>: <a href="https://hatch.pypa.io/latest/blog/2023/12/11/hatch-v180/">Hatch v1.8</a></ul> <ul><strong>Brian #2:</strong> <a href="https://svcs.hynek.me/en/stable/">svcs : A Flexible Service Locator for Python</a></ul> <ul><strong>Michael #3:</strong> <a href="https://discuss.python.org/t/steering-council-election-results-2024-term/40851">Steering Council 2024 Term Election Results</a></ul> <ul><strong>Brian #4:</strong> <a href="https://typethepipe.com/post/python-protocols-when-to-use">Python protocols. When to use them in your projects to abstract and decoupling</a></ul> <ul>Extras</ul><ul>Joke: <strong>Joke:</strong> <a href="https://mastodon.social/@tveskov/111289358585305218">The dream is dead?</a></ul></ol><br/> <strong>--- Episode sponsors ---</strong><br/> <a href='https://talkpython.fm/posit'>Posit</a><br> <a href='https://talkpython.fm/training'>Talk Python Training</a>
Categories: FLOSS Project Planets

Go Deh: How not to check for a key in a dictionary.

Thu, 2023-12-28 14:03

 I skim the Linkedin Python group and sometimes comment.

A few days there was a poll asking for the way to check if a key is in a Python dictionary and as I write, more than half of the 900+ respondents have chosen dict.get rather than key in dict, which is the correct answer!

When pushed, it seems they are relying on dict.get returning None if the key is not in the dict, but fail to see tha if the key being tested is in the dict, but has a value of None then their test fails. 

Here's some code:

# %%mydict1 = {'a': 1, 'b': 2}print(mydict1.get('c'))  # -> None
# %%
def key_in_dict1(key_, dict_: dict) -> bool:    "FAULTY IMPLEMENTATION"    return dict_.get(key_) != None
# This worksmydict1 = {'a': 1, 'b': 2}print(key_in_dict1('a', mydict1))  # -> Trueprint(key_in_dict1('x', mydict1))  # -> False# %%
# But adding a key of x with value None gives# the wrong resultmydict2 = {'a': 1, 'b': 2, 'x': None}print(key_in_dict1('x', mydict2))  # -> False
# %%
# The correct way is to use 'in'def key_in_dict2(key_, dict_: dict) -> bool:    "Pythonic IMPLEMENTATION"    return key_ in dict_
# Tests:print(key_in_dict2('a', mydict1))  # -> Trueprint(key_in_dict2('x', mydict1))  # -> False
# %%
# And now for keys with None as a value:print(key_in_dict2('x', mydict2))  # -> True

Ugly, code-golf solution using dict.get()You can alter the default value returned from dict.get if a key is not found. This allows one to use two calls of dict.get with different defaults  to be used to give a correct solution:
def key_in_dict3(key_, dict_: dict) -> bool:    "CODE-GOLF IMPLEMENTATION USING GETs"    default1 = None    default2 = ""    return default1 != default2 \        and ( dict_.get(key_, default1) != default1             or dict_.get(key_, default2) != default2)
# Tests:print(key_in_dict3('a', mydict1))  # -> Trueprint(key_in_dict3('x', mydict1))  # -> Falseprint(key_in_dict3('x', mydict2))  # -> True


Of course, don't use  key_in_dict3, use version 2, i.e. key in dict.
END.
Categories: FLOSS Project Planets

TechBeamers Python: Top 30 Data Engineer Interview Questions with Answers

Thu, 2023-12-28 07:47

If you are planning a job in data engineering, then you should be well prepared for it. We have identified 30 data engineer interview questions that can help in your endeavor. During the interview, you can be asked questions from different related areas. So, we tried to cover these in this tutorial. 30+ Data Engineer […]

The post Top 30 Data Engineer Interview Questions with Answers appeared first on TechBeamers.

Categories: FLOSS Project Planets

Seth Michael Larson: Security Developer-in-Residence Weekly Report #23

Wed, 2023-12-27 19:00
Security Developer-in-Residence Weekly Report #23 AboutBlogNewsletterLinks Security Developer-in-Residence Weekly Report #23

Published 2023-12-28 by Seth Larson
Reading time: minutes

This critical role would not be possible without funding from the OpenSSF Alpha-Omega project. Massive thank-you to Alpha-Omega for investing in the security of the Python ecosystem!

It was a short week this week due to Christmas and New Years holidays in the United States.

This week I spent time learning about the current state of proposals for solving the "index trust" problem for the Python Package Index. There are a few different proposals that have happened in the past being PEP 458 and RSTUF. This learning was to better review a draft proposal for publish provenance (stay tuned!) that also contained some mentions of the index trust problem. Some outcomes we're looking for when solving the index trust problem:

  • Reduce absolute trust in the Python Package Index.
  • Allow for integrity recovery of artifacts hosted on the index in the case of compromise.
  • Allow installers to detect tampering of existing artifacts in a trust-on-first-use (TOFU) fashion even when dependencies aren't pinned using hashes.

Back to publish provenance, I learned more about how NPM is handling their own provenance and made some recommendations about future provenance attestations that might come after publish provenance (like build provenance with the builder workflow ID, git commit, and repo being verifiable!). After thinking about build provenance and how to keep the choice of which builder workflows are "trusted" in the hands of consumers instead of PyPI I created the following quick mockup:

@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css");'PyPIOIDC ProviderBuilder Workflow (Reusable Workflow)Publishing Workflow (User-controlled)PyPIOIDC ProviderBuilder Workflow (Reusable Workflow)Publishing Workflow (User-controlled)#graph-div{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#graph-div .error-icon{fill:#552222;}#graph-div .error-text{fill:#552222;stroke:#552222;}#graph-div .edge-thickness-normal{stroke-width:2px;}#graph-div .edge-thickness-thick{stroke-width:3.5px;}#graph-div .edge-pattern-solid{stroke-dasharray:0;}#graph-div .edge-pattern-dashed{stroke-dasharray:3;}#graph-div .edge-pattern-dotted{stroke-dasharray:2;}#graph-div .marker{fill:#333333;stroke:#333333;}#graph-div .marker.cross{stroke:#333333;}#graph-div svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#graph-div .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#graph-div text.actor>tspan{fill:black;stroke:none;}#graph-div .actor-line{stroke:grey;}#graph-div .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#graph-div .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#graph-div #arrowhead path{fill:#333;stroke:#333;}#graph-div .sequenceNumber{fill:white;}#graph-div #sequencenumber{fill:#333;}#graph-div #crosshead path{fill:#333;stroke:#333;}#graph-div .messageText{fill:#333;stroke:none;}#graph-div .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#graph-div .labelText,#graph-div .labelText>tspan{fill:black;stroke:none;}#graph-div .loopText,#graph-div .loopText>tspan{fill:black;stroke:none;}#graph-div .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#graph-div .note{stroke:#aaaa33;fill:#fff5ad;}#graph-div .noteText,#graph-div .noteText>tspan{fill:black;stroke:none;}#graph-div .activation0{fill:#f4f4f4;stroke:#666;}#graph-div .activation1{fill:#f4f4f4;stroke:#666;}#graph-div .activation2{fill:#f4f4f4;stroke:#666;}#graph-div .actorPopupMenu{position:absolute;}#graph-div .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#graph-div .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#graph-div .actor-man circle,#graph-div line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#graph-div :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}loop[For each distribution ...]Call Builder workflow with git repo, commit SHA parametersProvide OIDC token for signing provenanceBuild Python distributionsSubmit name and digest of distribution and build provenanceVerify provenance is validStore build provenance document awaiting distributionHTTP 200 OKReturn distributions to Publishing WorkflowUpload distributions to PyPIAssociate build provenance with distributionsMake build provenance available programmatically and in the UI
This diagram doesn't represent a concrete proposal.

The only standards that would need agreeing on would be the upload API, the build provenance statement itself, and which parameters have special behavior/meaning for build provenance parameters (ie git repository, git commit SHA). This architecture would allow arbitrary build workflows provenance statements to be submitted to PyPI and verified.

Build provenance provides different guarantees to publish provenance, publish provenance only proves that a given artifact was at one point in the "hands" of the workflow but can't assert where the artifact actually came from without deeper inspection of the workflow. In a way, publish provenance is only making public and verifiable the configuration of a projects' Trusted Publisher at the time of release.

Build provenance from an isolated and trusted build workflow can assert that the artifact was built using a known set of steps and dependencies. It's also likely that there will be far fewer build workflows than projects, meaning that the list of trusted build workflows will be more surmountable to review compared to every publishing workflow of every project and dependency that would be required to review if relying on publish provenance for build integrity.

There's lots of cool stuff coming in this space next year, look forward to more from me and others.

Other items
  • Submitted a pull request for adding the new Software Bill-of-Materials Devguide URL to validation errors.
  • Triaged and responded to multiple security reports submitted to the Python Security Response Team at security@python.org.

That's all for this year! 👋 If you're interested in more you can read last week's report.

Thanks for reading! ♡ Did you find this article helpful and want more content like it? Get notified of new posts by subscribing to the RSS feed or the email newsletter.

This work is licensed under CC BY-SA 4.0

Categories: FLOSS Project Planets

Ned Batchelder: Coverage.py with sys.monitoring

Wed, 2023-12-27 18:03

New in Python 3.12 is sys.monitoring, a lighter-weight way to monitor the execution of Python programs. Coverage.py 7.4.0 now can optionally use sys.monitoring instead of sys.settrace, the facility that has underpinned coverage.py for nearly two decades. This is a big change, both in Python and in coverage.py. It would be great if you could try it out and provide some feedback.

Using sys.monitoring should reduce the overhead of coverage measurement, often lower than 5%, but of course your timings might be different. One of the things I would like to know is what your real-world speed improvements are like.

Because the support is still a bit experimental, you need to define an environment variable to use it: COVERAGE_CORE=sysmon. Eventually, sys.monitoring will be automatically used where possible, but for now you need to explicitly request it.

Some things won’t work with sys.monitoring: plugins and dynamic contexts aren’t yet supported, though eventually they will be. Execution will be faster for line coverage, but not yet for branch coverage. Let me know how it works for you.

This has been in the works since at least March. I hope I haven’t forgotten something silly in getting it out the door.

Categories: FLOSS Project Planets

Brett Cannon: My proof-of-concept record type

Wed, 2023-12-27 14:46

Back in June, I proposed a struct syntax for Python. I shared the post on Mastodon and got some feedback. Afterwards I thought about what I heard and talked it over with some folks. I&aposve now coded up a proof-of-concept to share to get some more feedback from people to gauge whether people in general like this idea.

And so I created the record-type project on PyPI to share a proof-of-concept of what I think a record type could look like if one was ever added to Python. I shared this on discuss.python.org and the feedback was generally positive, so now I&aposm seeking wider feedback via this blog post. To help show what the record-type does, here&aposs the opening example of the dataclasses documentation converted to use record-type:

from records import record @record def InventoryItem(name: str, price: float, *, quantity: int = 0): """Class for keeping track of an item in inventory."""

An example of using records.record

As listed in the README of the project&aposs repository, that decorator creates a class with:

  • __slots__ for performance
  • __match_args__ for pattern matching
  • __annotations__ for runtime type annotations
  • __eq__() for equality based on structure (via __slots__), not inheritance
  • __hash__() for hashing
  • __repr__() which is suitable for eval()
  • Immutability

The goal of this design is:

  • Create a simple data type that&aposs easy to explain to beginners
  • Creating the data type itself should be fast (i.e. no concerns over importing a module with a record type)
  • Type annotations are supported, but not required
  • Instances are immutable to make them (potentially) hashable
  • Support Python&aposs entire parameter definition syntax idiomatically for instance instantiation
  • Support structural typing as much as possible (e.g., equality based on object "shape" instead of inheritance)

Now, in all situations where you try to do something that simplifies classes leads to a comparison with dataclasses. Here&aposs the same example, but with dataclasses:

from dataclasses import dataclass, KW_ONLY @dataclass(frozen=True, slots=True) class InventoryItem: """Class for keeping track of an item in inventory.""" name: str price: float _: KW_ONLY quantity: int = 0

The same example using dataclasses.dataclass

Is that worse than the example using record-type? Is any of this compelling enough to turn what record-type proposes into actual syntax? I&aposve had some ask for method support, but I personally like the simplicity of leaning into a data-only approach (see my struct syntax post for more of an explanation). I personally like the structural equality, but I suspect some would be willing to give it up if performance could be improved for equality comparisons.

Anyway, based on the response I may write a PEP to see if there&aposs enough traction to add syntax for this (replies on Mastodon are probably the easiest way to express an opinion).

Categories: FLOSS Project Planets

TechBeamers Python: Understanding the Floor Function in Python

Wed, 2023-12-27 14:24

The floor function in Python is a mathematical operation that rounds down a given number to the nearest integer that is less than or equal to the original number. In this tutorial, we will delve into the floor function, exploring its usage, abilities, and various methods for implementation. We will cover the basics of the […]

The post Understanding the Floor Function in Python appeared first on TechBeamers.

Categories: FLOSS Project Planets

TechBeamers Python: Python Str Function Explained in Detail

Wed, 2023-12-27 11:24

In this tutorial, we will delve into the str function in Python to understand its capabilities, usage, and practical applications. Python, being a versatile and user-friendly programming language, offers a plethora of built-in functions that simplify various tasks. One such fundamental function is str, which plays a crucial role in working with strings. Understanding the […]

The post Python Str Function Explained in Detail appeared first on TechBeamers.

Categories: FLOSS Project Planets

TechBeamers Python: How to Get the Working Directory in Python

Wed, 2023-12-27 09:37

There are multiple ways to get the working directory in Python. Let’s check them out one by one. Later, you can decide which is the most suitable for your case. What are Different Methods to Get the Working Directory in Python? While working on different projects you need to get the current directory in Python […]

The post How to Get the Working Directory in Python appeared first on TechBeamers.

Categories: FLOSS Project Planets

Doug Hellmann: virtualenvwrapper 6.0.0

Wed, 2023-12-27 07:28
What’s Changed Breaking Changes formally drop Python 2 support remove toggleglobalsitepackages command, since virtualenv seems to have removed that capability\ drop ksh support by @dhellmann in https://github.com/python-virtualenvwrapper/virtualenvwrapper/pull/27 remove python2 from startup logic for finding the python interpreter by @dhellmann in https://github.com/python-virtualenvwrapper/virtualenvwrapper/pull/28 Updated tested Python versions in README. by @carltongibson in https://github.com/python-virtualenvwrapper/virtualenvwrapper/pull/37 Features add a –version option to the hook loader by @dhellmann in https://github.com/python-virtualenvwrapper/virtualenvwrapper/pull/43 Miscellaneous Improvements switch to implicit namespaces by @dhellmann in https://github.
Categories: FLOSS Project Planets

TechBeamers Python: How to Find a Job in Python – Things You Need to Do

Wed, 2023-12-27 06:20

Are you eager to find a job in Python? Whether you’re a recent graduate or an experienced professional, navigating the job market in the Python ecosystem can be both challenging and rewarding. Your Essential Guide to Find a Job in Python In this extensive tutorial, we’ll explore various aspects of how to find jobs in […]

The post How to Find a Job in Python – Things You Need to Do appeared first on TechBeamers.

Categories: FLOSS Project Planets

Pages