6
6
import shutil
7
7
import time
8
8
import tempfile
9
- from glob import glob
10
9
import json as simplejson
11
10
import click
12
11
import click_completion
51
50
PIPENV_SKIP_VALIDATION ,
52
51
PIPENV_HIDE_EMOJIS ,
53
52
PIPENV_INSTALL_TIMEOUT ,
54
- PYENV_ROOT ,
55
- PYENV_INSTALLED ,
56
53
PIPENV_YES ,
57
54
PIPENV_DONT_LOAD_ENV ,
58
55
PIPENV_DEFAULT_PYTHON_VERSION ,
@@ -317,76 +314,38 @@ def ensure_pipfile(validate=True, skip_requirements=False, system=False):
317
314
project .write_toml (p )
318
315
319
316
320
- def find_python_from_py ( python ):
321
- """Find a Python executable from on Windows .
317
+ def find_a_system_python ( line ):
318
+ """Find a Python installation from a given line .
322
319
323
- Ask py.exe for its opinion.
324
- """
325
- py = system_which ("py" )
326
- if not py :
327
- return None
328
-
329
- version_args = ["-{0}" .format (python [0 ])]
330
- if len (python ) >= 2 :
331
- version_args .append ("-{0}.{1}" .format (python [0 ], python [2 ]))
332
- import subprocess
333
-
334
- for ver_arg in reversed (version_args ):
335
- try :
336
- python_exe = subprocess .check_output (
337
- [py , ver_arg , "-c" , "import sys; print(sys.executable)" ]
338
- )
339
- except subprocess .CalledProcessError :
340
- continue
320
+ This tries to parse the line in various of ways:
341
321
342
- if not isinstance (python_exe , str ):
343
- python_exe = python_exe .decode (sys .getdefaultencoding ())
344
- python_exe = python_exe .strip ()
345
- version = python_version (python_exe )
346
- if (version or "" ).startswith (python ):
347
- return python_exe
348
-
349
-
350
- def find_python_in_path (python ):
351
- """Find a Python executable from a version number.
352
-
353
- This uses the PATH environment variable to locate an appropriate Python.
322
+ * Looks like an absolute path? Use it directly.
323
+ * Looks like a py.exe call? Use py.exe to get the executable.
324
+ * Starts with "py" something? Looks like a python command. Try to find it
325
+ in PATH, and use it directly.
326
+ * Search for "python" and "pythonX.Y" executables in PATH to find a match.
327
+ * Nothing fits, return None.
354
328
"""
355
- possibilities = ["python" , "python{0}" .format (python [0 ])]
356
- if len (python ) >= 2 :
357
- possibilities .extend (
358
- [
359
- "python{0}{1}" .format (python [0 ], python [2 ]),
360
- "python{0}.{1}" .format (python [0 ], python [2 ]),
361
- "python{0}.{1}m" .format (python [0 ], python [2 ]),
362
- ]
363
- )
364
- # Reverse the list, so we find specific ones first.
365
- possibilities = reversed (possibilities )
366
- for possibility in possibilities :
367
- # Windows compatibility.
368
- if os .name == "nt" :
369
- possibility = "{0}.exe" .format (possibility )
370
- pythons = system_which (possibility , mult = True )
371
- for p in pythons :
372
- version = python_version (p )
373
- if (version or "" ).startswith (python ):
374
- return p
375
-
376
-
377
- def find_a_system_python (python ):
378
- """Finds a system python, given a version (e.g. 2 / 2.7 / 3.6.2), or a full path."""
379
- if python .startswith ("py" ):
380
- return system_which (python )
381
-
382
- elif os .path .isabs (python ):
383
- return python
384
-
385
- python_from_py = find_python_from_py (python )
386
- if python_from_py :
387
- return python_from_py
388
-
389
- return find_python_in_path (python )
329
+ if not line :
330
+ return None
331
+ if os .path .isabs (line ):
332
+ return line
333
+ from .vendor .pythonfinder import Finder
334
+ finder = Finder (system = False , global_search = True )
335
+ if ((line .startswith ("py " ) or line .startswith ("py.exe " ))
336
+ and os .name == 'nt' ):
337
+ line = line .split (" " , 1 )[1 ].lstrip ("-" )
338
+ elif line .startswith ("py" ):
339
+ python_entry = finder .which (line )
340
+ if python_entry :
341
+ return python_entry .path .as_posix ()
342
+ return None
343
+ python_entry = finder .find_python_version (line )
344
+ if not python_entry :
345
+ python_entry = finder .which ("python{0}" .format (line ))
346
+ if python_entry :
347
+ return python_entry .path .as_posix ()
348
+ return None
390
349
391
350
392
351
def ensure_python (three = None , python = None ):
@@ -409,35 +368,7 @@ def abort():
409
368
)
410
369
sys .exit (1 )
411
370
412
- def activate_pyenv ():
413
- from notpip ._vendor .packaging .version import parse as parse_version
414
-
415
- """Adds all pyenv installations to the PATH."""
416
- if PYENV_INSTALLED :
417
- if PYENV_ROOT :
418
- pyenv_paths = {}
419
- for found in glob ("{0}{1}versions{1}*" .format (PYENV_ROOT , os .sep )):
420
- pyenv_paths [os .path .split (found )[1 ]] = "{0}{1}bin" .format (
421
- found , os .sep
422
- )
423
- for version_str , pyenv_path in pyenv_paths .items ():
424
- version = parse_version (version_str )
425
- if version .is_prerelease and pyenv_paths .get (version .base_version ):
426
- continue
427
-
428
- add_to_path (pyenv_path )
429
- else :
430
- click .echo (
431
- "{0}: PYENV_ROOT is not set. New python paths will "
432
- "probably not be exported properly after installation."
433
- "" .format (crayons .red ("Warning" , bold = True )),
434
- err = True ,
435
- )
436
-
437
371
global USING_DEFAULT_PYTHON
438
- # Add pyenv paths to PATH.
439
- activate_pyenv ()
440
- path_to_python = None
441
372
USING_DEFAULT_PYTHON = three is None and not python
442
373
# Find out which python is desired.
443
374
if not python :
@@ -446,8 +377,7 @@ def activate_pyenv():
446
377
python = project .required_python_version
447
378
if not python :
448
379
python = PIPENV_DEFAULT_PYTHON_VERSION
449
- if python :
450
- path_to_python = find_a_system_python (python )
380
+ path_to_python = find_a_system_python (python )
451
381
if not path_to_python and python is not None :
452
382
# We need to install Python.
453
383
click .echo (
@@ -459,6 +389,7 @@ def activate_pyenv():
459
389
err = True ,
460
390
)
461
391
# Pyenv is installed
392
+ from .vendor .pythonfinder .environment import PYENV_INSTALLED
462
393
if not PYENV_INSTALLED :
463
394
abort ()
464
395
else :
@@ -501,8 +432,6 @@ def activate_pyenv():
501
432
click .echo (crayons .blue (e .err ), err = True )
502
433
# Print the results, in a beautiful blue…
503
434
click .echo (crayons .blue (c .out ), err = True )
504
- # Add new paths to PATH.
505
- activate_pyenv ()
506
435
# Find the newly installed Python, hopefully.
507
436
version = str (version )
508
437
path_to_python = find_a_system_python (version )
@@ -915,21 +844,17 @@ def do_create_virtualenv(python=None, site_packages=False, pypi_mirror=None):
915
844
916
845
# Actually create the virtualenv.
917
846
with spinner ():
918
- try :
919
- c = delegator .run (cmd , block = False , timeout = PIPENV_TIMEOUT , env = pip_config )
920
- except OSError :
921
- click .echo (
922
- "{0}: it looks like {1} is not in your {2}. "
923
- "We cannot continue until this is resolved."
924
- "" .format (
925
- crayons .red ("Warning" , bold = True ),
926
- crayons .red (cmd [0 ]),
927
- crayons .normal ("PATH" , bold = True ),
928
- ),
929
- err = True ,
930
- )
931
- sys .exit (1 )
932
- click .echo (crayons .blue (c .out ), err = True )
847
+ c = delegator .run (
848
+ cmd , block = False , timeout = PIPENV_TIMEOUT , env = pip_config ,
849
+ )
850
+ c .block ()
851
+ click .echo (crayons .blue ("{0}" .format (c .out )), err = True )
852
+ if c .return_code != 0 :
853
+ click .echo (crayons .blue ("{0}" .format (c .err )), err = True )
854
+ click .echo (u"{0}: Failed to create virtual environment." .format (
855
+ crayons .red ("Warning" , bold = True ),
856
+ ), err = True )
857
+ sys .exit (1 )
933
858
934
859
# Associate project directory with the environment.
935
860
# This mimics Pew's "setproject".
@@ -1258,19 +1183,19 @@ def do_init(
1258
1183
err = True ,
1259
1184
)
1260
1185
else :
1261
- click .echo (
1262
- crayons .red (
1263
- u"Pipfile.lock ({0}) out of date, updating to ({1})…" .format (
1264
- old_hash [- 6 :], new_hash [- 6 :]
1265
- ),
1266
- bold = True ,
1267
- ),
1268
- err = True ,
1269
- )
1186
+ if old_hash :
1187
+ msg = u"Pipfile.lock ({1}) out of date, updating to ({0})…"
1188
+ else :
1189
+ msg = u"Pipfile.lock is corrupted, replaced with ({0})…"
1190
+ click .echo (crayons .red (
1191
+ msg .format (old_hash [- 6 :], new_hash [- 6 :]),
1192
+ bold = True ,
1193
+ ), err = True )
1270
1194
do_lock (
1271
1195
system = system ,
1272
1196
pre = pre ,
1273
1197
keep_outdated = keep_outdated ,
1198
+ verbose = verbose ,
1274
1199
write = True ,
1275
1200
pypi_mirror = pypi_mirror ,
1276
1201
)
0 commit comments