Skip to content

Prefer "python" over "python3" for command line examples in docs. #98763

Description

@felixxm

Documentation

Currently docs are not consistent in using python vs. python3 for command line examples. As far as I'm aware, we should prefer python, see https://peps.python.org/pep-0394/#for-end-users-of-python

Linked PRs

Activity

  1. added a commit that references this issue on Oct 27, 2022
  2. AlexWaygood commented on Oct 27, 2022

    @AlexWaygood
    Member

    I agree it would be nice to be more consistent here.

    Here's the results of `git grep "$ python"` in the `Doc/` directory:
    extending/newtypes_tutorial.rst:   $ python setup.py build
    howto/logging-cookbook.rst:    ~/logging-contextual-webapp$ python main.py
    howto/logging-cookbook.rst:    $ python logctx.py
    howto/logging-cookbook.rst:    $ python logctx.py 2>/dev/null
    howto/logging-cookbook.rst:    $ python logctx.py >/dev/null
    howto/logging-cookbook.rst:    $ python app.py start foo
    howto/logging-cookbook.rst:    $ python app.py stop foo bar
    howto/logging-cookbook.rst:    $ python app.py restart foo bar baz
    howto/logging-cookbook.rst:    $ python app.py --log-level DEBUG start foo
    howto/logging-cookbook.rst:    $ python app.py --log-level DEBUG stop foo bar
    howto/logging-cookbook.rst:    $ python app.py --log-level DEBUG restart foo bar baz
    howto/logging-cookbook.rst:    $ python app.py --log-level WARNING start foo
    howto/logging-cookbook.rst:    $ python app.py --log-level WARNING stop foo bar
    howto/logging-cookbook.rst:    $ python app.py --log-level WARNING restart foo bar baz
    howto/logging.rst:    $ python simple_logging_module.py
    howto/logging.rst:    $ python simple_logging_config.py
    howto/perf_profiling.rst:    $ python -Xperf my_script.py
    howto/perf_profiling.rst:    $ python -m sysconfig | grep 'no-omit-frame-pointer'
    howto/unicode.rst:   $ python listdir-test.py
    library/argparse.rst:   $ python prog.py -h
    library/argparse.rst:   $ python prog.py 1 2 3 4
    library/argparse.rst:   $ python prog.py 1 2 3 4 --sum
    library/argparse.rst:   $ python prog.py a b c
    library/argparse.rst:   $ python myprogram.py --help
    library/argparse.rst:   $ python subdir/myprogram.py --help
    library/argparse.rst:   $ python myprogram.py --help
    library/doctest.rst:   $ python example.py
    library/doctest.rst:   $ python example.py -v
    library/importlib.metadata.rst:    (example) $ python -m pip install wheel
    library/json.rst:      $ python -m json.tool mp_films.json
    library/pickletools.rst:    $ python -m pickle x.pickle
    library/pickletools.rst:    $ python -m pickletools x.pickle
    library/shutil.rst:    $ python -m tarfile -l /Users/tarek/myarchive.tar
    library/socketserver.rst:   $ python TCPServer.py
    library/socketserver.rst:   $ python TCPClient.py hello world with TCP
    library/socketserver.rst:   $ python TCPClient.py python is nice
    library/socketserver.rst:   $ python ThreadedTCPServer.py
    library/sysconfig.rst:    $ python -m sysconfig
    library/tarfile.rst:    $ python -m tarfile -c monty.tar  spam.txt eggs.txt
    library/tarfile.rst:    $ python -m tarfile -c monty.tar life-of-brian_1979/
    library/tarfile.rst:    $ python -m tarfile -e monty.tar
    library/tarfile.rst:    $ python -m tarfile -e monty.tar  other-dir/
    library/tarfile.rst:    $ python -m tarfile -l monty.tar
    library/timeit.rst:   $ python -m timeit -s 'text = "sample string"; char = "g"'  'char in text'
    library/timeit.rst:   $ python -m timeit -s 'text = "sample string"; char = "g"'  'text.find(char)'
    library/timeit.rst:   $ python -m timeit 'try:' '  str.__bool__' 'except AttributeError:' '  pass'
    library/timeit.rst:   $ python -m timeit 'if hasattr(str, "__bool__"): pass'
    library/timeit.rst:   $ python -m timeit 'try:' '  int.__bool__' 'except AttributeError:' '  pass'
    library/timeit.rst:   $ python -m timeit 'if hasattr(int, "__bool__"): pass'
    library/tokenize.rst:    $ python -m tokenize hello.py
    library/tokenize.rst:    $ python -m tokenize -e hello.py
    library/zipapp.rst:   $ python -m zipapp myapp -m "myapp:main"
    library/zipapp.rst:   $ python myapp.pyz
    library/zipapp.rst:   $ python -m zipapp source [options]
    library/zipapp.rst:   $ python -m zipapp myapp
    library/zipapp.rst:   $ python myapp.pyz
    library/zipapp.rst:   $ python -m zipapp myapp -p "/usr/bin/env python"
    library/zipapp.rst:      $ python -m pip install -r requirements.txt --target myapp
    library/zipapp.rst:      $ python -m zipapp -p "interpreter" myapp
    library/zipfile.rst:    $ python -m zipfile -c monty.zip spam.txt eggs.txt
    library/zipfile.rst:    $ python -m zipfile -c monty.zip life-of-brian_1979/
    library/zipfile.rst:    $ python -m zipfile -e monty.zip target-dir/
    library/zipfile.rst:    $ python -m zipfile -l monty.zip
    tutorial/modules.rst:   $ python fibo.py 50
    tutorial/venv.rst:  (tutorial-env) $ python -m pip install novas
    tutorial/venv.rst:  (tutorial-env) $ python -m pip install requests==2.6.0
    tutorial/venv.rst:  (tutorial-env) $ python -m pip install --upgrade requests
    tutorial/venv.rst:  (tutorial-env) $ python -m pip show requests
    tutorial/venv.rst:  (tutorial-env) $ python -m pip list
    tutorial/venv.rst:  (tutorial-env) $ python -m pip freeze > requirements.txt
    tutorial/venv.rst:  (tutorial-env) $ python -m pip install -r requirements.txt
    whatsnew/3.2.rst:    $ python -q
    whatsnew/3.2.rst:      $ python -q -Wdefault
    whatsnew/3.2.rst:    $ python -m unittest discover -s my_proj_dir -p _test.py
    whatsnew/3.2.rst:    $ python -m site --user-base
    whatsnew/3.2.rst:    $ python -m site --user-site
    whatsnew/3.2.rst:    $ python -m turtledemo
    whatsnew/3.3.rst:    $ python -q -X faulthandler
    whatsnew/3.5.rst:    $ python -m zipapp myapp
    whatsnew/3.5.rst:    $ python myapp.pyz
    whatsnew/3.8.rst:    $ python -m asyncio
    
    Here's the results of `git grep "$ python3"` in the `Doc/` directory:
    howto/argparse.rst:   $ python3 prog.py
    howto/argparse.rst:   $ python3 prog.py --help
    howto/argparse.rst:   $ python3 prog.py --verbose
    howto/argparse.rst:   $ python3 prog.py foo
    howto/argparse.rst:   $ python3 prog.py
    howto/argparse.rst:   $ python3 prog.py --help
    howto/argparse.rst:   $ python3 prog.py foo
    howto/argparse.rst:   $ python3 prog.py -h
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py four
    howto/argparse.rst:   $ python3 prog.py --verbosity 1
    howto/argparse.rst:   $ python3 prog.py
    howto/argparse.rst:   $ python3 prog.py --help
    howto/argparse.rst:   $ python3 prog.py --verbosity
    howto/argparse.rst:   $ python3 prog.py --verbose
    howto/argparse.rst:   $ python3 prog.py --verbose 1
    howto/argparse.rst:   $ python3 prog.py --help
    howto/argparse.rst:   $ python3 prog.py -v
    howto/argparse.rst:   $ python3 prog.py --help
    howto/argparse.rst:   $ python3 prog.py
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py 4 --verbose
    howto/argparse.rst:   $ python3 prog.py --verbose 4
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py 4 -v
    howto/argparse.rst:   $ python3 prog.py 4 -v 1
    howto/argparse.rst:   $ python3 prog.py 4 -v 2
    howto/argparse.rst:   $ python3 prog.py 4 -v 3
    howto/argparse.rst:   $ python3 prog.py 4 -v 3
    howto/argparse.rst:   $ python3 prog.py 4 -h
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py 4 -v
    howto/argparse.rst:   $ python3 prog.py 4 -vv
    howto/argparse.rst:   $ python3 prog.py 4 --verbosity --verbosity
    howto/argparse.rst:   $ python3 prog.py 4 -v 1
    howto/argparse.rst:   $ python3 prog.py 4 -h
    howto/argparse.rst:   $ python3 prog.py 4 -vvv
    howto/argparse.rst:   $ python3 prog.py 4 -vvv
    howto/argparse.rst:   $ python3 prog.py 4 -vvvv
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py 4
    howto/argparse.rst:   $ python3 prog.py
    howto/argparse.rst:   $ python3 prog.py -h
    howto/argparse.rst:   $ python3 prog.py 4 2 -v
    howto/argparse.rst:   $ python3 prog.py 4 2
    howto/argparse.rst:   $ python3 prog.py 4 2 -v
    howto/argparse.rst:   $ python3 prog.py 4 2 -vv
    howto/argparse.rst:   $ python3 prog.py 4 2
    howto/argparse.rst:   $ python3 prog.py 4 2 -q
    howto/argparse.rst:   $ python3 prog.py 4 2 -v
    howto/argparse.rst:   $ python3 prog.py 4 2 -vq
    howto/argparse.rst:   $ python3 prog.py 4 2 -v --quiet
    howto/argparse.rst:   $ python3 prog.py --help
    howto/clinic.rst:    $ python3 Tools/clinic/clinic.py foo.c
    howto/unicode.rst:    $ python3 compare-strs.py
    library/__main__.rst:       $ python3 helloworld.py
    library/__main__.rst:       $ python3 -m tarfile
    library/__main__.rst:       $ python3 -c "import this"
    library/__main__.rst:   $ python3 -m bandclass
    library/__main__.rst:   $ python3 start.py
    library/__main__.rst:   $ python3 start.py
    library/devmode.rst:    $ python3 script.py README.txt
    library/devmode.rst:    $ python3 -X dev script.py README.txt
    library/devmode.rst:    $ python3 -X dev -X tracemalloc=5 script.py README.rst
    library/devmode.rst:    $ python3 script.py
    library/devmode.rst:    $ python3 script.py
    library/faulthandler.rst:    $ python3 -c "import ctypes; ctypes.string_at(0)"
    library/faulthandler.rst:    $ python3 -q -X faulthandler
    library/importlib.metadata.rst:    $ python3 -m venv example
    library/site.rst:   $ python3 -m site --user-site
    library/timeit.rst:   $ python3 -m timeit '"-".join(str(n) for n in range(100))'
    library/timeit.rst:   $ python3 -m timeit '"-".join([str(n) for n in range(100)])'
    library/timeit.rst:   $ python3 -m timeit '"-".join(map(str, range(100)))'
    

    In particular, it's pretty strange that the argparse reference doc uses python very consistently, while the argparse HOWTO uses python3 very consistently.

  3. sc68cal commented on Nov 20, 2022

    @sc68cal

    Homebrew still installs and links python as python3. Ubuntu 20.04 LTS (at least via Windows Subsystem for Linux) does not have a python binary, but instead has python3. So, I think the issue is that until the OS distros start consistently installing python3.x interpreters as python in $PATH, we will have this issue. I think this means maybe everything needs to be explicitly python3 until that happens? Until we then have to change it back?

    The referenced PEP says

    The python command should always invoke Python 2 (to prevent hard-to-diagnose errors when Python 2 code is run on Python 3).

    Which argues that it should be python3 - although that's not to say things haven't changed since the PEP was written.

  4. AlexWaygood commented on Nov 20, 2022

    @AlexWaygood
    Member

    I'm removing the "easy" label since we already have a PR here, it just needs to be reviewed :)

  5. added a commit that references this issue on Jan 3, 2023
  6. added a commit that references this issue on Jan 11, 2023
  7. added a commit that references this issue on Jan 11, 2023
  8. hugovk commented on Jan 12, 2023

    @hugovk
    Member

    See issue #100972 and PR #100973 for more.

  9. rhettinger commented on Jan 14, 2023

    @rhettinger
    Contributor

    On my Mac, python no longer refers to an executable. Only python3 works. So, at least for Mac Users, the status quo is better. With the proposed substitutions, the examples won't work any more.

  10. AlexWaygood commented on Jan 14, 2023

    @AlexWaygood
    Member

    On my Mac, python no longer refers to an executable. Only python3 works. So, at least for Mac Users, the status quo is better. With the proposed substitutions, the examples won't work any more.

    On my Windows machine, only python works. python3 takes me to a page on the Windows Store inviting me to download Python (I obviously have it downloaded, but downloaded it from python.org instead of the Windows Store).

    I think it's unlikely that there's anything that works for everybody, sadly.

  11. carljm commented on Mar 14, 2023

    @carljm
    Member

    The ideal future is that python works for everyone. I think it's just a question of how long we have to wait for Python 2 to sink into irrelevancy, before we can update PEP 394 to clearly recommend that redistributors should make python be Python 3, and also do things like #102358

    In the meantime, we seem to be in a situation where there is no form we can use in the docs that will reliably work for all users, and I have no idea how we should handle that. It seems unlikely that "continue indefinitely to be randomly inconsistent depending who happened to write which docs" is the best option, though.

  12. carljm commented on Mar 14, 2023

    @carljm
    Member

    FWIW, #102354 is a bug recently filed by a Windows user about the doc examples using python3 not working for them. When I asked other core devs about this, I was pointed to #98761, which seemed to establish a clear consensus that we should prefer python over python3. I didn't see that there had been further discussion here. So I just merged #102696 which converts the last few python3 to python. So the status quo is now that we consistently use python. But we can leave this issue open to discuss how else we might want to handle it.

  13. felixxm commented on Mar 14, 2023

    @felixxm
    ContributorAuthor

    In the meantime, we seem to be in a situation where there is no form we can use in the docs that will reliably work for all users, ..

    Unfortunately, that's true.

    For me, this recommendation from PEP 394 is the most important:

    While far from being universally available, python remains the preferred spelling for explicitly invoking Python, as this is the spelling that virtual environments make consistently available across different platforms and Python installations.

    So for example in Django docs, we assume that command lines examples are run in virtual environments.

  14. carljm commented on Mar 14, 2023

    @carljm
    Member

    this is the spelling that virtual environments make consistently available

    Which makes a lot of sense, but doesn't help resolve the question of which spelling the venv docs themselves should use :) Though I think at that point, "just be consistent with the rest of the docs" is a reasonable argument.

  15. erlend-aasland commented on Jun 19, 2023

    @erlend-aasland
    Contributor

    The linked PR was merged. It seems to me we can close this. Please re-open if you feel more work is needed.

  16. added a commit that references this issue on Sep 8, 2023
  17. added a commit that references this issue on Sep 13, 2023
  18. added a commit that references this issue on Sep 26, 2023
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

    docsDocumentation in the Doc dir

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions