Skip to content

sys.orig_argv is not original, at least on some systems #125006

Open

Description

@pkit

In an OSX .venv the "original" sys.orig_argv is not really original...

(.venv) % cat orig.py
import sys

print(sys.orig_argv)

(.venv) % python orig.py 
['/opt/homebrew/Cellar/[email protected]/3.11.10/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python', 'orig.py']

(.venv) % which python
/Users/user/git/project/.venv/bin/python

I can use os.environ["_"] but it's a workaround.

Activity

  1. vstinner commented on Oct 5, 2024

    @vstinner
    Member

    I cannot reproduce the issue on Linux.

    $ python3 -m venv env
    $ env/bin/python -c 'import sys; print(sys.orig_argv[0])'
    env/bin/python
    
    $ source env/bin/activate
    (env) $ python -c 'import sys; print(sys.orig_argv[0])'
    python
    
    (env) $ which python
    ~/env/bin/python
    (env) $ ls -l env/bin/python
    lrwxrwxrwx 1 vstinner vstinner 7  5 oct.  22:31 env/bin/python -> python3*
    (env) $ ls -l env/bin/python3
    lrwxrwxrwx 1 vstinner vstinner 16  5 oct.  22:31 env/bin/python3 -> /usr/bin/python3*
    

    You can also have a look at:

    (env) vstinner@mona$ python
    >>> import sys
    >>> sys.executable
    '/home/vstinner/env/bin/python'
    >>> sys._base_executable
    '/usr/bin/python3.12'
    
  2. pkit commented on Oct 5, 2024

    @pkit
    Author

    Yup. As I've said it's probably OSX-specific

    This one is inside venv:

    % python -c 'import sys; print(sys.orig_argv[0])'
    /opt/homebrew/Cellar/[email protected]/3.11.10/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python
    
    % python -c 'import sys; print(sys.executable, sys._base_executable)'
    /Users/user/git/project/.venv/bin/python /opt/homebrew/Cellar/[email protected]/3.11.10/Frameworks/Python.framework/Versions/3.11/bin/python3.11
    
  3. pkit commented on Oct 7, 2024

    @pkit
    Author

    sys.executable works well on both Linux and OSX
    So, to correctly re-exec in a cross-platform way:

    os.execve(sys.executable, sys.orig_argv, os.environ.copy())
    
  4. JacobCoffee commented on Oct 10, 2024

    @JacobCoffee
    Member

    here's my side

    Details
    ~ on ☁  (us-east-2)
    ➜ ntp 125006
    Directory /tmp/testing/125006 created and switched to.
    
    /tmp/testing/125006 on ☁  (us-east-2)
    ➜ python3 -m venv venv
    
    /tmp/testing/125006 on ☁  (us-east-2) took 2s
    ➜ env/bin/python -c 'import sys; print(sys.orig_argv[0])'^C
    
    /tmp/testing/125006 on ☁  (us-east-2) took 2s
    ➜ ./venv/bin/python -c 'import sys; print(sys.orig_argv[0])'
    ./venv/bin/python
    
    /tmp/testing/125006 on ☁  (us-east-2)
    ✗ source venv/bin/activate.fish
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ which python
    /private/tmp/testing/125006/venv/bin/python
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ ls -l venv/bin/python
    lrwxr-xr-x@ - coffee 10 Oct 15:59 venv/bin/python -> python3
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ ls -l venv/bin/python3
    lrwxr-xr-x@ - coffee 10 Oct 15:59 venv/bin/python3 -> /Users/coffee/.local/share/mise/installs/python/3.12/bin/python3
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ ./venv/bin/python -c 'import sys; print(sys.orig_argv[0])'
    
    ./venv/bin/python
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ python -c 'import sys; print(sys.executable, sys._base_executable)'
    /private/tmp/testing/125006/venv/bin/python3 /Users/coffee/.local/share/mise/installs/python/3.12/bin/python3.12
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ python -c 'import sys; print(sys.orig_argv[0])'
            python3
    
    /tmp/testing/125006 via  pyenv (venv) on ☁  (us-east-2)
    ➜ python -c 'import sys; print(sys.orig_argv[0])'
    python
    
  5. ronaldoussoren commented on Dec 18, 2025

    @ronaldoussoren
    Contributor

    The difference between macOS framework builds (such as our installer) and other platforms is that sys.executable is a small stub that execv-s the real interpreter that's in an embedded app bundle. Reason for that is that some system APIs, and in particular GUI frameworks, assume they are only used from app bundles.

    It is probably possible to ensure sys.orig_argv[0], but getting this right in all cases including embedding in other applications is non trivial. The current behaviour is also already 5 years old at this time (the PR linked to is from 2025), which means there's a risk that changing behaviour here will break other code...

    IMHO we should change the code here, although adding a note to the documentation about not using sys.executable instead of sys.orig_argv[0] could be helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-mactype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions