pipenv icon indicating copy to clipboard operation
pipenv copied to clipboard

Pipfile seems to default to 3.9, while `pyenv global` is set to 3.11

Open startakovsky opened this issue 2 years ago • 10 comments

Based on this code and upon further inspection, I wouldn't expect to default to 3.9 because I did the following as I had no python global version except 3.11 set:

  1. pyenv global 3.11
  2. pip install --user pipx (installed to 3.11)
  3. pipx install pipenv
➜  lab3 ls
➜  lab3 pyenv global
3.11
➜  lab3 pipx list
venvs are in /Users/steven/.local/pipx/venvs
apps are exposed on your $PATH at /Users/steven/.local/bin
   package pipenv 2023.6.2, installed using Python 3.11.3
    - pipenv
    - pipenv-resolver
➜  lab3 pipenv shell
Creating a Pipfile for this project...
Launching subshell in virtual environment...
 . /Users/steven/.local/share/virtualenvs/lab3-HokYbGH3/bin/activate
Reverting to nvm default version
Now using node v18.16.0 (npm v9.5.1)
➜  lab3  . /Users/steven/.local/share/virtualenvs/lab3-HokYbGH3/bin/activate
(lab3) ➜  lab3 cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.9"
(lab3) ➜  lab3

startakovsky avatar Jun 08 '23 22:06 startakovsky

Another artifact:

➜  code pipx list
venvs are in /Users/steven/.local/pipx/venvs
apps are exposed on your $PATH at /Users/steven/.local/bin
   package pipenv 2023.6.2, installed using Python 3.11.3
    - pipenv
    - pipenv-resolver
➜  code cat ~/.local/pipx/venvs/pipenv/pipx_metadata.json
{
    "injected_packages": {},
    "main_package": {
        "app_paths": [
            {
                "__Path__": "/Users/steven/.local/pipx/venvs/pipenv/bin/pipenv",
                "__type__": "Path"
            },
            {
                "__Path__": "/Users/steven/.local/pipx/venvs/pipenv/bin/pipenv-resolver",
                "__type__": "Path"
            }
        ],
        "app_paths_of_dependencies": {
            "virtualenv": [
                {
                    "__Path__": "/Users/steven/.local/pipx/venvs/pipenv/bin/virtualenv",
                    "__type__": "Path"
                }
            ],
            "virtualenv-clone": [
                {
                    "__Path__": "/Users/steven/.local/pipx/venvs/pipenv/bin/virtualenv-clone",
                    "__type__": "Path"
                }
            ]
        },
        "apps": [
            "pipenv",
            "pipenv-resolver"
        ],
        "apps_of_dependencies": [
            "virtualenv-clone",
            "virtualenv"
        ],
        "include_apps": true,
        "include_dependencies": false,
        "package": "pipenv",
        "package_or_url": "pipenv",
        "package_version": "2023.6.2",
        "pip_args": [],
        "suffix": ""
    },
    "pipx_metadata_version": "0.2",
    "python_version": "Python 3.11.3",
    "venv_args": []

startakovsky avatar Jun 08 '23 22:06 startakovsky

Here's one more, with this one, I removed all python versions of the form 3.9.x. Now it defaults to 3.10. Why is it not defaulting to $(pyenv global)?

... pyenv: 3.9.16 uninstalled
➜ pyenv global
3.11
➜  code mkdir lab4
➜  code pyenv versions | grep 3.9
➜  code cd lab4
➜  lab4 pipenv shell
Creating a virtualenv for this project...
Pipfile: /Users/steven/code/lab4/Pipfile
Using default python from /Users/steven/.local/pipx/venvs/pipenv/bin/python (3.11.3) to create virtualenv...
⠙ Creating virtual environment...created virtual environment CPython3.11.3.final.0-64 in 156ms
  creator CPython3Posix(dest=/Users/steven/.local/share/virtualenvs/lab4-1hdpgw6W, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/steven/Library/Application Support/virtualenv)
    added seed packages: pip==23.1.2, setuptools==67.7.2, wheel==0.40.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /Users/steven/.local/share/virtualenvs/lab4-1hdpgw6W
Creating a Pipfile for this project...
Launching subshell in virtual environment...
 . /Users/steven/.local/share/virtualenvs/lab4-1hdpgw6W/bin/activate
Reverting to nvm default version
Now using node v18.16.0 (npm v9.5.1)
➜  lab4  . /Users/steven/.local/share/virtualenvs/lab4-1hdpgw6W/bin/activate
(lab4) ➜  lab4 cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.10"
(lab4) ➜  lab4```

startakovsky avatar Jun 08 '23 22:06 startakovsky

I realize I may have changed some default behavior in pythonfinder when moving to 2.x but I am not sure that it was ever documented that if pyenv was installed with a global default that it should prefer that over a system python without a --python specifier. Even if it were documented, why should it prefer pyenv over asdf when both are supported?

I apologize for any inconveniences, but I'd expect if 3.9 is your system default that would be used unless a specifier like --python=3.11 were passed in which case pyenv or asdf is invoked to find/install/find the specified version. This definitely wasn't intentional in my refactor but I also didn't notice where it was somehow preferring or respecting the global pyenv value by default. I am definitely open to suggestions and proposed follow-up PRs on how to best handle this scenario.

matteius avatar Jun 09 '23 02:06 matteius

Thanks @matteius I guess there's nothing critical here, and it is not at an inconvenience, just that the docstring was not reflective of what was happening, and that I cannot rely on the system default (which is 3.11).

More on this: I don't think my mac came installed with any version of python. I first installed XCode, then Homebrew, then pyenv. From there I installed several versions of python and had set pyenv global 3.11 to be my default.

Thank you for all your contributions to this package, it's really awesome and so much better than relying on pyenv virtualenv like I have been over the years.

startakovsky avatar Jun 09 '23 05:06 startakovsky

@startakovsky Could you point me to the docstring you mean? -- I'd like to understand better if this was documented somewhere.

matteius avatar Jun 11 '23 03:06 matteius

There is a function that creates the pipfile, which creates the version. In this function there is a line defining the Python version and dependencies, seen here:

version = python_version(required_python) or self.s.PIPENV_DEFAULT_PYTHON_VERSION

This line depends upon the value of s.PIPENV_DEFAULT_PYTHON_VERSION, which is defined here:

# Tells Pipenv which Python to default to, when none is provided.
self.PIPENV_DEFAULT_PYTHON_VERSION = get_from_env(
    "DEFAULT_PYTHON_VERSION", check_for_negation=False
)
"""Use this Python version when creating new virtual environments by default.


This can be set to a version string, e.g. ``3.9``, or a path. Default is to use
whatever Python Pipenv is installed under (i.e. ``sys.executable``). Command
line flags (e.g. ``--python``) are prioritized over
this configuration.
"""

startakovsky avatar Jun 11 '23 06:06 startakovsky

Those doc strings refer to setting an environment variable that would be the default specifier to pass to python when initiating a new environment. The rest of the doc string refers to the sys path and system executable, which would be what is provided first on your system path. I think what your thinking is more of a feature request that was proposed a while back: https://github.com/pypa/pipenv/issues/3855

matteius avatar Jun 15 '23 00:06 matteius

@matteius Yes, it does seem similar, but the main difference is that I don't think I have any python executables on my machine that have been installed by anything other than pyenv. No matter, I have moved on now and in my mind the --python will just be required (probably good anyway so as not to leave it to chance). Thanks for taking time with my request.

startakovsky avatar Jun 15 '23 19:06 startakovsky

If your Pipfile specifies a version of Python, it will use that version if it can locate it or install it if pyenv is installed. If it does not, which is an option, it will use the default version of Python that is in the current PATH. In the interaction between pipenv and pyenv, it is the former's configuration that is used. However, you can use pyenv activate to put yourself in a virtual environment where Python 3.11 is the default. Alternatively you can add Python 3.11 to your PATH.

kalebmckale avatar Aug 16 '23 02:08 kalebmckale

One additional note: pyenv doesn't install the default system version of Python. Its functionality at the core is a series of shell script files called shims. Inside the activated pyenv environment, you will find your global-set version though. You will find the same behavior with other tools that work with pyenv, e.g. tox.

kalebmckale avatar Aug 16 '23 02:08 kalebmckale