Nâng cấp python trong virtualenv


205

Có cách nào để nâng cấp phiên bản python được sử dụng trong virtualenv (ví dụ: nếu bản phát hành lỗi phát hành) không?

Tôi có thể pip freeze --local > requirements.txt, sau đó loại bỏ thư mục và pip install -r requirements.txt, nhưng điều này đòi hỏi rất nhiều cài đặt lại các thư viện lớn, ví dụ numpy, mà tôi sử dụng rất nhiều.

Tôi có thể thấy đây là một lợi thế khi nâng cấp từ, ví dụ: 2.6 -> 2.7, nhưng còn 2.7.x -> 2.7.y thì sao?


2
Trong khi bạn có thể sửa đổi một số đường dẫn, vv để làm cho nó hoạt động. Điều cuối cùng bạn muốn là một môi trường hơi khác với sản xuất. Chỉ cần nghĩ rằng .. nếu thậm chí có một sự khác biệt giữa cách các phiên bản khác nhau biên dịch, bạn sẽ mất hết thời gian được lưu bằng cách theo dõi lỗi. Tôi chỉ cần dành thời gian để tạo một virtualenv hoàn toàn mới và cài đặt lại mọi thứ.
Sam Dolan

@Simon Walker. Chính xác vấn đề tương tự. Tôi phải nâng cấp python 3.5.3 để sửa lỗi.
Mohammed Shareef C

Câu trả lời:


77

Bạn đã thấy điều này ? Nếu tôi không hiểu nhầm câu trả lời đó, bạn có thể thử tạo một virtualenv mới trên đầu trang cũ. Bạn chỉ cần biết python nào sẽ sử dụng virtualenv của bạn (bạn sẽ cần phải xem phiên bản virtualenv của bạn).

Nếu virtualenv của bạn được cài đặt cùng phiên bản python của phiên bản cũ và nâng cấp gói virtualenv của bạn không phải là một tùy chọn, bạn có thể muốn đọc phần này để cài đặt virtualenv với phiên bản python mà bạn muốn.

BIÊN TẬP

Tôi đã thử nghiệm phương pháp này (phương pháp tạo ra một virtualenv mới trên phương thức cũ) và nó hoạt động tốt với tôi. Tôi nghĩ bạn có thể gặp một số vấn đề nếu bạn thay đổi từ python 2.6 thành 2.7 hoặc 2.7 thành 3.x nhưng nếu bạn chỉ nâng cấp bên trong cùng một phiên bản (ở mức 2.7 như bạn muốn) thì bạn không nên gặp vấn đề gì, vì tất cả các gói được giữ trong cùng một thư mục cho cả hai phiên bản python (các gói 2.7.x và 2.7.y nằm trong your_env / lib / python2.7 /).

Nếu bạn thay đổi phiên bản python ảo của mình, bạn sẽ cần cài đặt lại tất cả các gói của mình cho phiên bản đó (hoặc chỉ liên kết các gói bạn cần vào thư mục gói phiên bản mới, tức là: your_env / lib / python_newversion / site-gói)


13
Anh đặc biệt không muốn cài đặt lại bất kỳ gói nào nếu có thể. Rõ ràng là bạn chưa bao giờ cài đặt numpy từ nguồn nếu bạn không biết tại sao nó lại quan trọng;) gợi ý: phải mất một thời gian LOOOOOOOOOOOOOONG.
Antti Haapala

Vâng, tôi hiểu điều đó. Nhưng có vẻ như nếu anh ta tạo một virtualenv trên các gói khác, các gói không bị mất, vì vậy anh ta sẽ không phải cài đặt lại numpy hoặc bất kỳ gói nào khác. Tuy nhiên, tôi nghĩ anh ta nên thử điều này trong một virtualenv mới trong trường hợp nó thất bại.
marianobianchi

Tôi giải quyết trường hợp của mình, tôi tin rằng các phiên bản virtualenv mới thực sự nâng cấp tại chỗ, tuy nhiên đối với các phiên bản cũ, chúng thậm chí không ghi đè lên tệp thực thi python, gây ra sự cố với ít nhất một bản phát hành lỗi python.
Antti Haapala

