Skip to content

fix for #638 (__pycache__ file removal) #646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 27, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pip/backwardcompat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""Stuff that differs in different Python versions"""

import os
import imp
import sys
import site

__all__ = ['WindowsError']

uses_pycache = hasattr(imp,'cache_from_source')

try:
WindowsError = WindowsError
except NameError:
Expand Down
17 changes: 8 additions & 9 deletions pip/req.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from email.parser import FeedParser
import os
import imp
import pkg_resources
import re
import sys
Expand All @@ -13,13 +14,13 @@
DistributionNotFound)
from pip.vcs import vcs
from pip.log import logger
from pip.util import display_path, rmtree, is_pypy
from pip.util import display_path, rmtree
from pip.util import ask, ask_path_exists, backup_dir
from pip.util import is_installable_dir, is_local, dist_is_local, dist_in_usersite
from pip.util import renames, normalize_path, egg_link_path, dist_in_site_packages
from pip.util import make_path_relative
from pip.util import call_subprocess
from pip.backwardcompat import (urlparse, urllib,
from pip.backwardcompat import (urlparse, urllib, uses_pycache,
ConfigParser, string_types, HTTPError,
get_python_version, b)
from pip.index import Link
Expand Down Expand Up @@ -448,6 +449,8 @@ def uninstall(self, auto_confirm=False):
for installed_file in dist.get_metadata('installed-files.txt').splitlines():
path = os.path.normpath(os.path.join(egg_info_path, installed_file))
paths_to_remove.add(path)
#FIXME: need a test for this elif block
#occurs with --single-version-externally-managed/--record outside of pip
elif dist.has_metadata('top_level.txt'):
if dist.has_metadata('namespace_packages.txt'):
namespaces = dist.get_metadata('namespace_packages.txt')
Expand Down Expand Up @@ -1435,13 +1438,9 @@ def add(self, path):
else:
self._refuse.add(path)

#workaround for pip issue #626 (debian pypy creates __pycache__ folders)
if is_pypy:
head, tail = os.path.split(path)
tail_root, tail_ext = os.path.splitext(tail)
if tail_ext == '.py':
pycache_path = os.path.join(head, '__pycache__', tail_root + '.pypy-%d%d.pyc' % sys.pypy_version_info[:2])
self.add(pycache_path)
# __pycache__ files can show up after 'installed-files.txt' is created, due to imports
if os.path.splitext(path)[1] == '.py' and uses_pycache:
self.add(imp.cache_from_source(path))


def add_pth(self, pth_file, entry):
Expand Down
1 change: 0 additions & 1 deletion pip/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ def is_svn_page(html):
return (re.search(r'<title>[^<]*Revision \d+:', html)
and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I))

is_pypy = hasattr(sys, 'pypy_version_info')

def file_contents(filename):
fp = open(filename, 'rb')
Expand Down
Binary file modified tests/packages/parent-0.1.tar.gz
Binary file not shown.
17 changes: 17 additions & 0 deletions tests/test_uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def test_simple_uninstall():
env = reset_env()
result = run_pip('install', 'INITools==0.2')
assert join(env.site_packages, 'initools') in result.files_created, sorted(result.files_created.keys())
#the import forces the generation of __pycache__ if the version of python supports it
env.run('python', '-c', "import initools")
result2 = run_pip('uninstall', 'INITools', '-y')
assert_all_changes(result, result2, [env.venv/'build', 'cache'])

Expand All @@ -36,6 +38,19 @@ def test_uninstall_with_scripts():
assert_all_changes(result, result2, [env.venv/'build', 'cache'])


def test_uninstall_easy_install_after_import():
"""
Uninstall an easy_installed package after it's been imported

"""
env = reset_env()
result = env.run('easy_install', 'INITools==0.2', expect_stderr=True)
#the import forces the generation of __pycache__ if the version of python supports it
env.run('python', '-c', "import initools")
result2 = run_pip('uninstall', 'INITools', '-y')
assert_all_changes(result, result2, [env.venv/'build', 'cache'])


def test_uninstall_namespace_package():
"""
Uninstall a distribution with a namespace package without clobbering
Expand Down Expand Up @@ -66,6 +81,8 @@ def test_uninstall_overlapping_package():
result2 = run_pip('install', child_pkg, expect_error=False)
assert join(env.site_packages, 'child') in result2.files_created, sorted(result2.files_created.keys())
assert normpath(join(env.site_packages, 'parent/plugins/child_plugin.py')) in result2.files_created, sorted(result2.files_created.keys())
#the import forces the generation of __pycache__ if the version of python supports it
env.run('python', '-c', "import parent.plugins.child_plugin, child")
result3 = run_pip('uninstall', '-y', 'child', expect_error=False)
assert join(env.site_packages, 'child') in result3.files_deleted, sorted(result3.files_created.keys())
assert normpath(join(env.site_packages, 'parent/plugins/child_plugin.py')) in result3.files_deleted, sorted(result3.files_deleted.keys())
Expand Down