Examples and solutions that the Python version specified in pyenv does not run

Introduction

This article is the 19th day article of ZOZO Technologies # 3 Advent Calendar 2020. Yesterday's article was PAC4J: Security library for Play framework and Scala by @BrunoB.

TL;DR

--Confirmed the behavior that Python version is switched when .python-version exists in the same hierarchy as the file path passed in the Python command line argument. --Resolved by deleting .python-version in the same hierarchy as the file path or setting the environment variable PYENV_VERSION

Problem behavior

The first time I felt strange about the behavior was when ModuleNotFoundError was output when executing the python hoge.py -a ./fuga/piyo.txt command. I had confirmed that the library was installed with the pip list command, so I didn't understand why the above command output an error.

A closer look reveals that the version of Python specified by the pyenv local command is not running, the system default Python is running, and the system default Python does not have the above library installed, so ModuleNotFoundError Was occurring. Apparently, the .python-version in the same hierarchy as the ./fuga/piyo.txt passed as a command line argument was read, and the version of Python to be executed was switched.

Reproduction of problematic behavior

Reproduce the behavior of the problem with the following environment, code, and commands.

environment

Use an instance of AWS EC2.

code

The contents of the code print_version.py to be executed this time are as follows. It prints the executed Python version with print (sys.version) regardless of the contents of the argument arg1. The argument arg1 is not used in the main function, but its existence is the key to this time.

print_version.py


import argparse
import sys

def main(arg1):
    print(sys.version)
    return()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--arg1")
    args = parser.parse_args()
    main(args.arg1)

And the directory structure is as follows. There are two directories in the same hierarchy as print_version.py, and their contents are the same except for the presence or absence of .python-version. By the way, .python-version is a hidden file created in the directory where the pyenv local command is executed, so as will be described later, use the pyenv local 3.7.6 command in the pyenv-test directory and with You are running the pyenv local system command in the -pv directory.

pyenv-test
├── .python-version
├── print_version.py
├── with-pv
│   ├── .python-version
│   └── a.txt
└── without-pv
    └── a.txt

pyenv-test/.python-version


3.7.6

pyenv-test/with-pv/.python-version


system

a.txt


abcd

command

First, execute the following command and post the output result.

[ec2-user@******** pyenv-test]$ cd with-pv/

[ec2-user@******** with-pv]$ pyenv local system

[ec2-user@******** with-pv]$ python -V
Python 2.7.18

[ec2-user@******** with-pv]$ cd ../

[ec2-user@******** pyenv-test]$ pyenv local 3.7.6

[ec2-user@******** pyenv-test]$ python -V
Python 3.7.6

Continue to execute the following command and post the output result. Again, print_version.py is just code that prints the version of Python that was executed.

[ec2-user@******** pyenv-test]$ python print_version.py -a ./without-pv/a.txt
3.7.6 (default, Dec  8 2020, 06:20:44)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]

[ec2-user@******** pyenv-test]$ python print_version.py -a ./with-pv/a.txt
2.7.18 (default, Aug 27 2020, 21:22:52)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]

You should have passed a file with the same contents as an argument to print_version.py, but ** the versions of Python executed are different. ** ** Those who passed ./with-pv/a.txt as command line arguments ran Python 2.7.18, which should not have been specified in pyenv. The difference between the two commands is that the version of Python described in .python-version has priority and is executed depending on whether .python-version exists in the same hierarchy as the file path passed as a command line argument. It is believed that it has been done.

By the way, I tried the same thing with Click because it may be due to the behavior of argparse, but the result was the same.

solution

There are the following two methods.

1: Set the environment variable PYENV_VERSION

When pyenv decides which version of Python to run, the environment variable PYENV_VERSION has the highest priority (reference: pyenv's home repository). You can set the environment variable by executing the export PYENV_VERSION = 3.7.6 command or by executing the pyenv shell 3.7.6 command, and the following is executed.

python


[ec2-user@******** pyenv-test]$ pyenv shell 3.7.6

[ec2-user@******** pyenv-test]$ python print_version.py -a ./without-pv/a.txt
3.7.6 (default, Dec  8 2020, 06:20:44)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]

[ec2-user@******** pyenv-test]$ python print_version.py -a ./with-pv/a.txt
3.7.6 (default, Dec  8 2020, 06:20:44)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-9)]

