Jason R. Coombs <jar...@jaraco.com> added the comment:

My bad. I probably could have been more proactive about providing a reproducer. 
The problem, as described above (msg335220) and in the associated cmdix ticket, 
is that invocation of `platform.(anything)` causes shelling out to execute 
"uname", so it's not possible to implement uname on Python unless one can 
guarantee that `platform.(anything)` is not invoked prior to the Python uname 
implementation executing.

Here's a Dockerfile replicating the issue:

```
FROM ubuntu:focal

# Install Python
RUN apt update
RUN apt install -y python3
RUN ln -s /usr/bin/python3 /usr/bin/python

# Simulate something on the system that invokes platform early.
RUN printf 'print(__import__("platform").system())' > sitecustomize.py
ENV PYTHONPATH=/

# Create a stubbed 'uname' command build in Python
ENV PATH=/:$PATH
RUN printf '#!/usr/bin/env python\nprint("getting ready to patch platform", 
flush=True)' > uname
RUN chmod u+x uname

CMD uname
```

As you can see, this reproducer creates a _very_ simple 'uname' implementation. 
All it does is print that it's about to patch the platform module (because 
maybe that will make things work). Unfortunately, that behavior is never 
reached because before that code has a chance to run, `sitecustomize` is 
imported and calls `platform.system()`, which invokes `platform.uname()` which 
attempts to resolve the processor, which attempts to invoke `uname -p` (even on 
Windows), which invokes the stubbed uname command, and infinite recursion 
begins.

The `sitecustomize` might seem a little contrived, except that a very similar 
behavior occurs in a very typical environment:

- pip, when installing a package for editing, invokes setuptools to `develop` 
the package.
- setuptools, when installing a package for developing, creates command-line 
entry points using a routine that imports `pkg_resources` to ensure that the 
relevant packages are present before invoking the command's functionality.
- pkg_resources imports packaging to evaluate markers.
- packaging uses `platform.system()` and other behaviors to evaluate the 
markers.

So ultimately, the same behavior is triggered before the user's code is ever 
executed.

But more importantly, why should "uname -p" be invoked in a subprocess on 
Windows to get "platform.system()"?

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue35967>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to