27
27
import subprocess
28
28
import pkgutil
29
29
import tempfile
30
+ import textwrap
30
31
from distutils .util import strtobool
31
32
from os .path import join
32
33
35
36
except ImportError :
36
37
import configparser as ConfigParser
37
38
38
- __version__ = "14 .0.6 "
39
+ __version__ = "15 .0.0 "
39
40
virtualenv_version = __version__ # legacy
40
41
41
42
if sys .version_info < (2 , 6 ):
@@ -353,22 +354,19 @@ def copyfile(src, dest, symlink=True):
353
354
def writefile (dest , content , overwrite = True ):
354
355
if not os .path .exists (dest ):
355
356
logger .info ('Writing %s' , dest )
356
- f = open (dest , 'wb' )
357
- f .write (content .encode ('utf-8' ))
358
- f .close ()
357
+ with open (dest , 'wb' ) as f :
358
+ f .write (content .encode ('utf-8' ))
359
359
return
360
360
else :
361
- f = open (dest , 'rb' )
362
- c = f .read ()
363
- f .close ()
361
+ with open (dest , 'rb' ) as f :
362
+ c = f .read ()
364
363
if c != content .encode ("utf-8" ):
365
364
if not overwrite :
366
365
logger .notify ('File %s exists with different content; not overwriting' , dest )
367
366
return
368
367
logger .notify ('Overwriting %s with new content' , dest )
369
- f = open (dest , 'wb' )
370
- f .write (content .encode ('utf-8' ))
371
- f .close ()
368
+ with open (dest , 'wb' ) as f :
369
+ f .write (content .encode ('utf-8' ))
372
370
else :
373
371
logger .info ('Content %s already in place' , dest )
374
372
@@ -709,7 +707,7 @@ def main():
709
707
def call_subprocess (cmd , show_stdout = True ,
710
708
filter_stdout = None , cwd = None ,
711
709
raise_on_returncode = True , extra_env = None ,
712
- remove_from_env = None ):
710
+ remove_from_env = None , stdin = None ):
713
711
cmd_parts = []
714
712
for part in cmd :
715
713
if len (part ) > 45 :
@@ -739,7 +737,9 @@ def call_subprocess(cmd, show_stdout=True,
739
737
env = None
740
738
try :
741
739
proc = subprocess .Popen (
742
- cmd , stderr = subprocess .STDOUT , stdin = None , stdout = stdout ,
740
+ cmd , stderr = subprocess .STDOUT ,
741
+ stdin = None if stdin is None else subprocess .PIPE ,
742
+ stdout = stdout ,
743
743
cwd = cwd , env = env )
744
744
except Exception :
745
745
e = sys .exc_info ()[1 ]
@@ -748,6 +748,10 @@ def call_subprocess(cmd, show_stdout=True,
748
748
raise
749
749
all_output = []
750
750
if stdout is not None :
751
+ if stdin is not None :
752
+ proc .stdin .write (stdin )
753
+ proc .stdin .close ()
754
+
751
755
stdout = proc .stdout
752
756
encoding = sys .getdefaultencoding ()
753
757
fs_encoding = sys .getfilesystemencoding ()
@@ -771,7 +775,7 @@ def call_subprocess(cmd, show_stdout=True,
771
775
else :
772
776
logger .info (line )
773
777
else :
774
- proc .communicate ()
778
+ proc .communicate (stdin )
775
779
proc .wait ()
776
780
if proc .returncode :
777
781
if raise_on_returncode :
@@ -839,48 +843,56 @@ def space_path2url(p):
839
843
return urljoin ('file:' , pathname2url (os .path .abspath (p )))
840
844
findlinks = ' ' .join (space_path2url (d ) for d in search_dirs )
841
845
842
- sys .path = pythonpath .split (os .pathsep ) + sys .path
843
- cert_data = pkgutil .get_data ("pip._vendor.requests" , "cacert.pem" )
846
+ SCRIPT = textwrap .dedent ("""
847
+ import sys
848
+ import pkgutil
849
+ import tempfile
850
+ import os
844
851
845
- if cert_data is not None :
846
- cert_file = tempfile .NamedTemporaryFile (delete = False )
847
- cert_file .write (cert_data )
848
- cert_file .close ()
849
- else :
850
- cert_file = None
852
+ import pip
851
853
852
- try :
853
- cmd = [
854
- py_executable , '-c' ,
855
- 'import sys, pip; sys.exit(pip.main(["install", "--ignore-installed"] + sys.argv[1:]))' ,
856
- ] + project_names
857
- logger .start_progress ('Installing %s...' % (', ' .join (project_names )))
858
- logger .indent += 2
859
-
860
- env = {
861
- "PYTHONPATH" : pythonpath ,
862
- "JYTHONPATH" : pythonpath , # for Jython < 3.x
863
- "PIP_FIND_LINKS" : findlinks ,
864
- "PIP_USE_WHEEL" : "1" ,
865
- "PIP_ONLY_BINARY" : ":all:" ,
866
- "PIP_PRE" : "1" ,
867
- "PIP_USER" : "0" ,
868
- }
869
-
870
- if not download :
871
- env ["PIP_NO_INDEX" ] = "1"
872
-
873
- if cert_file is not None :
874
- env ["PIP_CERT" ] = cert_file .name
854
+ cert_data = pkgutil.get_data("pip._vendor.requests", "cacert.pem")
855
+ if cert_data is not None:
856
+ cert_file = tempfile.NamedTemporaryFile(delete=False)
857
+ cert_file.write(cert_data)
858
+ cert_file.close()
859
+ else:
860
+ cert_file = None
875
861
876
862
try:
877
- call_subprocess (cmd , show_stdout = False , extra_env = env )
863
+ args = ["install", "--ignore-installed"]
864
+ if cert_file is not None:
865
+ args += ["--cert", cert_file.name]
866
+ args += sys.argv[1:]
867
+
868
+ sys.exit(pip.main(args))
878
869
finally:
879
- logger .indent -= 2
880
- logger .end_progress ()
870
+ if cert_file is not None:
871
+ os.remove(cert_file.name)
872
+ """ ).encode ("utf8" )
873
+
874
+ cmd = [py_executable , '-' ] + project_names
875
+ logger .start_progress ('Installing %s...' % (', ' .join (project_names )))
876
+ logger .indent += 2
877
+
878
+ env = {
879
+ "PYTHONPATH" : pythonpath ,
880
+ "JYTHONPATH" : pythonpath , # for Jython < 3.x
881
+ "PIP_FIND_LINKS" : findlinks ,
882
+ "PIP_USE_WHEEL" : "1" ,
883
+ "PIP_ONLY_BINARY" : ":all:" ,
884
+ "PIP_PRE" : "1" ,
885
+ "PIP_USER" : "0" ,
886
+ }
887
+
888
+ if not download :
889
+ env ["PIP_NO_INDEX" ] = "1"
890
+
891
+ try :
892
+ call_subprocess (cmd , show_stdout = False , extra_env = env , stdin = SCRIPT )
881
893
finally :
882
- if cert_file is not None :
883
- os . remove ( cert_file . name )
894
+ logger . indent -= 2
895
+ logger . end_progress ( )
884
896
885
897
886
898
def create_environment (home_dir , site_packages = False , clear = False ,
@@ -1583,16 +1595,14 @@ def fixup_scripts(home_dir, bin_dir):
1583
1595
if not os .path .isfile (filename ):
1584
1596
# ignore subdirs, e.g. .svn ones.
1585
1597
continue
1586
- f = open ( filename , 'rb' )
1587
- try :
1598
+ lines = None
1599
+ with open ( filename , 'rb' ) as f :
1588
1600
try :
1589
1601
lines = f .read ().decode ('utf-8' ).splitlines ()
1590
1602
except UnicodeDecodeError :
1591
1603
# This is probably a binary program instead
1592
1604
# of a script, so just ignore it.
1593
1605
continue
1594
- finally :
1595
- f .close ()
1596
1606
if not lines :
1597
1607
logger .warn ('Script %s is an empty file' % filename )
1598
1608
continue
@@ -1611,9 +1621,9 @@ def fixup_scripts(home_dir, bin_dir):
1611
1621
continue
1612
1622
logger .notify ('Making script %s relative' % filename )
1613
1623
script = relative_script ([new_shebang ] + lines [1 :])
1614
- f = open (filename , 'wb' )
1615
- f .write ('\n ' .join (script ).encode ('utf-8' ))
1616
- f . close ()
1624
+ with open (filename , 'wb' ) as f :
1625
+ f .write ('\n ' .join (script ).encode ('utf-8' ))
1626
+
1617
1627
1618
1628
def relative_script (lines ):
1619
1629
"Return a script that'll work in a relocatable environment."
@@ -1660,9 +1670,8 @@ def fixup_pth_and_egg_link(home_dir, sys_path=None):
1660
1670
def fixup_pth_file (filename ):
1661
1671
lines = []
1662
1672
prev_lines = []
1663
- f = open (filename )
1664
- prev_lines = f .readlines ()
1665
- f .close ()
1673
+ with open (filename ) as f :
1674
+ prev_lines = f .readlines ()
1666
1675
for line in prev_lines :
1667
1676
line = line .strip ()
1668
1677
if (not line or line .startswith ('#' ) or line .startswith ('import ' )
@@ -1677,22 +1686,19 @@ def fixup_pth_file(filename):
1677
1686
logger .info ('No changes to .pth file %s' % filename )
1678
1687
return
1679
1688
logger .notify ('Making paths in .pth file %s relative' % filename )
1680
- f = open (filename , 'w' )
1681
- f .write ('\n ' .join (lines ) + '\n ' )
1682
- f .close ()
1689
+ with open (filename , 'w' ) as f :
1690
+ f .write ('\n ' .join (lines ) + '\n ' )
1683
1691
1684
1692
def fixup_egg_link (filename ):
1685
- f = open (filename )
1686
- link = f .readline ().strip ()
1687
- f .close ()
1693
+ with open (filename ) as f :
1694
+ link = f .readline ().strip ()
1688
1695
if os .path .abspath (link ) != link :
1689
1696
logger .debug ('Link in %s already relative' % filename )
1690
1697
return
1691
1698
new_link = make_relative_path (filename , link )
1692
1699
logger .notify ('Rewriting link %s in %s as %s' % (link , filename , new_link ))
1693
- f = open (filename , 'w' )
1694
- f .write (new_link )
1695
- f .close ()
1700
+ with open (filename , 'w' ) as f :
1701
+ f .write (new_link )
1696
1702
1697
1703
def make_relative_path (source , dest , dest_is_directory = True ):
1698
1704
"""
@@ -1775,9 +1781,8 @@ def after_install(options, home_dir):
1775
1781
filename = __file__
1776
1782
if filename .endswith ('.pyc' ):
1777
1783
filename = filename [:- 1 ]
1778
- f = codecs .open (filename , 'r' , encoding = 'utf-8' )
1779
- content = f .read ()
1780
- f .close ()
1784
+ with codecs .open (filename , 'r' , encoding = 'utf-8' ) as f :
1785
+ content = f .read ()
1781
1786
py_exe = 'python%s' % python_version
1782
1787
content = (('#!/usr/bin/env %s\n ' % py_exe )
1783
1788
+ '## WARNING: This file is generated\n '
@@ -2297,7 +2302,9 @@ def do_file(file, offset=0, size=maxint):
2297
2302
do_macho (file , 64 , LITTLE_ENDIAN )
2298
2303
2299
2304
assert (len (what ) >= len (value ))
2300
- do_file (open (path , 'r+b' ))
2305
+
2306
+ with open (path , 'r+b' ) as f :
2307
+ do_file (f )
2301
2308
2302
2309
2303
2310
if __name__ == '__main__' :
0 commit comments