4
Nó không hoạt động với tôi và có vẻ như nó không phải là: github.com/pypa/virtualenv/issues/437
Kentzo 20/07/13

1
Tôi đã cố gắng tạo một cái mới virtualenvtrên cái cũ và nó đã hoạt động. Tôi đã phải xác định -pđể chỉ nó vào phiên bản đúng của python.
osa

76

Nếu bạn tình cờ sử dụng mô-đun venv đi kèm với Python 3.3+, nó hỗ trợ một --upgradetùy chọn. Theo các tài liệu :

Nâng cấp thư mục môi trường để sử dụng phiên bản Python này, giả sử Python đã được nâng cấp tại chỗ

python3 -m venv --upgrade ENV_DIR

1
Thật không may, điều này không hoạt động trên Ubuntu 16.04, nơi họ đã phá vỡ venvvà từ chối sửa nó trên cơ sở rằng "bạn chỉ có thể sử dụng virtualenv". EDIT: thực sự, nó hoạt động! Nó cũng chỉ hiển thị một thông báo lỗi về "consturepip".
rspeer

2
Tôi đã nâng cấp python từ 3.5.1 lên 3.6.4 trên hệ thống của mình. Và để nâng cấp python trên virtualenv của tôi, tôi đã phải đề cập rõ ràng đến python3.6 trong lệnh:python3.6 -m venv --upgrade <path_of_existing_env>
Sarfraaz Ahmed

1
Trong trường hợp của tôi, bin/pythonbin/python3vẫn được liên kết với python3.4nhị phân cũ , và tôi phải đặt các liên kết theo cách thủ công. Ngoài ra, có cách nào để loại bỏ phiên bản python đã lỗi thời?
Jens

4
Tôi đã nhận Error: Command '['/Users/me/Sites/site/venv3/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.> nó có nghĩa là gì? Tôi thấy không có quá trình python hoạt động, không thể nâng cấp.
dùng305883

1
@ user305883 Tôi gặp một lỗi tương tự sau khi tôi nâng cấp phiên bản Python hệ thống của mình từ 3.5 lên 3.6 (và đã xóa 3.5). Tôi đã phải cài đặt lại 3.5 và chạy python3.6 -m venv --upgrade ENV_DIRcho nó hoạt động. Tôi nghĩ rằng tôi vẫn sẽ phải cập nhật một số liên kết tượng trưng trong ENV_DIR/bin. Do đó, các trick là để cập nhật với mới phiên bản Python trong khi phiên bản cũ vẫn được cài đặt.
AstroFloyd

24

Cập nhật lại: Phương pháp sau có thể không hoạt động trong các phiên bản mới hơn của virtualenv. Trước khi bạn cố gắng thực hiện sửa đổi cho virtualenv cũ, bạn nên lưu các phụ thuộc trong tệp yêu cầu (pip freeze > requirements.txt) và tạo bản sao lưu của nó ở một nơi khác. Nếu bất cứ điều gì sai, bạn vẫn có thể tạo một virtualenv mới và cài đặt các phụ thuộc cũ trong nó (pip install -r requirements.txt).

Cập nhật: Tôi đã thay đổi câu trả lời 5 tháng sau khi tôi trả lời ban đầu. Phương pháp sau đây thuận tiện và mạnh mẽ hơn.

Tác dụng phụ: nó cũng sửa lỗiSymbol not found: _SSLv2_methodngoại lệ khi bạn thực hiệnimport ssltrong môi trường ảo sau khi nâng cấp Python lên v2.7.8.

Thông báo: Hiện nay, đây là chỉ Python 2.7.x .


Nếu bạn đang sử dụng Homebrew Python trên OS X, trước deactivatehết hãy sử dụng virtualenv, sau đó nâng cấp Python:

brew update && brew upgrade python

Chạy các lệnh sau ( <EXISTING_ENV_PATH>là đường dẫn của môi trường ảo của bạn):

cd <EXISTING_ENV_PATH>
rm .Python
rm bin/pip{,2,2.7}
rm bin/python{,2,2.7}
rm -r include/python2.7
rm lib/python2.7/*
rm -r lib/python2.7/distutils
rm lib/python2.7/site-packages/easy_install.*
rm -r lib/python2.7/site-packages/pip
rm -r lib/python2.7/site-packages/pip-*.dist-info
rm -r lib/python2.7/site-packages/setuptools
rm -r lib/python2.7/site-packages/setuptools-*.dist-info

Cuối cùng, tạo lại môi trường ảo của bạn:

virtualenv <EXISTING_ENV_PATH>

Bằng cách làm như vậy, các tệp lõi Python cũ và các thư viện chuẩn (cộng setuptoolspip) sẽ bị xóa, trong khi các thư viện tùy chỉnh được cài đặt site-packagesđược bảo tồn và hoạt động, ngay khi chúng ở trong Python thuần túy. Thư viện nhị phân có thể hoặc không cần phải được cài đặt lại để hoạt động đúng.

Điều này làm việc cho tôi trên 5 môi trường ảo với Django được cài đặt.

BTW, nếu ./manage.py compilemessageskhông hoạt động sau đó, hãy thử điều này:

brew install gettext && brew link gettext --force

Tệp duy nhất tôi phải xóa là bin/pythontệp.
Koen.

Đối với một số phiên bản Python cũ hơn, việc xóa setuptoolspiplà cần thiết.
Rockallite

1
Tôi cũng đã phải xóa <EXISTING_ENV_PATH>/.Pythonvì điều đó đã phá vỡ việc tạo virtualenv.
Kiran Jonnalagadda

2
Dựa trên câu trả lời này, tôi đã viết một đoạn script nhỏ (có ghi công đầy đủ): burgundywall.com/post/update-all-python-virtual-envirments
Kurt

Bạn thực sự có thể dễ dàng loại bỏ môi trường ảo của mình bằng cách chạy rmvirtualenv <env_name>và sẽ xóa tất cả các phụ thuộc được xếp hàng của nó :) Xem thêm tại: virtualenvwrapper.readthedocs.io/en/latest/iêu
Nick Lucas

7

Tôi không thể tạo một virtualenv mới trên cái cũ. Nhưng có những công cụ trong pip giúp việc cài đặt lại các yêu cầu thành một venv hoàn toàn mới nhanh hơn nhiều. Pip có thể xây dựng từng mục trong tệp.txt của bạn thành gói bánh xe và lưu trữ trong bộ đệm cục bộ. Khi bạn tạo một venv mới và chạy cài đặt pip trong đó, pip sẽ tự động sử dụng các bánh xe dựng sẵn nếu nó tìm thấy chúng. Bánh xe cài đặt nhanh hơn nhiều so với chạy setup.py cho mỗi mô-đun.

Của tôi ~ / .pip / pip.conf trông như thế này:

[global]
download-cache = /Users/me/.pip/download-cache
find-links =
/Users/me/.pip/wheels/

[wheel]
wheel-dir = /Users/me/.pip/wheels

Tôi cài đặt bánh xe ( pip install wheel), sau đó chạy pip wheel -r requirements.txt. Điều này lưu trữ các bánh xe được xây dựng trong bánh xe-dir trong pip.conf của tôi.

Từ đó trở đi, bất cứ khi nào tôi cài đặt bất kỳ yêu cầu nào trong số này, nó sẽ cài đặt chúng từ các bánh xe, khá nhanh chóng.


1
Đối với hầu hết mọi người, tôi nghĩ rằng việc sử dụng máy móc pip để thực hiện công việc có ý nghĩa, nhưng đối với bất kỳ ai đã tùy chỉnh postenivate của họ, kích hoạt trước, v.v., đây không phải là một lựa chọn mong muốn bởi vì tất cả những gì đã mất và phải được thực hiện lại một cách thủ công.
dpwrussell

6

Cách nâng cấp phiên bản Python cho dự án virtualenvwrapper hiện có và giữ nguyên tên

Tôi thêm một câu trả lời cho bất cứ ai sử dụng tuyệt vời Doug Hellmann của virtualenvwrapper đặc biệt kể từ khi câu trả lời hiện không làm điều đó cho tôi.

Một số bối cảnh:

  • Tôi làm việc trên một số dự án là Python 2 và một số dự án là Python 3; Mặc dù tôi rất thích sử dụng python3 -m venvnhưng nó không hỗ trợ môi trường Python 2
  • Khi tôi bắt đầu một dự án mới, tôi sử dụng mkprojectđể tạo môi trường ảo, tạo một thư mục dự án trống và cds vào đó
  • Tôi muốn tiếp tục sử dụng workonlệnh virtualenvwraperser để kích hoạt bất kỳ dự án nào không phân biệt phiên bản Python

Hướng:

Giả sử dự án hiện tại của bạn được đặt tên foovà hiện đang chạy Python 2 ( mkproject -p python2 foo), mặc dù các lệnh giống nhau cho dù nâng cấp từ 2.x lên 3.x, 3.6.0 lên 3.6.1, v.v. Tôi cũng giả sử bạn ' Hiện đang ở trong môi trường ảo được kích hoạt.

1. Hủy kích hoạt và xóa môi trường ảo cũ:

$ deactivate
$ rmvirtualenv foo

Lưu ý rằng nếu bạn đã thêm bất kỳ lệnh tùy chỉnh nào vào hook (ví dụ bin/postactivate:) bạn cần lưu chúng trước khi xóa môi trường.

2. Stash dự án thực trong một thư mục tạm thời:

$ cd ..
$ mv foo foo-tmp

3. Tạo môi trường ảo mới (và thư mục dự án) và kích hoạt:

$ mkproject -p python3 foo

4. Thay thế thư mục dự án được tạo trống bằng dự án thực, thay đổi lại thành thư mục dự án:

$ cd ..
$ mv -f foo-tmp foo
$ cdproject

5. Cài đặt lại phụ thuộc, xác nhận phiên bản Python mới, v.v .:

$ pip install -r requirements.txt
$ python --version

Nếu đây là trường hợp sử dụng phổ biến, tôi sẽ xem xét mở PR để thêm một cái gì đó như $ upgradevirtualenv/ $ upgradeprojectvào virtualenvwrapper.


1
Vâng, làm ơn. Tôi đã đi được nửa đường và gặp vấn đề lớn ... Một kiểm tra sẽ rất hay vì bước đầu tiên là không thể đảo ngược một khi đã bị xóa (theo hiểu biết hiện tại của tôi)
chris Frisina

2

Cách tiếp cận này luôn hiệu quả với tôi:

# First of all, delete all broken links. Replace  my_project_name` to your virtual env name
find ~/.virtualenvs/my_project_name/ -type l -delete
# Then create new links to the current Python version
virtualenv ~/.virtualenvs/my_project_name/
# It's it. Just repeat for each virtualenv located in ~/.virtualenvs

Được lấy từ:


1

Tôi đã chuyển thư mục nhà của mình từ máy mac này sang máy khác (Mountain Lion đến Yosemite) và không nhận ra về chiếc virtualenv bị hỏng cho đến khi tôi mất chiếc laptop cũ. Tôi đã cài đặt điểm ảoen vào Python 2.7 brewvà vì Yosemite đi kèm với Python 2.7, tôi muốn cập nhật virtualenv của mình lên hệ thống python. Khi tôi chạy virtualenvtrên đầu thư mục hiện có, tôi đã gặp OSError: [Errno 17] File exists: '/Users/hdara/bin/python2.7/lib/python2.7/config'lỗi. Bằng cách dùng thử và lỗi, tôi đã khắc phục sự cố này bằng cách xóa một vài liên kết và sửa một vài thủ công. Đây là những gì tôi cuối cùng đã làm (tương tự như những gì @Rockalite đã làm, nhưng đơn giản hơn):

cd <virtualenv-root>
rm lib/python2.7/config
rm lib/python2.7/lib-dynload
rm include/python2.7
rm .Python
cd lib/python2.7
gfind . -type l -xtype l | while read f; do ln -s -f /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/${f#./} $f; done

Sau này, tôi đã có thể chạy virtualenv trên đầu thư mục hiện có.


1

Trên OS X hoặc macOS sử dụng Homebrew để cài đặt và nâng cấp Python3, tôi đã phải xóa các liên kết tượng trưng trước khi python -m venv --upgrade ENV_DIRhoạt động.

Tôi đã lưu các mục sau trong nâng cấp_python3.sh vì vậy tôi sẽ nhớ bao nhiêu tháng kể từ khi tôi cần làm lại:

brew upgrade python3
find ~/.virtualenvs/ -type l -delete
find ~/.virtualenvs/ -type d -mindepth 1 -maxdepth 1 -exec python3 -m venv --upgrade "{}" \;

CẬP NHẬT: mặc dù lúc đầu nó có vẻ hoạt động tốt, nhưng khi tôi chạy py.test thì nó đã báo lỗi. Cuối cùng, tôi chỉ tạo lại môi trường từ một tệp yêu cầu.


py.testkhông hoạt động vì `~ / .virtualenvs / myenv / bin / python3.7 không phải là một liên kết tượng trưng, ​​vì vậy không được cập nhật.
Ash Berlin-Taylor

Ah thực sự, vấn đề là Có ~/.virtualenvs/myenv/.Pythonmột liên kết tượng trưng.
Ash Berlin-Taylor

1

Nếu bạn đang sử dụng pipenv, tôi không biết có thể nâng cấp môi trường tại chỗ không, nhưng ít nhất là đối với các nâng cấp phiên bản nhỏ, có vẻ đủ thông minh để không xây dựng lại các gói từ đầu khi tạo môi trường mới. Ví dụ: từ 3.6.4 đến 3.6.5:

$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv
Creating a v$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv
Creating a virtualenv for this project
Using /usr/local/bin/python3.6m (3.6.5) to create virtualenv
Running virtualenv with interpreter /usr/local/bin/python3.6m
Using base prefix '/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python3.6
Also creating executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python
Installing setuptools, pip, wheel...done.

Virtualenv location: /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD
Installing dependencies from Pipfile.lock (84dd0e)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 47/47  00:00:24
To activate this project's virtualenv, run the following:
 $ pipenv shell
$ pipenv shell
Spawning environment shell (/bin/bash). Use 'exit' to leave.
. /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
bash-3.2$ . /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
(autoscale-aBUhewiD) bash-3.2$ python
Python 3.6.5 (default, Mar 30 2018, 06:41:53) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>>

tuyệt vời! Cảm ơn viên ngọc này
Mayur Patil

1

Tôi chỉ muốn làm rõ, bởi vì một số câu trả lời đề cập đến venvvà những người khác đề cập đến virtualenv.

Sử dụng -phoặc --pythoncờ được hỗ trợ virtualenv, nhưng không bật venv. Nếu bạn có nhiều phiên bản Python và bạn muốn chỉ định phiên bản nào sẽ tạo venvvới, hãy thực hiện trên dòng lệnh, như sau:

malikarumi@Tetuoan2:~/Projects$ python3.6 -m venv {path to pre-existing dir you want venv in}

Tất nhiên bạn có thể nâng cấp với venvnhững gì người khác đã chỉ ra, nhưng điều đó giả định rằng bạn đã nâng cấp Python đã được sử dụng để tạo ra nó venvở nơi đầu tiên. Bạn không thể nâng cấp lên phiên bản Python mà bạn chưa có trên hệ thống của mình ở đâu đó, vì vậy hãy đảm bảo có được phiên bản bạn muốn, trước tiên, sau đó thực hiện tất cả các venv bạn muốn từ nó.


1

Bước 1: Yêu cầu đóng băng & sao lưu env hiện có

pip freeze > requirements.txt
deactivate
mv env env_old

Bước 2: Cài đặt Python 3.7 và kích hoạt môi trường virutal

sudo apt-get install python3.7-venv
python3.7 -m venv env
source env/bin/activate
python --version

Bước 3: Yêu cầu cài đặt

sudo apt-get install python3.7-dev
pip3 install -r requirements.txt

0

Cho mọi người có vấn đề

Lỗi: Lệnh '[' / Người dùng / tôi / Trang web / trang web / venv3 / bin / python3 ',' -Im ',' oblurepip ',' --upup ',' --default-pip ']' được trả về khác không trạng thái thoát 1.

Bạn phải cài đặt python3.6-venv

 sudo apt-get install python3.6-venv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.