What is the purpose of the setuptools requirements of the form "package === version"

Say I have a package with a console console like

from setuptools import setup setup( name='eg_package', version='0.0.1', description='Trivial test package', packages=[ 'eg_package', ], entry_points={ 'console_scripts': [ 'foo = eg_package.main:main', ] }, ) 

If I set it with an explicit string tag using egg_info -b mytag , the resulting script has __requires__ = 'eg-package===0.0.1mytag' , i.e. with 3 "=" signs. This happens when the tag is not something ordinary, like b1 for the beta.

At first, I thought it was a mistake, but the setuptools documentation assumes this is a valid request identifier. However, it does not work with older versions of setuptools, which cause problems with our systems.

My question is what does "===" mean and why does modern setuptools use it?

+5
source share
1 answer

section of the requirements specifier in pip docs links to official documents for requirements specifiers implemented in setuptools pkg_resources . It defines formal syntax, but says nothing about semantics. A document review explains the semantics, but says nothing about the things ~= and === , which obviously were added somewhere between vv.7 (installed with python 2.7.9) and 16.

When the docs don't work, it's time to turn to the sources. Downloading setuptools hg repo and annotating pkg_resources/__init__.py ultimately leads us to changeset 3125 with the message "Implement PEP 440 using the packaging library".

Indeed, PEP 440, the version specifier section, explains the syntax and semantics:

After examining the other files in the commit and its associated packaging , I came to these obvious conclusions:

  • ~= never produced; during processing 1, it acts as a filter in accordance with the rules set forth in PEP.
  • === when processed, the signals return to the older setuptools version syntax and comparison logic. It is created whenever the resulting version string does not match PEP 2 .

1 <sub> In pkg_resources._vendor.packaging.specifiers._compare_compatible() 2 pkg_resources.parse_version() creates a pkg_resources.SetuptoolsLegacyVersion , not pkg_resources.SetuptoolsVersion

+2
source

All Articles