Skip to content

Commit

Permalink
pip freeze: skip local directory by default
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikulimu committed Oct 29, 2018
1 parent b47b2fa commit fc456df
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 28 deletions.
1 change: 1 addition & 0 deletions news/2926.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Skip local directory by default for 'pip freeze'.
3 changes: 2 additions & 1 deletion src/pip/_internal/operations/freeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def freeze(
installations = {}
for dist in get_installed_distributions(local_only=local_only,
skip=(),
user_only=user_only):
user_only=user_only,
include_curr_dir=False):
try:
req = FrozenRequirement.from_dist(dist)
except RequirementParseError:
Expand Down
24 changes: 22 additions & 2 deletions src/pip/_internal/utils/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,20 @@ def dist_is_editable(dist):
return False


def dist_in_curr_dir(dist):
'''
Return True if given Distribution is installed in the current directory.
'''
norm_path = normalize_path(dist_location(dist))
return norm_path.startswith(normalize_path(os.getcwd()))


def get_installed_distributions(local_only=True,
skip=stdlib_pkgs,
include_editables=True,
editables_only=False,
user_only=False):
user_only=False,
include_curr_dir=True):
"""
Return a list of installed Distribution objects.
Expand All @@ -351,6 +360,9 @@ def get_installed_distributions(local_only=True,
If ``user_only`` is True , only report installations in the user
site directory.
If ``include_curr_dir`` is False, ignore the current directory when
looking for installations.
"""
if local_only:
local_test = dist_is_local
Expand Down Expand Up @@ -378,12 +390,20 @@ def editables_only_test(d):
def user_test(d):
return True

if include_curr_dir:
def curr_dir_test(d):
return True
else:
def curr_dir_test(d):
return not dist_in_curr_dir(d)

return [d for d in pkg_resources.working_set
if local_test(d) and
d.key not in skip and
editable_test(d) and
editables_only_test(d) and
user_test(d)
user_test(d) and
curr_dir_test(d)
]


Expand Down
49 changes: 32 additions & 17 deletions tests/functional/test_freeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ def banner(msg):
)


def _fake_install(pkgname, dest):
egg_info_path = os.path.join(
dest, '{}-1.0-py{}.{}.egg-info'.format(
pkgname.replace('-', '_'),
sys.version_info[0],
sys.version_info[1]
)
)
with open(egg_info_path, 'w') as egg_info_file:
egg_info_file.write(textwrap.dedent("""\
Metadata-Version: 1.0
Name: {}
Version: 1.0
""".format(pkgname)
))

return egg_info_path


def test_basic_freeze(script):
"""
Some tests of freeze, first we have to install some stuff. Note that
Expand Down Expand Up @@ -73,34 +92,30 @@ def test_freeze_with_pip(script):
assert 'pip==' in result.stdout


def test_freeze_skip_curr_dir(script):
'''
Test that 'pip freeze' skips current directory by default.
'''

curr_dir = os.getcwd()
egg_info_path = _fake_install("local-package", curr_dir)
result = script.pip('freeze')
os.remove(egg_info_path)
assert 'local-package==' not in result.stdout


def test_freeze_with_invalid_names(script):
"""
Test that invalid names produce warnings and are passed over gracefully.
"""

def fake_install(pkgname, dest):
egg_info_path = os.path.join(
dest, '{}-1.0-py{}.{}.egg-info'.format(
pkgname.replace('-', '_'),
sys.version_info[0],
sys.version_info[1]
)
)
with open(egg_info_path, 'w') as egg_info_file:
egg_info_file.write(textwrap.dedent("""\
Metadata-Version: 1.0
Name: {}
Version: 1.0
""".format(pkgname)
))

valid_pkgnames = ('middle-dash', 'middle_underscore', 'middle.dot')
invalid_pkgnames = (
'-leadingdash', '_leadingunderscore', '.leadingdot',
'trailingdash-', 'trailingunderscore_', 'trailingdot.'
)
for pkgname in valid_pkgnames + invalid_pkgnames:
fake_install(pkgname, script.site_packages_path)
_fake_install(pkgname, script.site_packages_path)
result = script.pip('freeze', expect_stderr=True)
for pkgname in valid_pkgnames:
_check_output(
Expand Down
34 changes: 26 additions & 8 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def test_noegglink_in_sitepkgs_venv_global(self):
assert egg_link_path(self.mock_dist) is None


@patch('pip._internal.utils.misc.dist_in_curr_dir')
@patch('pip._internal.utils.misc.dist_in_usersite')
@patch('pip._internal.utils.misc.dist_is_local')
@patch('pip._internal.utils.misc.dist_is_editable')
Expand All @@ -177,6 +178,7 @@ class Tests_get_installed_distributions:
Mock(test_name="editable"),
Mock(test_name="normal"),
Mock(test_name="user"),
Mock(test_name="curr_dir")
]

workingset_stdlib = [
Expand All @@ -199,45 +201,57 @@ def dist_is_local(self, dist):
def dist_in_usersite(self, dist):
return dist.test_name == "user"

def dist_in_curr_dir(self, dist):
return dist.test_name == "curr_dir"

@patch('pip._vendor.pkg_resources.working_set', workingset)
def test_editables_only(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions(editables_only=True)
assert len(dists) == 1, dists
assert dists[0].test_name == "editable"

@patch('pip._vendor.pkg_resources.working_set', workingset)
def test_exclude_editables(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions(include_editables=False)
assert len(dists) == 1
assert len(dists) == 2
assert dists[0].test_name == "normal"
assert dists[1].test_name == "curr_dir"

@patch('pip._vendor.pkg_resources.working_set', workingset)
def test_include_globals(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions(local_only=False)
assert len(dists) == 4
assert len(dists) == 5

@patch('pip._vendor.pkg_resources.working_set', workingset)
def test_user_only(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions(local_only=False,
user_only=True)
assert len(dists) == 1
Expand All @@ -246,20 +260,24 @@ def test_user_only(self, mock_dist_is_editable,
@patch('pip._vendor.pkg_resources.working_set', workingset_stdlib)
def test_gte_py27_excludes(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions()
assert len(dists) == 0

@patch('pip._vendor.pkg_resources.working_set', workingset_freeze)
def test_freeze_excludes(self, mock_dist_is_editable,
mock_dist_is_local,
mock_dist_in_usersite):
mock_dist_in_usersite,
mock_dist_in_curr_dir):
mock_dist_is_editable.side_effect = self.dist_is_editable
mock_dist_is_local.side_effect = self.dist_is_local
mock_dist_in_usersite.side_effect = self.dist_in_usersite
mock_dist_in_curr_dir.side_effect = self.dist_in_curr_dir
dists = get_installed_distributions(
skip=('setuptools', 'pip', 'distribute'))
assert len(dists) == 0
Expand Down

0 comments on commit fc456df

Please sign in to comment.