Feeds
The Drop Times: Policy-Based Access in Core by Kristiaan Van den Enyde
Tag1 Consulting: Migrating Your Data from Drupal 7 to Drupal 10 using the Migrate API: Avoiding entity ID conflicts
By default, the Drupal 7 to 10 upgrade path preserves entity IDs. In the previous article, we explained that this would cause problems if content or configuration already exists in the destination Drupal 10 site. Let’s explore this further and evaluate ways to work around the issue.
Read more mauricio Wed, 05/15/2024 - 14:15Debug Academy: How to create custom sorting logic for Drupal views
Drupal websites sometimes have a need to implement more advanced sorting logic than what's available out of the box.
One of our career-changing Drupal training course alumni asked me how to handle this today. After answering them, I decided to copy the answer into a blogpost.
The views module creates dynamic queries for us based on the configuration options we select. The UI essentially allows us to use any field for sorting in ascending (smallest to largest) or descending (largest to smallest) order. This is extremely helpful and covers the vast majority of use cases - date sorting, alphabetical sorting, and numeric sorting are all supported - but we sometimes run into limitations when we have more complicated requirements.
Some examples of these scenarios include:
ashrafabed Wed, 05/15/2024Dirk Eddelbuettel: RApiSerialize 0.1.3 on CRAN: Skipping XDR
A new bug fix release 0.1.3 of RApiSerialize got onto CRAN earlier today. This is the first release in well over a year, and permits the skip the XDR serialization format which is needed when transfering between big- and little-endian machines. But it comes at a certain run-time cost one can avoid on the (much more common) little-endian machines. This is a new option, and the old behavior is the default. Those who want to can now skip the step.
The RApiSerialize package is used by both my RcppRedis as well as by Travers excellent qs package. We also addressed the recent nag by the CRAN concerning ‘NO_REMAP’.
Changes in version 0.1.3 (2024-05-13)Add an xdr argument to disable XDR for an approx. threefold speed increase (Travers Ching and Dirk in #6)
Use R_NO_REMAP and Rf_* prefix for API calls
Minor continuous integration updates
Courtesy of my CRANberries, there is a diffstat report relative to previous release. More details are at the RApiSerialize page; code, issue tickets etc at the GitHub repositoryrapiserializerepo.
If you like this or other open-source work I do, you can sponsor me at GitHub.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.
Evgeni Golov: Using Packit to build RPMs for projects that depend on or vendor your code
I am a huge fan of Packit as it allows us to provide RPMs to our users and testers directly from a pull-request, thus massively tightening the feedback loop and involving people who otherwise might not be able to apply the changes (for whatever reason) and "quickly test" something out. It's also a great way to validate that a change actually builds in a production environment, where no unnecessary development and test dependencies are installed.
You can also run tests of the built packages on Testing Farm and automate pushing releases into Fedora/CentOS Stream, but this is neither a (plain) Packit advertisement post, nor is that functionality that I can talk about with a certain level of experience.
Adam recently asked why we don't have Packit builds for our our Puppet modules and my first answer was: "well, puppet-* doesn't produce a thing we ship directly, so nobody dared to do it".
My second answer was that I had blogged how to test a Puppet module PR with Packit, but I totally agree that the process was a tad cumbersome and could be improved.
Now some madman did it and we all get to hear his story! ;-)
What is the problem anyway?The Foreman Installer is a bit of Ruby code1 that provides a CLI to puppet apply based on a set of Puppet modules. As the Puppet modules can also be used outside the installer and have their own lifecycle, they live in separate git repositories and their releases get uploaded to the Puppet Forge. Users however do not want to (and should not have to) install the modules themselves.
So we have to ship the modules inside the foreman-installer package. Packaging 25 modules for two packaging systems (we support Enterprise Linux and Debian/Ubuntu) seems like a lot of work. Especially if you consider that the main foreman-installer package would need to be rebuilt after each module change as it contains generated files based on the modules which are too expensive to generate at runtime.
So we can ship the modules inside the foreman-installer source release, thus vendoring those modules into the installer release.
To do so we use librarian-puppet with a Puppetfile and either a Puppetfile.lock for stable releases or by letting librarian-puppet fetch latest for nightly snapshots.
This works beautifully for changes that land in the development and release branches of our repositories - regardless if it's foreman-installer.git or any of the puppet-*.git ones. It also works nicely for pull-requests against foreman-installer.git.
But because the puppet-* repositories do not map to packages, we assumed it wouldn't work well for pull-requests against those.
How can we solve this?Well, the "obvious" solution is to build the foreman-installer package via Packit also for pull-requests against the puppet-* repositories. However, as usual, the devil is in the details.
Packit by default clones the repository of the pull-request and tries to create a source tarball from that using git archive. As this might be too simple for many projects, one can define a custom create-archive action that runs after the pull-request has been cloned and produces the tarball instead. We already use that in the Packit configuration for foreman-installer to run the pkg:generate_source rake target which executes librarian-puppet for us.
But now the pull-request is against one of the Puppet modules, so Packit will clone that, not the installer.
We gotta clone foreman-installer on our own. And then point librarian-puppet at the pull-request. Fun.
Cloning is relatively simple, call git clone -- sorry Packit/Copr infrastructure.
But the Puppet module pull-request? One can use :git => 'https://git.example.com/repo.git' in the Puppetfile to fetch a git repository. In fact, that's what we already do for our nightly snapshots. It also supports :ref => 'some_branch_or_tag_name', if the remote HEAD is not what you want.
My brain first went "I know this! GitHub has this magic refs/pull/1/head and refs/pull/1/merge refs you can checkout to get the contents of the pull-request without bothering to add a remote for the source of the pull-request". Well, this requires to know the ID of the pull-request and Packit does not expose that in the environment variables available during create-archive.
Wait, but we already have a checkout. Can we just say :git => '../.git'? Cloning a .git folder is totally possible after all.
[Librarian] --> fatal: repository '../.git' does not exist Could not checkout ../.git: fatal: repository '../.git' does not existSeems librarian disagrees. Damn. (Yes, I checked, the path exists.)
💡 does it maybe just not like relative paths?! Yepp, using an absolute path absolutely works!
For some reason it ends up checking out the default HEAD of the "real" (GitHub) remote, not of ../. Luckily this can be fixed by explicitly passing :ref => 'origin/HEAD', which resolves to the branch Packit created for the pull-request.
Now we just need to put all of that together and remember to execute all commands from inside the foreman-installer checkout as that is where all our vendoring recipes etc live.
Putting it all togetherLet's look at the diff between the packit.yaml for foreman-installer and the one I've proposed for puppet-pulpcore:
--- a/foreman-installer/.packit.yaml 2024-05-14 21:45:26.545260798 +0200 +++ b/puppet-pulpcore/.packit.yaml 2024-05-14 21:44:47.834162418 +0200 @@ -18,13 +18,15 @@ actions: post-upstream-clone: - "wget https://raw.githubusercontent.com/theforeman/foreman-packaging/rpm/develop/packages/foreman/foreman-installer/foreman-installer.spec -O foreman-installer.spec" + - "git clone https://github.com/theforeman/foreman-installer" + - "sed -i '/theforeman.pulpcore/ s@:git.*@:git => \"#{__dir__}/../.git\", :ref => \"origin/HEAD\"@' foreman-installer/Puppetfile" get-current-version: - - "sed 's/-develop//' VERSION" + - "sed 's/-develop//' foreman-installer/VERSION" create-archive: - - bundle config set --local path vendor/bundle - - bundle config set --local without development:test - - bundle install - - bundle exec rake pkg:generate_source + - bash -c "cd foreman-installer && bundle config set --local path vendor/bundle" + - bash -c "cd foreman-installer && bundle config set --local without development:test" + - bash -c "cd foreman-installer && bundle install" + - bash -c "cd foreman-installer && bundle exec rake pkg:generate_source"- It clones foreman-installer (in post-upstream-clone, as that felt more natural after some thinking)
- It adjusts the Puppetfile to use #{__dir__}/../.git as the Git repository, abusing the fact that a Puppetfile is really just a Ruby script (sorry Ben!) and knows the __dir__ it lives in
- It fetches the version from the foreman-installer checkout, so it's sort-of reasonable
- It performs all building inside the foreman-installer checkout
I hope so! Vendoring is not unheard of. And testing your "consumers" (dependents? naming is hard) is good style anyway!
The Accidental Coder: AI Translation - Not Ready for Prime Time?
While working on the latest (D10) version of my blog, I wanted to add multilingual functionality.
Investigation suggested that in order to capture the largest language groups in the U.S./Canada a site should offer:
PyCoder’s Weekly: Issue #629 (May 14, 2024)
#629 – MAY 14, 2024
View in Browser »
In this video course, you’ll learn how to flatten a list of lists in Python. You’ll use different tools and techniques to accomplish this task. First, you’ll use a loop along with the .extend() method of list. Then you’ll explore other tools, including reduce(), sum(), itertools.chain(), and more.
REAL PYTHON course
Python 3.13 has gone into beta, which means the feature freeze is now in place. This is the official listing of the new features in 3.13. This release includes changes to the REPL, new typing features, experimental support for disabling the GIL, dead battery removal, and more.
PYTHON
Join us on May 30th: we’ll give a brief overview of Sagas, including challenges and benefits. Then we’ll introduce you to Temporal and demonstrate how easy it is to build, test, and run Sagas using our platform and coding in your preferred language. Prior knowledge of Temporal is not required →
TEMPORAL sponsor
A set is a built-in data type that provides fast lookup and insertion with characteristics similar to those of dictionary keys. This article explores the relationship between sets and dictionaries by implementing a set class.
RODRIGO GIRÃO SERRÃO
This is a deep, in the weeds analysis of how different packages can store the same kinds of data in a different order, and how row-based vs column-based storage order can affect NumPy’s speed to process the data. The not often examined “strides” value of a NumPy array specifies how things are stored and this article shows an interesting approach to getting around this value for speed-up.
YOSSI KREININ
Python 3.13 just hit feature freeze with the first beta release, and it includes a host of improvements to the REPL. Automatic indenting, block-level editing, and more make the built-in REPL more powerful and easier to use.
TREY HUNNER
Apache Parquet files are a popular columnar storage format used by data scientists and anyone using the Hadoop ecosystem. By using the pyarrow package, you can read and write Parquet files, this tutorial shows you how.
MIKE DRISCOLL
Writing good tests means having data to test with. The factory-boy library helps you create fake data that you can use with your tests. This article shows you how to use factory-boy with Django ORM models.
AIDAS BENDORAITIS
This tutorial dives into Python sequences, which is one of the main categories of data types. You’ll learn about the properties that make an object a sequence and how to create user-defined sequences.
REAL PYTHON
You’ve probably come across articles on Large Language Models (LLMs) and may have tried products like ChatGPT. This article explains how these tools work without resorting to advanced math.
MIGUEL GRINBERG
wxPython is a GUI toolkit for the Python programming language. This article introduces you to building GUIs by creating a personal calculator.
MIKE DRISCOLL
Ever wanted to add concurrency to your concurrency? You can run multiple asyncio event loops by using threading. This articles shows you how.
JASON BROWNLEE
This article explains how asyncio works by showing you how to re-create it using generators and the __await__ method.
JACOB PADILLA • Shared by Jacob Padilla
Nat responds to a presentation by C J Silverio on how software gets made at small to medium sized organizations.
NAT BENNETT
May 15, 2024
REALPYTHON.COM
May 15 to May 24, 2024
PYCON.ORG
May 16, 2024
MEETUP.COM
May 16, 2024
PYLADIES.COM
May 17 to May 18, 2024
FLASKCON.COM
May 17 to May 18, 2024
PYGRUNN.ORG
May 17, 2024
OPENLAB.EC
Happy Pythoning!
This was PyCoder’s Weekly Issue #629.
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 ]
Aten Design Group: Drupal API Development Simplified with APITools Module
One of Drupal’s most important features is its ability to integrate seamlessly with other systems (CRMs, eCommerce Platforms, Event Management Platforms, etc). Drupal can expose data using modules like JSON:API, which are integral parts of Drupal Core. Moreover, it can also consume data and make HTTP requests using standard HTTP methods. This post will focus primarily on the latter—highlighting how a module named APITools simplifies the process for Drupal developers.
BackgroundIn researching the history of HTTP request handling in Drupal, I discovered that drupal_http_request has been around since version 5.x. It was described as:
"A flexible and powerful HTTP client implementation that correctly handles GET, POST, PUT, or any other HTTP requests, including handling redirects."
Throughout Drupal versions 6.x and 7.x, drupal_http_request continued to be a go-to option, seemingly simpler than using PHP's CURL function directly—a tool that many developers find intricate. With the release of Drupal 8, Drupal::httpClient replaced drupal_http_request, granting developers access to Guzzle—the de facto HTTP client in the PHP community.
While httpClient/Guzzle is typically the preferred choice for HTTP requests, it's rare that any request happens without some form of authentication. Although OAuth 2 has emerged as a standard for API authentication, the specifics can vary considerably between different APIs. This variability doesn’t mean the principles of OAuth 2 aren’t followed; rather, the implementations differ just enough that attempts to abstract this functionality into a universal module have faced challenges. As a result, developers frequently find themselves writing slightly different code for each API integration to accommodate these nuances. APITools attempts to be just helpful enough in these sorts of situations without making too many assumptions.
Leveraging APITools for the Drupal Zoom API ModuleI personally maintain the Drupal Zoom API module, and over the past year, Zoom has changed their authentication requirements. This challenge prompted me to explore the APITools module, maintained by my friend and colleague Alan Sherry. What attracted me most to APITools was its ability to offer configurable options for storing credentials and an extensible client plugin that routes all API requests through a specified authentication method. By using APITools, I significantly reduced the amount of code in the Zoom API module and quickly released a version 3.x, which is compatible with Zoom’s "Server-to-Server OAuth" authentication method. The configuration form and the majority of the API client are now provided by APITools, reducing the amount of code I’ll need to maintain in the Zoom API module.
If you, like me, maintain an API-focused contrib module or need a reliable HTTP client for one-off tasks, I highly encourage you to explore APITools. With a little setup time, you can configure your ApiToolsClient and start making requests effortlessly.
The fact is, there are numerous API client modules on Drupal.org, each tailored for different services. APITools offers an opportunity for a more consistent and efficient approach. I hope you'll check it out!
Getting Started / ExamplesWe've written some documentation on Drupal.org for you to reference. For a fairly complete example in the Drupal contrib space, checkout the client plugin that is part of the Zoom API module.
Additional ExamplesWe’ve created a repository with some various API clients that will hopefully help with getting started.
- Acalog - Simple api key implementation
- Auth0 - Access token request with audience and grant type
- Brandfolder - An example of using an sdk as a base with an apitools client wrapper around it
- Localist - Example of a static access token created by an administrator
- Sharepoint - Access token with audience / grant type, and “ext_expires_in” instead of “expires_in”
If you decide to use APITools, we’d love to hear about your experience in the blog comments below.
Joel SteidlFSF Blogs: We need your help to release the LibrePlanet 2024 videos
ADCI Solutions: How to quickly integrate Angular with a Drupal website
Open Source AI Definition – Weekly update May 13
- Apple has released a license to distribute its new model, OpenELM. The license looks BSD/MIT-like with the exclusion of patents. According to you, does it seem OSD compliant?
- Initial thoughts:
- @pchestek added that the license appears to be similar to open source but raises concerns about potential limitations on rights, particularly regarding patents. It highlights Apple’s approach of granting only a copyright license, which might not be sufficient for ensuring all necessary freedoms, especially in the context of AI models
- @shujisado agreed, saying that the terms related to trademarks and patents need to be scrutinized
- @Aspie96 asks clarifying questions regarding the list of open components and points out how, unlike “traditional” software which can be released as open source software without as easy as proprietary software, this definition seem to require a lot more components to be open.
- Stefano points out that “The “classic” Open Source Definition is applied to licenses, not to the software” and “ if a program is shipped with a license approved by the OSI then the software is considered Open Source”
- He further states that “Through the co-design process of the Open Source AI Definition we learned that to use, study, share and modify an ML system one needs a complex combo of multiple components each following diverse legal regimes (not just the usual copyright+patents.) Therefore we must describe in more details what is required to grant users the agency and control expected.”
- The frequently asked questions page is starting to take form
- We add relevant questions that have arisen from the forums so far, though if you have any contributions in mind, please leave a comment!
This week, Stefano, Mer and the OSI team are visiting Pittsburgh, PA, hosting the first workshop of our Open Source AI Definition Roadshow! We are starting to get more in-person feedback on our draft definition.
If you are at PyCon come visit us on the 17th, from 11 am to 1pm in the Open Space area!
Programiz: Python List
Real Python: HTML and CSS Foundations for Python Developers
When you want to build websites as a Python programmer, there’s no way around HTML and CSS. Almost every website on the Internet is built with HTML markup to structure the page. To make a website look nice, you can style HTML with CSS.
If you’re interested in web development with Python, then knowing HTML and CSS will help you understand web frameworks like Django and Flask better. But even if you’re just getting started with Python, HTML and CSS can enable you to create small websites to impress your friends.
In this video course, you’ll learn how to:
- Structure a basic HTML file
- View and inspect HTML in your browser
- Insert images and page links
- Style a website with CSS
- Format HTML with accessibility in mind
- Use Python to write and parse HTML code
[ 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 ]
Matt Glaman: Starshot, recipe to cook up ambitious Drupal applications
This blog post was inspired by my time at DrupalCon Portland and the Driesnote, announcing Starshot.
There has also been a story about Drupal being a series of building blocks for building your own CMS (or other application). Often, it has been compared to building a LEGO® set. The idea is that you have Drupal core and contributed modules, acting as individual pieces, to build an application that meets your desired needs. Oftentimes, this could be done without writing any code. As someone who built with Drupal, this made so much sense. You take disparate components, build on a solid base, and have this magical software built with minimal code (if you choose) that meets your needs. That metaphor always stuck, but it was pretty flawed, and I never really understood why until DrupalCon Portland 2024, last week.
KDE e.V. is looking for a graphic designer for environmental sustainability project
KDE e.V., the non-profit organisation supporting the KDE community, is looking for a graphic designer to implement materials (print design, logo design, infographics, etc.) for a new environmental sustainability campaign within KDE Eco. Please see the job ad for more details about this employment opportunity.
We are looking forward to your application.
PyCharm: PyCharm at PyCon US 2024: Engage, Learn, and Celebrate!
We’re thrilled to announce that the PyCharm team will be part of the vibrant PyCon US 2024 conference in Pittsburgh, Pennsylvania, USA. Join us for a series of engaging activities, expert talks, live demonstrations, and fun quizzes throughout the event!
Here’s a sneak peek at what we have lined up for you. Unless otherwise specified, all activities mentioned will take place at the JetBrains PyCharm booth.
Engaging talks and live demonstrations1. Lies, damned lies, and large language models
Speaker: Jodie Burchell
Dive into the intricacies of large language models (LLMs) with Jodie Burchell’s talk. Discover the reasons behind LLM hallucinations and explore methods like retrieval augmented generation (RAG) to mitigate these issues.
📅 Date and time: May 18, 1:45 pm – 2:15 pm
📍 Location: Ballroom BC
Learn more about this talk
2. XGBoost demo and book signing with Matt Harrison
Get hands-on with XGBoost in this engaging demo, during which you can ask Matt Harrison any questions you have about the gradient boosting library.
📅 Date and time: May 17, 10:30 am
🎁 Giveaway: The first 20 attendees will get a free signed copy of Effective XGBoost.
3. Build a fully local RAG app for a variety of files in just 20 minutes
Presenter: Maria Khalusova
Watch a live demonstration on setting up a fully local RAG application in just 20 minutes. Gain insights from Maria Khalusova, an expert from Unstructured and former Hugging Face employee.
📅 Date and time: May 17, 4:10 pm
4. PyCharm on-demand demos
Discover how to boost your efficiency in data science and web development projects with PyCharm’s latest features. Have any questions or feedback? Our team lead, product manager, and developer advocates will be there to discuss everything PyCharm with you.
5. Qodana on-demand demos
Enhance your team’s code quality with our Qodana static code analysis tool. Drop by the PyCharm booth for on-demand demos and learn how to maintain high-quality, secure, and maintainable code.
1. Data science quizzes with Matt Harrison
Kick off the event with our exciting quiz session during the opening reception. Engage in challenging questions and stand a chance to win a copy of Effective Pandas 2.0.
📅 Date and time: May 16, 5:30 pm
2. More quizzes! More prizes!
Continue testing your knowledge on May 17 at 1:20 pm. Win a one-year subscription to PyCharm Professional or a voucher for JetBrains merch.
1. Share your Python story
Want to share your Python experiences with us? Get interviewed by Paul Everitt at our booth! Our video crew will be on-site throughout the conference to capture your stories and insights.
2. Talk Python To Me: Live podcast recording
Join Michael Kennedy for a live recording with guests Maria Jose Molina-Contreras, Jessica Greene, and Jodie Burchell.
📅 Date and time: May 18, 10:10 am
2. The Black Python Dev community’s first anniversary
Celebrate the Black Python Developers group’s milestone with Jay Miller.
📅 Date and time: May 18, 12:45 pm
3. Frontend testing office hours with Paul Everitt
Got questions about frontend testing? Paul Everitt has the answers! Visit our booth to engage directly with an expert.
📅 Date and time: May 18, 3:45 pm
Don’t miss out on these exciting opportunities to deepen your knowledge, network with peers, and celebrate achievements in the Python community. See you there!
PyCon: Get ready for PyCon US 2024! Tips and tricks from our community.
If you’re wondering about who else you will meet or what to do during your time at the conference, check out this video to hear advice from other experienced PyCon US attendees.
Thank you to our community members for helping us with the creation of the video, and for sharing their experiences and advice to the community:
- Carol Willing
- Ned Batchelder
- Ngazetungue Muheue
- Donghee Na
- Kojo Idrissa
- Abigail Afi Gbadago
- Velda Kiara
- Kattni Rembor
- Takanori Suzuki
- Denny Perez
- Maria Jose Molina
- Mario Munoz
- Tammy Do
- Jules/Juliana Barros Lima
In addition to all the talks, tutorials, Charlas, and keynotes, PyCon US offers additional activities and events, including Open Spaces, Sprints, Summits. Check out the full list on our conference website under the Events menu.
First time attendee at PyCon US are recommended to attend the Newcomer Orientation on Thursday at 4:30 PM.
Also new this year is the Hatchery Programs, which features four new tracks. While some of the Hatchery programs are now full, you will be delighted to know you don’t need to sign up in order to attend FlaskCon. Be sure to check them out.
Thank you everyone! Safe travels, and we look forward to meeting you soon!
Not yet registered for PyCon US? You still have time to register and join us either in-person or online.
Register here: https://us.pycon.org/2024/registration/register
Check our full schedule: https://us.pycon.org/2024/schedule/Julian Andres Klode: The new APT 3.0 solver
APT 2.9.3 introduces the first iteration of the new solver codenamed solver3, and now available with the –solver 3.0 option. The new solver works fundamentally different from the old one.
How does it work?Solver3 is a fully backtracking dependency solving algorithm that defers choices to as late as possible. It starts with an empty set of packages, then adds the manually installed packages, and then installs packages automatically as necessary to satisfy the dependencies.
Deferring the choices is implemented multiple ways:
First, all install requests recursively mark dependencies with a single solution for install, and any packages that are being rejected due to conflicts or user requests will cause their reverse dependencies to be transitively marked as rejected, provided their or group cannot be solved by a different package.
Second, any dependency with more than one choice is pushed to a priority queue that is ordered by the number of possible solutions, such that we resolve a|b before a|b|c.
Not just by the number of solutions, though. One important point to note is that optional dependencies, that is, Recommends, are always sorting after mandatory dependencies. Do note on that: Recommended packages do not “nest” in backtracking - dependencies of a Recommended package themselves are not optional, so they will have to be resolved before the next Recommended package is seen in the queue.
Another important step in deferring choices is extracting the common dependencies of a package across its version and then installing them before we even decide which of its versions we want to install - one of the dependencies might cycle back to a specific version after all.
Decisions about package levels are recorded at a certain decision level, if we reach a conflict we backtrack to the previous decision level, mark the decision we made (install X) in the inverse (DO NOT INSTALL X), reset all the state all decisions made at the higher level, and restore any dependencies that are no longer resolved to the work queue.
Comparison to SAT solver design.If you have studied SAT solver design, you’ll find that essentially this is a DPLL solver without pure literal elimination. A pure literal eliminitation phase would not work for a package manager: First negative pure literals (packages that everything conflicts with) do not exist, and positive pure literals (packages nothing conflicts with) we do not want to mark for install - we want to install as little as possible (well subject, to policy).
As part of the solving phase, we also construct an implication graph, albeit a partial one: The first package installing another package is marked as the reason (A -> B), the same thing for conflicts (not A -> not B).
Once we have added the ability to have multiple parents in the implication graph, it stands to reason that we can also implement the much more advanced method of conflict-driven clause learning; where we do not jump back to the previous decision level but exactly to the decision level that caused the conflict. This would massively speed up backtracking.
What changes can you expect in behavior?The most striking difference to the classic APT solver is that solver3 always keeps manually installed packages around, it never offers to remove them. We will relax that in a future iteration so that it can replace packages with new ones, that is, if your package is no longer available in the repository (obsolete), but there is one that Conflicts+Replaces+Provides it, solver3 will be allowed to install that and remove the other.
Implementing that policy is rather trivial: We just need to queue obsolete | replacement as a dependency to solve, rather than mark the obsolete package for install.
Another critical difference is the change in the autoremove behavior: The new solver currently only knows the strongest dependency chain to each package, and hence it will not keep around any packages that are only reachable via weaker chains. A common example is when gcc-<version> packages accumulate on your system over the years. They all have Provides: c-compiler and the libtool Depends: gcc | c-compiler is enough to keep them around.
New featuresThe new option --no-strict-pinning instructs the solver to consider all versions of a package and not just the candidate version. For example, you could use apt install foo=2.0 --no-strict-pinning to install version 2.0 of foo and upgrade - or downgrade - packages as needed to satisfy foo=2.0 dependencies. This mostly comes in handy in use cases involving Debian experimental or the Ubuntu proposed pockets, where you want to install a package from there, but try to satisfy from the normal release as much as possible.
The implication graph building allows us to implement an apt why command, that while not as nicely detailed as aptitude, at least tells you the exact reason why a package is installed. It will only show the strongest dependency chain at first of course, since that is what we record.
What is left to do?At the moment, error information is not stored across backtracking in any way, but we generally will want to show you the first conflict we reach as it is the most natural one; or all conflicts. Currently you get the last conflict which may not be particularly useful.
Likewise, errors currently are just rendered as implication graphs of the form [not] A -> [not] B -> ..., and we need to put in some work to present those nicely.
The test suite is not passing yet, I haven’t really started working on it. A challenge is that most packages in the test suite are manually installed as they are mocked, and the solver now doesn’t remove those.
We plan to implement the replacement logic such that foo can be replaced by foo2 Conflicts/Replaces/Provides foo without needing to be automatically installed.
Improving the backtracking to be non-chronological conflict-driven clause learning would vastly enhance our backtracking performance. Not that it seems to be an issue right now in my limited testing (mostly noble 64-bit-time_t upgrades). A lot of that complexity you have normally is not there because the manually installed packages and resulting unit propagation (single-solution Depends/Reverse-Depends for Conflicts) already ground us fairly far in what changes we can actually make.
Once all the stuff has landed, we need to start rolling it out and gather feedback. On Ubuntu I’d like automated feedback on regressions (running solver3 in parallel, checking if result is worse and then submitting an error to the error tracker), on Debian this could just be a role email address to send solver dumps to.
At the same time, we can also incrementally start rolling this out. Like phased updates in Ubuntu, we can also roll out the new solver as the default to 10%, 20%, 50% of users before going to the full 100%. This will allow us to capture regressions early and fix them.