venv --- ایجاد محیطهای مجازی¶
اضافه شده در نسخهی 3.3.
کد منبع: Lib/venv/
ماژول venv از ایجاد «محیطهای مجازی» سبک پشتیبانی میکند؛ هرکدام دارای مجموعهای مستقل از بستههای پایتون نصبشده در پوشههای site خود است. یک محیط مجازی بر روی یک نصب موجود پایتون ایجاد میشود، که بهعنوان پایتون «پایه» محیط مجازی شناخته میشود، و بهطور پیشفرض از بستههای محیط پایه جدا است، تا فقط بستههایی که بهصراحت در محیط مجازی نصب شدهاند در دسترس باشند. برای اطلاعات بیشتر، محیطهای مجازی و مستندات محیطهای مجازی ماژول site را ببینید.
هنگام استفاده از داخل یک محیط مجازی، ابزارهای نصب رایج مانند pip بستههای پایتون را بدون نیاز به دستور صریح، در محیط مجازی نصب میکنند.
یک محیط مجازی (از جمله موارد دیگر):
برای دربرگرفتن یک مفسر پایتون خاص و کتابخانهها و دودوییهای نرمافزاری که برای پشتیبانی از یک پروژه (کتابخانه یا برنامه کاربردی) لازم هستند، استفاده میشود. اینها بهطور پیشفرض از نرمافزارهای موجود در سایر محیطهای مجازی و مفسرهای پایتون و کتابخانههای نصبشده در سیستمعامل جدا هستند.
در یک پوشه قرار دارد، که بهطور قراردادی
.venvیاvenvنام دارد و در پوشهی پروژه یا زیر یک پوشهی حاوی تعداد زیادی از محیطهای مجازی قرار میگیرد، مانند~/.virtualenvs.در سیستمهای کنترل منبع مانند Git ثبت نشده است.
بهعنوان یکبارمصرف در نظر گرفته میشود — باید حذف و ایجاد مجدد آن از صفر ساده باشد. شما هیچ کد پروژهای را در محیط قرار نمیدهید.
بهعنوان قابلجابهجایی یا قابلکپی در نظر گرفته نمیشود -- شما فقط همان محیط را در مکان مقصد بازایجاد میکنید.
برای پیشزمینه بیشتر در مورد محیطهای مجازی پایتون، PEP 405 را ببینید.
همچنین ملاحظه نمائید
راهنمای کاربر بستهبندی پایتون: ایجاد و استفاده از محیطهای مجازی
دسترسپذیری: not Android, not iOS, not WASI.
این ماژول در سکوهای موبایل یا سکوهای WebAssembly پشتیبانی نمیشود.
ایجاد محیطهای مجازی¶
محیطهای مجازی با اجرای ماژول venv ایجاد میشوند:
python -m venv /path/to/new/virtual/environment
این کار پوشه هدف (شامل پوشههای والد، در صورت نیاز) را ایجاد میکند و یک پرونده pyvenv.cfg را با یک کلید home در آن قرار میدهد، کلیدی که به نصب پایتونی که دستور از آن اجرا شده است اشاره میکند. همچنین یک زیرپوشه bin (یا Scripts در ویندوز) ایجاد میکند که شامل یک کپی یا پیوند نمادین از پرونده اجرایی پایتون است (متناسب با سکو یا آرگومانهای استفادهشده در زمان ایجاد محیط). همچنین یک زیرپوشه lib/pythonX.Y/site-packages ایجاد میکند (در ویندوز، این زیرپوشه Lib\site-packages است). اگر یک پوشه موجود مشخص شود، دوباره از آن استفاده خواهد شد.
تغییر یافته در نسخهی 3.5: استفاده از venv اکنون برای ایجاد محیطهای مجازی توصیه میشود.
منسوخ شده از نسخهی 3.6، در نسخهی 3.8 حذف شده است: pyvenv ابزار توصیهشده برای ایجاد محیطهای مجازی برای پایتون 3.3 و 3.4 بود، و در 3.5 با اجرای مستقیم venv جایگزین شد.
در ویندوز، فرمان venv را بهصورت زیر اجرا کنید:
PS> python -m venv C:\path\to\new\virtual\environment
این فرمان، اگر با -h اجرا شود، گزینههای موجود را نمایش خواهد داد:
usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
[--upgrade] [--without-pip] [--prompt PROMPT] [--upgrade-deps]
[--without-scm-ignore-files]
ENV_DIR [ENV_DIR ...]
محیطهای مجازی پایتون را در یک یا چند پوشه هدف ایجاد میکند.
پس از ایجاد یک محیط، ممکن است بخواهید آن را فعال کنید، برای مثال با source کردن یک اسکریپت activate در پوشه bin آن.
- ENV_DIR¶
یک آرگومان ضروری برای مشخص کردن پوشهای که محیط در آن ایجاد میشود.
- --system-site-packages¶
به محیط مجازی دسترسی به پوشهی site-packages سیستم را بدهید.
- --symlinks¶
سعی کنید به جای کپیها از پیوندهای نمادین استفاده کنید، هنگامی که پیوندهای نمادین برای پلتفرم پیشفرض نیستند.
- --copies¶
سعی کنید بهجای پیوندهای نمادین از رونوشتها استفاده کنید، حتی زمانی که پیوندهای نمادین پیشفرض سکو هستند.
- --clear¶
اگر پوشهی محیط از قبل وجود دارد، پیش از ایجاد محیط، محتویات آن را حذف کنید.
- --upgrade¶
با فرض اینکه پایتون بهصورت درجا ارتقا یافته باشد، پوشهی محیط را ارتقا دهید تا از این نسخه از پایتون استفاده کند.
- --without-pip¶
از نصب یا بهروزرسانی pip در محیط مجازی صرفنظر میکند (pip بهصورت پیشفرض بوتاسترپ میشود).
- --prompt <PROMPT>¶
پیشوند اعلان جایگزینی برای این محیط فراهم میکند.
- --upgrade-deps¶
وابستگیهای اصلی (pip) را به آخرین نسخه در PyPI ارتقا دهید.
- --without-scm-ignore-files¶
از افزودن پروندههای ignore SCM به پوشه محیط صرفنظر میکند (Git بهطور پیشفرض پشتیبانی میشود).
تغییر یافته در نسخهی 3.4: pip را بهطور پیشفرض نصب میکند و گزینههای --without-pip و --copies را اضافه میکند.
تغییر یافته در نسخهی 3.4: در نسخههای پیشین، اگر پوشه هدف از قبل وجود داشت، خطایی پرتاب میشد، مگر اینکه گزینه --clear یا --upgrade ارائه شده باشد.
تغییر یافته در نسخهی 3.9: افزودن گزینه --upgrade-deps برای ارتقاء pip + setuptools به آخرین نسخه در PyPI.
تغییر یافته در نسخهی 3.12: setuptools دیگر یک وابستگی اصلی venv نیست.
تغییر یافته در نسخهی 3.13: گزینه --without-scm-ignore-files افزوده شد.
تغییر یافته در نسخهی 3.13: venv اکنون بهطور پیشفرض یک پرونده .gitignore برای Git ایجاد میکند.
توجه
اگرچه پیوندهای نمادیندر ویندوز پشتیبانی میشوند، اما استفاده از آنها توصیه نمیشود. بهویژه توجه داشته باشید که دوبار کلیک کردن روی python.exe در File Explorer، پیوند نمادین را بلافاصله حل میکند و محیط مجازی را نادیده میگیرد.
توجه
در Microsoft Windows، ممکن است لازم باشد اسکریپت Activate.ps1 را با تنظیم خطمشی اجرا (execution policy) برای کاربر فعال کنید. میتوانید این کار را با صدور دستور PowerShell زیر انجام دهید:
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
برای اطلاعات بیشتر، درباره سیاستهای اجرا را ببینید.
پرونده pyvenv.cfg ایجادشده همچنین شامل کلید include-system-site-packages است، که اگر venv با گزینهی --system-site-packages اجرا شود، به true تنظیم میشود؛ در غیر این صورت به false تنظیم میشود.
مگر اینکه گزینه --without-pip داده شده باشد، ensurepip برای بوتاسترپ (bootstrap) pip در محیط مجازی فراخوانی میشود.
میتوان چند مسیر به venv داد؛ در این صورت، یک محیط مجازی یکسان بر اساس گزینههای دادهشده در هر مسیر ارائهشده ایجاد خواهد شد.
نحوه کار venvها¶
هنگامی که یک مفسر پایتون از یک محیط مجازی اجرا میشود، sys.prefix و sys.exec_prefix به پوشههای محیط مجازی اشاره میکنند، در حالی که sys.base_prefix و sys.base_exec_prefix به پوشههای پایتون پایهای که برای ایجاد محیط استفاده شده است اشاره میکنند. برای تشخیص اینکه مفسر فعلی از یک محیط مجازی اجرا میشود، بررسی sys.prefix != sys.base_prefix کافی است.
یک محیط مجازی میتواند با استفاده از اسکریپتی در پوشه دودویی خود (bin در POSIX؛ Scripts در Windows) «فعال» شود. این کار آن پوشه را به ابتدای PATH شما اضافه میکند، بهطوری که اجرای python مفسر پایتون آن محیط را فراخوانی میکند و شما میتوانید اسکریپتهای نصبشده را بدون نیاز به استفاده از مسیر کامل آنها اجرا کنید. فراخوانی اسکریپت فعالسازی وابسته به پلتفرم است (<venv> باید با مسیر پوشهای که محیط مجازی را شامل میشود جایگزین شود):
سکو |
پوسته |
دستور فعالسازی محیط مجازی |
|---|---|---|
POSIX |
bash/zsh |
|
ماهی |
|
|
csh/tcsh |
|
|
pwsh |
|
|
ویندوز |
cmd.exe |
|
PowerShell |
|
اضافه شده در نسخهی 3.4: اسکریپتهای فعالسازی fish و csh.
اضافه شده در نسخهی 3.8: اسکریپتهای فعالسازی PowerShell نصبشده تحت POSIX برای پشتیبانی از PowerShell Core.
شما لزوماً نیاز ندارید یک محیط مجازی را فعال کنید، زیرا میتوانید صرفاً مسیر کامل مفسر پایتون آن محیط را هنگام فراخوانی پایتون مشخص کنید. علاوه بر این، تمام اسکریپتهای نصبشده در محیط باید بدون فعالسازی آن قابل اجرا باشند.
برای دستیابی به این هدف، اسکریپتهای نصبشده در محیطهای مجازی دارای یک خط «shebang» هستند که به مفسر پایتون محیط اشاره میکند، #!/<path-to-venv>/bin/python. این بدان معناست که اسکریپت صرفنظر از مقدار PATH با آن مفسر اجرا میشود. در ویندوز، پردازش خط «shebang» در صورتی پشتیبانی میشود که مدیر نصب پایتون را نصب کرده باشید. بنابراین، دوبار کلیک روی یک اسکریپت نصبشده در یک پنجرهی Windows Explorer باید آن را با مفسر صحیح اجرا کند، بدون نیاز به فعالسازی محیط یا قرار داشتن آن در PATH.
هنگامی که یک محیط مجازی فعال شده باشد، متغیر محیطی VIRTUAL_ENV روی مسیر آن محیط تنظیم میشود. از آنجا که برای استفاده از یک محیط مجازی نیازی به فعالسازی صریح آن نیست، نمیتوان برای تعیین اینکه آیا یک محیط مجازی در حال استفاده است، به VIRTUAL_ENV اتکا کرد.
هشدار
از آنجا که اسکریپتهای نصبشده در محیطها نباید انتظار داشته باشند که محیط فعال شده باشد، سطرهای shebang آنها حاوی مسیرهای مطلق به مفسرهای محیط خود هستند. به همین دلیل، محیطها در حالت کلی ذاتاً غیرقابلانتقال هستند. شما همیشه باید راهی ساده برای بازسازی یک محیط داشته باشید (برای مثال، اگر یک پرونده نیازمندیها با نام requirements.txt دارید، میتوانید با استفاده از pip همان محیط، دستور pip install -r requirements.txt را اجرا کنید تا تمام بستههای موردنیاز محیط نصب شوند). اگر به هر دلیلی نیاز دارید محیط را به مکان جدیدی منتقل کنید، باید آن را در مکان دلخواه بازسازی کنید و محیط موجود در مکان قدیمی را حذف کنید. اگر محیطی را به این دلیل جابهجا میکنید که پوشه والد آن را جابهجا کردهاید، باید محیط را در مکان جدید آن بازسازی کنید. در غیر این صورت، ممکن است نرمافزار نصبشده در محیط آنطور که انتظار میرود کار نکند.
شما میتوانید با تایپ deactivate در پوسته، یک محیط مجازی را غیرفعال کنید. سازوکار دقیق آن به سکو بستگی دارد و جزئیاتی از پیادهسازی داخلی است (معمولاً از یک اسکریپت یا تابع پوسته استفاده میشود).
API¶
متد سطح بالایی که در بالا توضیح داده شد، از یک API ساده استفاده میکند که سازوکارهایی را برای سازندگان محیطهای مجازی شخص ثالث فراهم میکند تا ایجاد محیط را مطابق نیازهای خود سفارشیسازی کنند: کلاس EnvBuilder.
- class venv.EnvBuilder(system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())¶
کلاس
EnvBuilderدر هنگام نمونهسازی، آرگومانهای کلیدواژهای زیر را میپذیرد:system_site_packages -- یک مقدار بولی که نشان میدهد site-packages پایتون سیستم باید برای محیط در دسترس باشد (پیشفرض
Falseاست).clear -- یک مقدار بولی که اگر درست باشد، محتوای هر پوشه هدف موجود را پیش از ایجاد محیط حذف میکند.
symlinks -- یک مقدار بولی که نشان میدهد آیا باید بهجای کپی کردن، برای ایجاد پیوند نمادیندودویی Python تلاش شود یا خیر.
upgrade -- یک مقدار بولی که اگر true باشد، محیط موجود را با پایتون در حال اجرا ارتقا میدهد - برای استفاده زمانی که آن پایتون بهصورت درجا (in-place) ارتقا یافته است (پیشفرض
False).with_pip -- یک مقدار بولی که اگر true باشد، تضمین میکند pip در محیط مجازی نصب شده باشد. این کار از
ensurepipبا گزینهی--default-pipاستفاده میکند.prompt -- رشتهای که پس از فعالسازی محیط مجازی استفاده میشود (پیشفرض آن
Noneاست، یعنی از نام پوشهی محیط استفاده میشود). اگر رشتهی خاص"."ارائه شود، نام پایه (basename) پوشهی جاری بهعنوان prompt استفاده میشود.upgrade_deps -- بهروزرسانی ماژولهای پایه venv به آخرین نسخههای موجود در PyPI
scm_ignore_files -- برای مدیران کنترل منبع (SCM) مشخصشده در پیمایشپذیر، پروندههای نادیدهگرفتن (ignore files) ایجاد میکند. پشتیبانی با داشتن متدی به نام
create_{scm}_ignore_fileتعریف میشود. تنها مقدار پشتیبانیشده بهصورت پیشفرض"git"از طریقcreate_git_ignore_file()است.
تغییر یافته در نسخهی 3.4: پارامتر
with_pipافزوده شدتغییر یافته در نسخهی 3.6: پارامتر
promptاضافه شدتغییر یافته در نسخهی 3.9: پارامتر
upgrade_depsاضافه شدتغییر یافته در نسخهی 3.13: پارامتر
scm_ignore_filesافزوده شدمیتوان از
EnvBuilderبهعنوان کلاس پایه استفاده کرد.- create(env_dir)¶
با مشخص کردن پوشه هدف (بهصورت مطلق یا نسبی به پوشه فعلی) که باید حاوی محیط مجازی باشد، یک محیط مجازی ایجاد کنید. متد
createیا محیط را در پوشه مشخصشده ایجاد میکند، یا استثنای مناسبی را پرتاب میکند.متد
createکلاسEnvBuilderقلابهای در دسترس (hooks) برای سفارشیسازی در زیرکلاسها را نشان میدهد:def create(self, env_dir): """ یک محیط پایتون مجازیسازیشده را در یک پوشه ایجاد میکند. env_dir پوشه هدف برای ایجاد یک محیط است. """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) self.create_configuration(context) self.setup_python(context) self.setup_scripts(context) self.post_setup(context)
هر یک از متدهای
ensure_directories()،create_configuration()،setup_python()،setup_scripts()وpost_setup()را میتوان بازنویسی کرد.
- ensure_directories(env_dir)¶
پوشهی محیط و تمام زیرپوشههای ضروری را که از قبل وجود ندارند، ایجاد میکند و یک شیء زمینه را برمیگرداند. این شیء زمینه فقط نگهدارندهای برای ویژگیها (مانند مسیرها) برای استفاده توسط سایر متدها است. اگر
EnvBuilderبا آرگومانclear=Trueایجاد شود، محتویات پوشهی محیط پاک خواهد شد و سپس تمام زیرپوشههای ضروری دوباره ایجاد خواهند شد.شیء زمینهی برگرداندهشده یک
types.SimpleNamespaceبا ویژگیهای زیر است:env_dir- محل محیط مجازی. برای__VENV_DIR__در اسکریپتهای فعالسازی به کار میرود (بهinstall_scripts()مراجعه کنید).env_name- نام محیط مجازی. برای__VENV_NAME__در اسکریپتهای فعالسازی استفاده میشود (بهinstall_scripts()مراجعه کنید).prompt- اعلانی که توسط اسکریپتهای فعالسازی استفاده میشود. برای__VENV_PROMPT__در اسکریپتهای فعالسازی استفاده میشود (بهinstall_scripts()مراجعه کنید).executable- پرونده اجرایی پایتونِ زیربنایی که محیط مجازی از آن استفاده میکند. این، حالتی را در نظر میگیرد که در آن یک محیط مجازی از یک محیط مجازی دیگر ایجاد شده باشد.inc_path- مسیر include (include path) برای محیط مجازی.lib_path- مسیر purelib برای محیط مجازی.bin_path- مسیر اسکریپت برای محیط مجازی.bin_name- نام مسیر اسکریپت نسبت به محل محیط مجازی. برای__VENV_BIN_NAME__در اسکریپتهای فعالسازی استفاده میشود (بهinstall_scripts()مراجعه کنید).env_exe- نام مفسر پایتون در محیط مجازی. برای__VENV_PYTHON__در اسکریپتهای فعالسازی استفاده میشود (بهinstall_scripts()مراجعه کنید).env_exec_cmd- نام مفسر پایتون، با در نظر گرفتن تغییر مسیرهای سامانه فایلبندی. میتوان از آن برای اجرای پایتون در محیط مجازی استفاده کرد.
تغییر یافته در نسخهی 3.11: از طرحواره نصب sysconfig مربوط به venv برای ساخت مسیرهای پوشههای ایجادشده استفاده میشود.
تغییر یافته در نسخهی 3.12: ویژگی
lib_pathبه زمینه افزوده شد و شیء زمینه مستند شد.
- create_configuration(context)¶
پرونده پیکربندی
pyvenv.cfgرا در محیط ایجاد میکند.
- setup_python(context)¶
یک رونوشت یا پیوند نمادین به پرونده اجرایی پایتون را در محیط ایجاد میکند. در سیستمهای POSIX، اگر از یک پرونده اجرایی مشخص
python3.xاستفاده شده باشد، پیوندهای نمادینpythonوpython3ایجاد میشوند که به آن پرونده اجرایی اشاره میکنند، مگر اینکه پروندههایی با آن نامها از قبل وجود داشته باشند.
- setup_scripts(context)¶
اسکریپتهای فعالسازی متناسب با پلتفرم را در محیط مجازی نصب میکند.
- upgrade_dependencies(context)¶
بستههای وابستگی اصلی venv (در حال حاضر pip) را در محیط ارتقا میدهد. این کار با فراخوانی پرونده اجرایی
pipدر محیط از طریق پوسته انجام میشود.اضافه شده در نسخهی 3.9.
تغییر یافته در نسخهی 3.12: setuptools دیگر یک وابستگی اصلی برای venv نیست.
- post_setup(context)¶
یک متد جاینگهدار که میتوان آن را در پیادهسازیهای شخص ثالث بازنویسی کرد تا بستهها را از پیش در محیط مجازی نصب کند یا سایر مراحل پس از ایجاد را انجام دهد.
- install_scripts(context, path)¶
این متد را میتوان از
setup_scripts()یاpost_setup()در زیرکلاسها فراخوانی کرد تا به نصب اسکریپتهای سفارشی در محیط مجازی کمک کند.path مسیر پوشهای است که باید شامل زیرپوشههای
common،posixوntباشد؛ هر یک حاوی اسکریپتهایی که برای پوشهیbinدر محیط در نظر گرفته شدهاند. محتویاتcommonو پوشهی متناظر باos.nameپس از انجام برخی جایگزینیهای متنی برای جاینگهدارها کپی میشوند:__VENV_DIR__با مسیر مطلق پوشهی محیط جایگزین میشود.__VENV_NAME__با نام محیط جایگزین میشود (آخرین بخش مسیر پوشهی محیط).__VENV_PROMPT__با اعلان (prompt) جایگزین میشود (نام محیط داخل پرانتز بههمراه یک فاصله پس از آن)__VENV_BIN_NAME__با نام پوشهی bin (یاbinیاScripts) جایگزین میشود.__VENV_PYTHON__با مسیر مطلق پرونده اجرایی محیط جایگزین میشود.
وجود پوشهها مجاز است (برای زمانی که یک محیط موجود در حال ارتقا است).
- create_git_ignore_file(context)¶
یک پرونده
.gitignoreدرون محیط مجازی ایجاد میکند که باعث میشود کل پوشه توسط مدیر کنترل منبع Git نادیده گرفته شود.اضافه شده در نسخهی 3.13.
تغییر یافته در نسخهی 3.7.2: ویندوز اکنون بهجای کپی کردن دودوییهای واقعی، برای
python[w].exeاز اسکریپتهای تغییرمسیردهنده استفاده میکند. فقط در 3.7.2،setup_python()هیچ کاری انجام نمیدهد، مگر اینکه از یک ساخت در درخت منبع (source tree) اجرا شود.تغییر یافته در نسخهی 3.7.3: ویندوز اسکریپتهای تغییرمسیردهنده (redirector) را بهعنوان بخشی از
setup_python()کپی میکند، نه بهعنوان بخشی ازsetup_scripts(). این موضوع در 3.7.2 اینگونه نبود. هنگام استفاده از پیوندهای نمادین، پروندههای اجرایی اصلی پیوند داده خواهند شد.
همچنین یک تابع کمکی در سطح ماژول وجود دارد:
- venv.create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, *, scm_ignore_files=frozenset())¶
یک
EnvBuilderبا آرگومانهای کلیدواژهای دادهشده ایجاد کنید و متدcreate()آن را با آرگومان env_dir فراخوانی کنید.اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.4: پارامتر with_pip اضافه شد
تغییر یافته در نسخهی 3.6: پارامتر prompt اضافه شد
تغییر یافته در نسخهی 3.9: پارامتر upgrade_deps افزوده شد
تغییر یافته در نسخهی 3.13: پارامتر scm_ignore_files افزوده شد
مثالی از گسترش EnvBuilder¶
اسکریپت زیر نشان میدهد که چگونه میتوان EnvBuilder را با پیادهسازی زیرکلاسی که setuptools و pip را در یک محیط مجازی ایجادشده نصب میکند، گسترش داد:
import os
import os.path
from subprocess import Popen, PIPE
import sys
from threading import Thread
from urllib.parse import urlsplit
from urllib.request import urlretrieve
import venv
class ExtendedEnvBuilder(venv.EnvBuilder):
"""
This builder installs setuptools and pip so that you can pip or
easy_install other packages into the created virtual environment.
:param nodist: If true, setuptools and pip are not installed into the
created virtual environment.
:param nopip: If true, pip is not installed into the created
virtual environment.
:param progress: If setuptools or pip are installed, the progress of the
installation can be monitored by passing a progress
callable. If specified, it is called with two
arguments: a string indicating some progress, and a
context indicating where the string is coming from.
The context argument can have one of three values:
'main', indicating that it is called from virtualize()
itself, and 'stdout' and 'stderr', which are obtained
by reading lines from the output streams of a subprocess
which is used to install the app.
If a callable is not specified, default progress
information is output to sys.stderr.
"""
def __init__(self, *args, **kwargs):
self.nodist = kwargs.pop('nodist', False)
self.nopip = kwargs.pop('nopip', False)
self.progress = kwargs.pop('progress', None)
self.verbose = kwargs.pop('verbose', False)
super().__init__(*args, **kwargs)
def post_setup(self, context):
"""
Set up any packages which need to be pre-installed into the
virtual environment being created.
:param context: The information for the virtual environment
creation request being processed.
"""
os.environ['VIRTUAL_ENV'] = context.env_dir
if not self.nodist:
self.install_setuptools(context)
# Can't install pip without setuptools
if not self.nopip and not self.nodist:
self.install_pip(context)
def reader(self, stream, context):
"""
Read lines from a subprocess' output stream and either pass to a progress
callable (if specified) or write progress information to sys.stderr.
"""
progress = self.progress
while True:
s = stream.readline()
if not s:
break
if progress is not None:
progress(s, context)
else:
if not self.verbose:
sys.stderr.write('.')
else:
sys.stderr.write(s.decode('utf-8'))
sys.stderr.flush()
stream.close()
def install_script(self, context, name, url):
_, _, path, _, _ = urlsplit(url)
fn = os.path.split(path)[-1]
binpath = context.bin_path
distpath = os.path.join(binpath, fn)
# Download script into the virtual environment's binaries folder
urlretrieve(url, distpath)
progress = self.progress
if self.verbose:
term = '\n'
else:
term = ''
if progress is not None:
progress('Installing %s ...%s' % (name, term), 'main')
else:
sys.stderr.write('Installing %s ...%s' % (name, term))
sys.stderr.flush()
# Install in the virtual environment
args = [context.env_exe, fn]
p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
t1.start()
t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
t2.start()
p.wait()
t1.join()
t2.join()
if progress is not None:
progress('done.', 'main')
else:
sys.stderr.write('done.\n')
# Clean up - no longer needed
os.unlink(distpath)
def install_setuptools(self, context):
"""
Install setuptools in the virtual environment.
:param context: The information for the virtual environment
creation request being processed.
"""
url = "https://bootstrap.pypa.io/ez_setup.py"
self.install_script(context, 'setuptools', url)
# clear up the setuptools archive which gets downloaded
pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
files = filter(pred, os.listdir(context.bin_path))
for f in files:
f = os.path.join(context.bin_path, f)
os.unlink(f)
def install_pip(self, context):
"""
Install pip in the virtual environment.
:param context: The information for the virtual environment
creation request being processed.
"""
url = 'https://bootstrap.pypa.io/get-pip.py'
self.install_script(context, 'pip', url)
def main(args=None):
import argparse
parser = argparse.ArgumentParser(prog=__name__,
description='Creates virtual Python '
'environments in one or '
'more target '
'directories.')
parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
help='A directory in which to create the '
'virtual environment.')
parser.add_argument('--no-setuptools', default=False,
action='store_true', dest='nodist',
help="Don't install setuptools or pip in the "
"virtual environment.")
parser.add_argument('--no-pip', default=False,
action='store_true', dest='nopip',
help="Don't install pip in the virtual "
"environment.")
parser.add_argument('--system-site-packages', default=False,
action='store_true', dest='system_site',
help='Give the virtual environment access to the '
'system site-packages dir.')
if os.name == 'nt':
use_symlinks = False
else:
use_symlinks = True
parser.add_argument('--symlinks', default=use_symlinks,
action='store_true', dest='symlinks',
help='Try to use symlinks rather than copies, '
'when symlinks are not the default for '
'the platform.')
parser.add_argument('--clear', default=False, action='store_true',
dest='clear', help='Delete the contents of the '
'virtual environment '
'directory if it already '
'exists, before virtual '
'environment creation.')
parser.add_argument('--upgrade', default=False, action='store_true',
dest='upgrade', help='Upgrade the virtual '
'environment directory to '
'use this version of '
'Python, assuming Python '
'has been upgraded '
'in-place.')
parser.add_argument('--verbose', default=False, action='store_true',
dest='verbose', help='Display the output '
'from the scripts which '
'install setuptools and pip.')
options = parser.parse_args(args)
if options.upgrade and options.clear:
raise ValueError('you cannot supply --upgrade and --clear together.')
builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
clear=options.clear,
symlinks=options.symlinks,
upgrade=options.upgrade,
nodist=options.nodist,
nopip=options.nopip,
verbose=options.verbose)
for d in options.dirs:
builder.create(d)
if __name__ == '__main__':
rc = 1
try:
main()
rc = 0
except Exception as e:
print('Error: %s' % e, file=sys.stderr)
sys.exit(rc)
این اسکریپت همچنین بهصورت آنلاین برای بارگذاری در دسترس است.