Skip to content

Commit 9319efc

Browse files
committed
Merge pull request #1335 from dstufft/compile-wheel-pyc
Enable --[no-]compile which will compile or not compile pyc files
2 parents 56d3a48 + 7ec49dc commit 9319efc

File tree

5 files changed

+119
-3
lines changed

5 files changed

+119
-3
lines changed

pip/commands/install.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,21 @@ def __init__(self, *args, **kw):
136136
default=None,
137137
help="Install everything relative to this alternate root directory.")
138138

139+
cmd_opts.add_option(
140+
"--compile",
141+
action="store_true",
142+
dest="compile",
143+
default=True,
144+
help="Compile py files to pyc",
145+
)
146+
147+
cmd_opts.add_option(
148+
"--no-compile",
149+
action="store_false",
150+
dest="compile",
151+
help="Do not compile py files to pyc",
152+
)
153+
139154
cmd_opts.add_option(cmdoptions.use_wheel.make())
140155
cmd_opts.add_option(cmdoptions.no_use_wheel.make())
141156

@@ -227,6 +242,7 @@ def run(self, options, args):
227242
use_user_site=options.use_user_site,
228243
target_dir=temp_target_dir,
229244
session=session,
245+
pycompile=options.compile,
230246
)
231247
for name in args:
232248
requirement_set.add_requirement(

pip/req.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class InstallRequirement(object):
3939

4040
def __init__(self, req, comes_from, source_dir=None, editable=False,
4141
url=None, as_egg=False, update=True, prereleases=None,
42-
editable_options=None, from_bundle=False):
42+
editable_options=None, from_bundle=False, pycompile=True):
4343
self.extras = ()
4444
if isinstance(req, string_types):
4545
req = pkg_resources.Requirement.parse(req)
@@ -74,6 +74,8 @@ def __init__(self, req, comes_from, source_dir=None, editable=False,
7474
self.target_dir = None
7575
self.from_bundle = from_bundle
7676

77+
self.pycompile = pycompile
78+
7779
# True if pre-releases are acceptable
7880
if prereleases:
7981
self.prereleases = True
@@ -638,6 +640,11 @@ def install(self, install_options, global_options=(), root=None):
638640
if root is not None:
639641
install_args += ['--root', root]
640642

643+
if self.pycompile:
644+
install_args += ["--compile"]
645+
else:
646+
install_args += ["--no-compile"]
647+
641648
if running_under_virtualenv():
642649
## FIXME: I'm not sure if this is a reasonable location; probably not
643650
## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable
@@ -843,6 +850,7 @@ def move_wheel_files(self, wheeldir, root=None):
843850
user=self.use_user_site,
844851
home=self.target_dir,
845852
root=root,
853+
pycompile=self.pycompile,
846854
)
847855

848856
@property
@@ -884,7 +892,7 @@ class RequirementSet(object):
884892
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
885893
upgrade=False, ignore_installed=False, as_egg=False, target_dir=None,
886894
ignore_dependencies=False, force_reinstall=False, use_user_site=False,
887-
session=None):
895+
session=None, pycompile=True):
888896
self.build_dir = build_dir
889897
self.src_dir = src_dir
890898
self.download_dir = download_dir
@@ -904,6 +912,7 @@ def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
904912
self.use_user_site = use_user_site
905913
self.target_dir = target_dir #set from --target option
906914
self.session = session or PipSession()
915+
self.pycompile = pycompile
907916

908917
def __str__(self):
909918
reqs = [req for req in self.requirements.values()
@@ -916,6 +925,7 @@ def add_requirement(self, install_req):
916925
install_req.as_egg = self.as_egg
917926
install_req.use_user_site = self.use_user_site
918927
install_req.target_dir = self.target_dir
928+
install_req.pycompile = self.pycompile
919929
if not name:
920930
#url or path requirement w/o an egg fragment
921931
self.unnamed_requirements.append(install_req)

pip/wheel.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
from __future__ import with_statement
55

6+
import compileall
67
import csv
78
import functools
89
import hashlib
@@ -134,7 +135,8 @@ def get_entrypoints(filename):
134135
return console, gui
135136

136137

137-
def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None):
138+
def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None,
139+
pycompile=True):
138140
"""Install a wheel"""
139141

