python-build-standalone icon indicating copy to clipboard operation
python-build-standalone copied to clipboard

Detecting whether a Python was built by `python-build-standalone`

Open charliermarsh opened this issue 1 year ago • 9 comments

Due to #380, I'm looking for a way to detect whether a given Python interpreter was built by python-build-standalone. Is there any reliable metadata (maybe something on sysconfig.get_config_vars()) to support this?

charliermarsh avatar Oct 24 '24 15:10 charliermarsh

For example, this is a candidate though could obviously cause problems (false negatives or false positives):

>>> sysconfig.get_config_vars()['prefix']
'/install'

But if there's some kind of dedicated flag or metadata, it would of course be preferable.

charliermarsh avatar Oct 24 '24 15:10 charliermarsh

There shouldn't be false negatives from the sysconfig prefix variable, unless of course, the build process changes. I'm not opposed to setting something specific to reflect that it's a python-build-standalone build. I'm not sure where the correct place for that is. Probably something in sysconfig still?

zanieb avatar Oct 24 '24 15:10 zanieb

(I just meant false negatives in the event that the value differed at some previous point in the python-build-standalone history -- but I didn't verify whether that's true.)

charliermarsh avatar Oct 24 '24 15:10 charliermarsh

For what it's worth, I think there are good reasons not to have this exposed. It does enable clients to special-case python-build-standalone which ideally they shouldn't have to do.

charliermarsh avatar Oct 24 '24 15:10 charliermarsh

The standalone distributions do need to be special cased though, i.e., sysconfig is known to be broken and installers (or other consumers) need to understand that and adjust their behavior accordingly — there's no clear path towards fixing these values at build time.

zanieb avatar Oct 24 '24 15:10 zanieb

Analogy to a web browser...

Issue is asking to use User-Agent detection.

Seasoned web developers will tell you to sniff for features/bugs and not use the UA string as a proxy.

For the same reason you shouldn't use UA strings, we shouldn't key off an "is PBS" flag.

But it could be nice to know a Python is PBS.

If someone wants to footgun themselves keying functionality off that flag, so be it.

Perhaps we could add the PBS advertisement in the Python --version output? I think there's a configure flag to add supplemental text here. It's analogous to a UA string and feels like the right place to put it.

indygreg avatar Oct 24 '24 15:10 indygreg

@indygreg -- Can you think of anything we might use for the existing releases? :)

charliermarsh avatar Oct 24 '24 17:10 charliermarsh

For existing releases, the /install or /build references are probably the best we have. And those are prone to false positives.

It makes sense to expose something more explicit going forward.

Something in the version metadata (I think there's a vendor string or something) and maybe a new sysconfig define if a vendor string can't be easily read/parsed at runtime.

indygreg avatar Oct 24 '24 23:10 indygreg

(In uv, we now mark this in sysconfig after we unzip.)

charliermarsh avatar Dec 18 '24 00:12 charliermarsh

Is this possible? Trying to temporarily work around https://github.com/astral-sh/python-build-standalone/issues/707 in my test suite🤔

gaborbernat avatar Jul 21 '25 01:07 gaborbernat

In uv we use https://github.com/astral-sh/uv/blob/c25c800367a5f43069f1c9d778cfd5de1bcc54a6/crates/uv-python/python/get_interpreter_info.py#L639-L645

However, we patch that install time https://github.com/astral-sh/uv/blob/3bb8ac610ca5690fce0eea9da792dbe6eecaad05/crates/uv-python/src/sysconfig/mod.rs#L206

We should insert that into sysconfig in this repository.

zanieb avatar Jul 23 '25 00:07 zanieb

The use cases mentioned so far have all been for (mis)feature detection to work around bugs that will be fixed, so I agree with @indygreg's analysis :)

For the virtualenv case - I would recommend looking at, say, otool -l on the Python binary, and if there's an LC_LOAD_DYLIB command pointing to a path starting with @executable_path, then you either need to copy that target or do some rewriting of the load command with e.g. install_name_tool. And this isn't a python-build-standalone thing specifically: not doing this is a bug in virtualenv and upstream venv when operating against any relocatable Python build with dynamic dependencies.

There's a ping from a few days ago for broken Tk, which was now fixed. They ended up switching to misfeature detection instead, which is an argument that not advertising an easy switch gets people to do the right thing.

I do want to identify ourselves in version output, but I worry about this.... I would almost prefer to have a discoverable list of known, long-standing bugs/quirks so you can stop working around them when the quirk is resolved.

geofft avatar Aug 08 '25 18:08 geofft