Re: Python version dependencies in pkg

From: Stefan Esser <>
Date: Thu, 29 Sep 2022 21:21:09 UTC
Am 29.09.22 um 21:52 schrieb Dan Mahoney:>> On Sep 28, 2022, at 23:39, 
Alexander Leidinger <> wrote:
>> Quoting Rainer Hurling <> (from Thu, 29 Sep 2022 06:43:49 +0200):
>>> Hi Dan,
>>> Am 28.09.22 um 23:01 schrieb Dan Mahoney:
>>>>> On Sep 26, 2022, at 20:22, Kevin Oberman < <>> wrote:
>>>>> On Mon, Sep 26, 2022, 18:13 Dan Mahoney < <>> wrote:
>>>> Okay, so in either the package file, or the repo file, is there a bit that says "whatever is the default" or that explicitly says "if there's not a python, install 3.8"?
>>> There is PYTHON_DEFAULT (set to 3.9 ATM) in ports/Mk/ You can override this for example by an entry in /etc/make.conf:
>>> DEFAULT_VERSIONS+= python=3.10 python3=3.10
> That's ports.  I'm asking about packages.

Packages are built based on consistent defaults, e.g. currently for Python-3.9.

If you need a different Python version, you can easily build your own packages
for a different set of defaults.

The package system does not and cannot provide the version independence you
are asking for, since dependent packages could be built with different options
for changed defaults.

> I'm asking on ports@ because there's not any kind of pkgs@ mailing list.  I feel like I'm not being clear as to why.

Yes, and its a legitimate question - but the simple answer is that the
official packages constitute a set with complex interdependencies between
its members.

>> To extend a little bit on that:
>> "pkg info | grep py3" will give you a list of ports which are depending on a specific python version. If it lists py37-xxx it means the xxx port depends upon python 3.7. If you then delete python 3.7 pkg will also ask you if it is ok to delete all the py37-* ports.
> No, it will give me a list of *packages*, except it won't.
> Case in point: bind-tools (which in turn is a dependency of bind9)
> # pkg info | grep bind-tools
> bind-tools-9.16.27_1           Command line tools from BIND: delv, dig, host, nslookup...
> # pkg all-depends bind-tools
> libxml2-2.9.13_1
> python38-3.8.13
> libidn2-2.3.2
> py38-ply-3.11
> libuv-1.42.0
> libedit-3.1.20210910,1
> json-c-0.15_1
> #

This command will show packages together with the Python version they
depend on:

pkg query "%dn %n-%v" | grep -E "^python3[0-9]+ "

> The latest version of bind-tools no longer requires python at all (bind 9.18 has rewritten all the utilities in C once again), so I can't just experiment with this.

Yes, and the following command shows this information, too:

pkg rquery "%dn %n-%v" bind-tools | grep -E "^python3[0-9]+ "

> But trying to do a pkg delete python3.8 attempted to delete bind-tools, and I was looking for the magic incantation that says "without reinstalling bind-tools, how can I re-point it at the python39 variants of that package".  On a box without a ports tree.  Only using pkg.

As you say, bind-tools does no longer depend on Python and therefore is
not a good example.

But you can use the above command to query the python dependency for any
pre-built package.

And no, you cannot "re-point" a package. "Re-pointing" is done by building
the package with different default versions, and you can do it yourself,
if the official version do not match your requirements.

> If the answer is "you really can't unless you run poudriere and tell it to build a different package with a different dependent version of python", then so be it.  But I'd like to be able to install py39-ply, and python39, and have bind-tools not try to deinstall, and instead just re-point itself.  Now, I know this is not the same as a library that can build linked against two ssl's where there are real compile-time/link-time differences.  This is because one particular file in bind-tools is a python script.

The port/package system cannot distinguish cases of multiple packages that
could be used as substitutes for each other. There is no simple algorithmic
way to identify packages that could be exchanged with each other. It might
be possible to manually annotate packages in such a way (e.g. if any version
of Python-3.x would do with the matching set of Python modules), but this
would require a lot of effort for little value.

> If the answer is "some dumb ports will always depend on whatever the default version was on the build farm, so you MUST have those versions installed" that's an answer.

Yes, that's *the* answer ...

> I know ports support "flavors" but there's no py38-bind-tools, which led me to believe there was a looser coupling.

Only a small subset of supported flavors is built by the built servers.
But bind-tools is no longer a good example ...

> My secondary question: when a pkg is nailed to the "Default" version, does that result in the pkg file itself actually saying 3.8, or just a reference that says "the default was used, but any python will do, but you have to manually edit the pkgdb to update the dependencies".

There are search paths in the Python interpreters, some of which include
the Python version. In many cases you could move a python module into the
search path of a different interpreter version, but there is no guarantee,
that this would lead to a working combination of interpreter and module.
You could manipulate the pkgdb to reflect such a change in the installed
files, but that leads into madness ...

> If I had manually installed py39-ply and python3.9, would bind-tools have still required python3.8 and py38-ply?

If you install the bind-tools package (and assuming it still depended on
Python), then the exact version recorded at the time the bind-tools package
was built will be required.

>> So for a given system with already installed ports it is not simply installing python 3.9 and deleting 3.7. It is also updating all the ports which depend upon 3.7.


> Again, that's ports.  My question the whole time has been "how does this knob, specifed in the ports tree, ultimately translate into the pkg tree", where there is no ports tree present and make.conf is not consulted.
> I am asking about either fields in the pkg file itself, or in the pkg database.

You can display all the information in the pkgdb with "pkg query" for installed
and "pkg rquery" for available packages.

- STefan