{"id":1072,"date":"2019-12-24T23:59:58","date_gmt":"2019-12-24T22:59:58","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=1072"},"modified":"2019-12-25T00:37:12","modified_gmt":"2019-12-24T23:37:12","slug":"handling-pep-517-pyproject-toml-packages-in-gentoo","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2019\/12\/24\/handling-pep-517-pyproject-toml-packages-in-gentoo\/","title":{"rendered":"Handling PEP 517 (pyproject.toml) packages in\u00a0Gentoo"},"content":{"rendered":"<p>So far, the&nbsp;majority of&nbsp;Python packages have either used distutils, or&nbsp;a&nbsp;build system built upon it.  Most frequently, this was <a href=\"https:\/\/github.com\/pypa\/setuptools\">setuptools<\/a>.  All those solutions provided a&nbsp;<code>setup.py<\/code> script with a&nbsp;semi-standard interface, and&nbsp;we were able to&nbsp;handle them reliably within <code>distutils-r1.eclass<\/code>.  <a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0517\/\">PEP 517<\/a> changed that.<\/p>\n<p>Instead of&nbsp;a&nbsp;setup script, packages now only need to&nbsp;supply a&nbsp;declarative project information in&nbsp;<code>pyproject.toml<\/code> file (fun fact: TOML parser is not&nbsp;even part of&nbsp;Python stdlib yet).  The&nbsp;build system used is specified as&nbsp;a&nbsp;combination of&nbsp;a&nbsp;package requirement and&nbsp;a&nbsp;backend object to&nbsp;use.  The&nbsp;backends are expected to&nbsp;provide a&nbsp;very narrow API: it&#8217;s limited to&nbsp;building wheel packages and&nbsp;source distribution tarballs.<\/p>\n<p>The&nbsp;new build systems built around this concept are troublesome to&nbsp;Gentoo.  They are more focused on&nbsp;being standalone package managers than build systems.  They lack the&nbsp;APIs matching our needs.  They have large dependency trees, including circular dependencies.  Hence, we&#8217;ve decided to&nbsp;try an&nbsp;alternate route.<br \/>\n<!--more--><br \/>\nInstead of&nbsp;trying to&nbsp;tame the&nbsp;new build systems, or&nbsp;work around their deficiencies (i.e.&nbsp;by&nbsp;making them build wheel packages, then unpacking and&nbsp;repackaging them), we&#8217;ve explored the&nbsp;possibility of&nbsp;converting the&nbsp;<code>pyproject.toml<\/code> files into&nbsp;<code>setup.py<\/code> scripts.  Since the&nbsp;new formats are declarative, this should not be that hard.<\/p>\n<p>We&#8217;ve found <a href=\"https:\/\/github.com\/orsinium\/poetry-setup\">poetry-setup<\/a> project which seemed to&nbsp;have a&nbsp;similar goal.  However, it was already discontinued at&nbsp;the&nbsp;time in&nbsp;favor of&nbsp;<a href=\"https:\/\/github.com\/dephell\/dephell\">dephell<\/a>.  The&nbsp;latter project looked pretty powerful but&nbsp;the&nbsp;name was pretty ominous.  We did not need most of&nbsp;the&nbsp;functions, and&nbsp;it was hell to&nbsp;package.<\/p>\n<p>Finally, I&#8217;ve managed to&nbsp;dedicate some time into building an&nbsp;in-house solution instead.  <a href=\"https:\/\/github.com\/mgorny\/pyproject2setuppy\">pyproject2setuppy<\/a> is a&nbsp;small-ish (&lt;100 SLOC) <code>pyproject.toml<\/code>-to-setuptools adapter which allows us to&nbsp;run flit- or&nbsp;poetry-based projects as&nbsp;if&nbsp;they used regular distutils.  While it&#8217;s quite limited, it&#8217;s good enough to&nbsp;build and&nbsp;install the&nbsp;packages that we needed to&nbsp;deal with so far.<\/p>\n<p>The&nbsp;design is quite simple \u2014 it reads <code>pyproject.toml<\/code> and&nbsp;calls setuptools&#8217; <code>setup()<\/code> function with the&nbsp;metadata read.  As&nbsp;such, the&nbsp;package can even be&nbsp;used to&nbsp;provide a&nbsp;backwards-compatible <code>setup.py<\/code> script in&nbsp;other packages.  In&nbsp;fact, this is how its own <code>setup.py<\/code> works \u2014 it carries flit-compatible <code>pyproject.toml<\/code> and&nbsp;uses itself to&nbsp;install itself via&nbsp;setuptools.<\/p>\n<p><code>dev-python\/pyproject2setuppy<\/code> is already packaged in&nbsp;Gentoo.  I&#8217;ve sent eclass patches to&nbsp;easily integrate it into distutils-r1.  Once they are merged, installing <code>pyproject.toml<\/code> packages should be as&nbsp;simple as&nbsp;adding the&nbsp;following declaration into&nbsp;ebuilds:<\/p>\n<pre><code>DISTUTILS_USE_SETUPTOOLS=pyproject.toml\n<\/code><\/pre>\n<p>This should make things easier both for us (as&nbsp;it saves us from&nbsp;having to&nbsp;hurriedly add new build systems and&nbsp;their NIH dependencies) and&nbsp;for users who will not have to&nbsp;suffer from more circular dependencies in&nbsp;the&nbsp;Python world.  It may also help some upstream projects to&nbsp;maintain backwards compatibility while migrating to&nbsp;new build systems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So far, the&nbsp;majority of&nbsp;Python packages have either used distutils, or&nbsp;a&nbsp;build system built upon it. Most frequently, this was setuptools. All those solutions provided a&nbsp;setup.py script with a&nbsp;semi-standard interface, and&nbsp;we were able to&nbsp;handle them reliably within distutils-r1.eclass. PEP 517 changed that. Instead of&nbsp;a&nbsp;setup script, packages now only need to&nbsp;supply a&nbsp;declarative project information in&nbsp;pyproject.toml file (fun fact: &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2019\/12\/24\/handling-pep-517-pyproject-toml-packages-in-gentoo\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Handling PEP 517 (pyproject.toml) packages in\u00a0Gentoo&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1072"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=1072"}],"version-history":[{"count":15,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1072\/revisions"}],"predecessor-version":[{"id":1087,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/1072\/revisions\/1087"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=1072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=1072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=1072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}