2: Delete .python-version

As confirmed in the Command section, if the argument does not have .python-version in the same hierarchy as the file, it will be executed with the Python version specified by the pyenv local command.

Consideration

According to pyenv's home repository, .python-version, which exists in the same hierarchy as the file specified by the command line argument, is expected to have no effect on the Python version being executed. However, it did not behave as expected, so it seems necessary to understand the specifications in more detail.

in conclusion

This article summarizes what I was addicted to when using pyenv. At the time of ModuleNotFoundError, I was completely unaware that the Python version was switched, and for a long time I suspected that the pyenv installation failed, and it took a long time to resolve. Furthermore, although this article omits the case where there are two or more command line arguments, the code I was writing at that time had four command line arguments. This is also one of the personnel who took a long time to resolve, but I managed to identify the cause.

Tomorrow will be an article by @ Horie1024. look forward to tomorrow too!

Recommended Posts

Examples and solutions that the Python version specified in pyenv does not run
What to do if Python does not switch from the System version in pyenv
About the problem that the python version of Google App Engine does not mesh
Key input that does not wait for key input in Python
Check when the version does not switch with pyenv
Python version does not switch
The story that `while queue` did not work in python
[Tips] Problems and solutions in the development of python + kivy
A story that pyenv is stuck because the python execution command PATH does not pass
The story that the version of python 3.7.7 was not adapted to Heroku
New Python grammar and features not mentioned in the introductory book
The story that 2D list replacement did not work in python
Change the active version in Pyenv from anaconda to plain Python
python> does not include the letters mm> if "mm" not in text: / print "not including mm"
Run the Python interpreter in a script
The module that should have been installed with pip does not run
Python> Python does not include the last offset
[Python] Read the specified line in the file
Intuitive explanation that does not rely on mathematical formulas for the Monty Hall problem and simulation with Python
A solution to the problem that the Python version in Conda cannot be changed
I compared the speed of regular expressions in Ruby, Python, and Perl (2013 version)
Divides the character string by the specified number of characters. In Ruby and Python.
[Question] Python string replacement.replace () will replace even the ones that are not specified.
Until you run the changefinder sample in python
About the difference between "==" and "is" in python
[Mac] Run the RealSense D415 sample in Python
The one that displays the progress bar in Python
About the matter that the contents of Python print are not visible in docker logs
Solved the problem that MacVim installed by Homebrew was not built by python of pyenv
A note that runs an external program in Python and parses the resulting line
A solution to the problem that files containing [and] are not listed in glob.glob ()
"Linear regression" and "Probabilistic version of linear regression" in Python "Bayesian linear regression"
The simplest Python memo in Japan (classes and objects)
[Python] Boolean operator (or / and) does not return Boolean value
Receive the form in Python and do various things
Carefully understand the exponential distribution and draw in Python
Logical symbols learned in marriage (and implementation examples in Python)
Plot and understand the multivariate normal distribution in Python
Find the part that is 575 from Wikipedia in Python
Carefully understand the Poisson distribution and draw in Python
Not being aware of the contents of the data in python
Find the Hermitian matrix and its eigenvalues in Python
PHP and Python samples that hit the ChatWork API
Install the latest stable Python with pyenv (both 2 and 3)
Modules that may go through the shell in Python
Install pyenv on Raspberry Pi and version control Python
The story that yapf did not work in vscode
What does the last () in a function mean in Python?
[Internal_math version (2)] Decoding the AtCoder Library ~ Implementation in Python ~
[C / C ++] Pass the value calculated in C / C ++ to a python function to execute the process, and use that value in C / C ++.
Jedi-vim shortcut command that allows you to refer to the definition source and definition destination in Python
About the matter that nosetests does not pass when __init__.py is created in the project directory
[Python] Programming to find the number of a in a character string that repeats a specified number of times.
Python version switching (pyenv)
Test.py is not reflected on the web server in Python3.
[Python] Open the csv file in the folder specified by pandas
[Python] Reason why index error does not occur in slice
Get and create nodes added and updated in the new version
Get the MIME type in Python and determine the file format
Sort and output the elements in the list as elements and multiples in Python.
Grep so that grep does not appear at the time of grep