140142
scheme = distutils_scheme(name, user=user, home=home, root=root)
@@ -156,6 +158,10 @@ def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None):
156158
changed = set()
157159
generated = []
158160

161+
# Compile all of the pyc files that we're going to be installing
162+
if pycompile:
163+
compileall.compile_dir(source, force=True, quiet=True)
164+
159165
def normpath(src, p):
160166
return make_path_relative(src, p).replace(os.path.sep, '/')
161167

tests/functional/test_install.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
import textwrap
4+
import glob
45

56
from os.path import abspath, join, curdir, pardir
67

@@ -456,3 +457,43 @@ def test_url_req_case_mismatch(script, data):
456457
assert egg_folder in result.files_created, str(result)
457458
egg_folder = script.site_packages / 'Upper-2.0-py%s.egg-info' % pyversion
458459
assert egg_folder not in result.files_created, str(result)
460+
461+
462+
def test_compiles_pyc(script):
463+
"""
464+
Test installing with --compile on
465+
"""
466+
del script.environ["PYTHONDONTWRITEBYTECODE"]
467+
script.pip("install", "--compile", "--no-use-wheel", "INITools==0.2")
468+
469+
# There are many locations for the __init__.pyc file so attempt to find
470+
# any of them
471+
exists = [
472+
os.path.exists(script.site_packages_path/"initools/__init__.pyc"),
473+
]
474+
475+
exists += glob.glob(
476+
script.site_packages_path/"initools/__pycache__/__init__*.pyc"
477+
)
478+
479+
assert any(exists)
480+
481+
482+
def test_no_compiles_pyc(script, data):
483+
"""
484+
Test installing from wheel with --compile on
485+
"""
486+
del script.environ["PYTHONDONTWRITEBYTECODE"]
487+
script.pip("install", "--no-compile", "--no-use-wheel", "INITools==0.2")
488+
489+
# There are many locations for the __init__.pyc file so attempt to find
490+
# any of them
491+
exists = [
492+
os.path.exists(script.site_packages_path/"initools/__init__.pyc"),
493+
]
494+
495+
exists += glob.glob(
496+
script.site_packages_path/"initools/__pycache__/__init__*.pyc"
497+
)
498+
499+
assert not any(exists)

tests/functional/test_install_wheel.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import os
22
import pytest
3+
import glob
4+
35
from tests.lib.path import Path
46

57

@@ -186,3 +188,44 @@ def test_install_from_wheel_gui_entrypoint(script, data):
186188
wrapper_file = script.bin / 't1'
187189
assert wrapper_file in result.files_created
188190

191+
192+
def test_wheel_compiles_pyc(script, data):
193+
"""
194+
Test installing from wheel with --compile on
195+
"""
196+
script.pip(
197+
"install", "--compile", "simple.dist==0.1", "--no-index",
198+
"--find-links=" + data.find_links
199+
)
200+
# There are many locations for the __init__.pyc file so attempt to find
201+
# any of them
202+
exists = [
203+
os.path.exists(script.site_packages_path/"simpledist/__init__.pyc"),
204+
]
205+
206+
exists += glob.glob(
207+
script.site_packages_path/"simpledist/__pycache__/__init__*.pyc"
208+
)
209+
210+
assert any(exists)
211+
212+
213+
def test_wheel_no_compiles_pyc(script, data):
214+
"""
215+
Test installing from wheel with --compile on
216+
"""
217+
script.pip(
218+
"install", "--no-compile", "simple.dist==0.1", "--no-index",
219+
"--find-links=" + data.find_links
220+
)
221+
# There are many locations for the __init__.pyc file so attempt to find
222+
# any of them
223+
exists = [
224+
os.path.exists(script.site_packages_path/"simpledist/__init__.pyc"),
225+
]
226+
227+
exists += glob.glob(
228+
script.site_packages_path/"simpledist/__pycache__/__init__*.pyc"
229+
)
230+
231+
assert not any(exists)

0 commit comments

Comments
 (0)