Hello community, here is the log from the commit of package python3-pip for openSUSE:Factory checked in at 2015-02-01 12:30:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-pip (Old) and /work/SRC/openSUSE:Factory/.python3-pip.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-pip" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-pip/python3-pip.changes 2015-01-09 20:50:31.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python3-pip.new/python3-pip.changes 2015-02-01 12:30:39.000000000 +0100 @@ -1,0 +2,17 @@ +Sat Jan 31 22:07:04 UTC 2015 - [email protected] + +- update to version 6.0.7: + * Fix a regression where Numpy requires a build path without + symlinks to properly build. + * Fix a broken log message when running pip wheel without a + requirement. + * Don’t mask network errors while downloading the file as a hash + failure. + * Properly create the state file for the pip version check so it + only happens once a week. + * Fix an issue where switching between Python 3 and Python 2 would + evict cached items. + * Fix a regression where pip would be unable to successfully + uninstall a project without a normalized version. + +------------------------------------------------------------------- Old: ---- pip-6.0.6.tar.gz New: ---- pip-6.0.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-pip.spec ++++++ --- /var/tmp/diff_new_pack.g2vRbk/_old 2015-02-01 12:30:40.000000000 +0100 +++ /var/tmp/diff_new_pack.g2vRbk/_new 2015-02-01 12:30:40.000000000 +0100 @@ -17,7 +17,7 @@ Name: python3-pip -Version: 6.0.6 +Version: 6.0.7 Release: 0 Url: http://www.pip-installer.org Summary: Pip installs packages. Python packages. An easy_install replacement ++++++ pip-6.0.6.tar.gz -> pip-6.0.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/AUTHORS.txt new/pip-6.0.7/AUTHORS.txt --- old/pip-6.0.6/AUTHORS.txt 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/AUTHORS.txt 2015-01-28 22:35:25.000000000 +0100 @@ -73,6 +73,7 @@ Igor Sobreira <[email protected]> Ilya Baryshev <[email protected]> INADA Naoki <[email protected]> +Ionel Cristian Mărieș <[email protected]> Ionel Maries Cristian <[email protected]> Jakub Stasiak <[email protected]> Jakub Vysoky <[email protected]> @@ -100,6 +101,7 @@ Kevin Burke <[email protected]> Kevin Frommelt <[email protected]> Kumar McMillan <[email protected]> +Laurent Bristiel <[email protected]> Leon Sasson <[email protected]> Lev Givon <[email protected]> Lincoln de Sousa <[email protected]> @@ -130,6 +132,7 @@ Oscar Benjamin <[email protected]> Patrick Dubroy <[email protected]> Patrick Jenkins <[email protected]> +patricktokeeffe <[email protected]> Paul Moore <[email protected]> Paul Nasrat <[email protected]> Paul Oswald <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/CHANGES.txt new/pip-6.0.7/CHANGES.txt --- old/pip-6.0.6/CHANGES.txt 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/CHANGES.txt 2015-01-28 22:35:25.000000000 +0100 @@ -1,3 +1,22 @@ +**6.0.7 (2015-01-28)** + +* Fix a regression where Numpy requires a build path without symlinks to + properly build. + +* Fix a broken log message when running ``pip wheel`` without a requirement. + +* Don't mask network errors while downloading the file as a hash failure. + +* Properly create the state file for the pip version check so it only happens + once a week. + +* Fix an issue where switching between Python 3 and Python 2 would evict cached + items. + +* Fix a regression where pip would be unable to successfully uninstall a + project without a normalized version. + + **6.0.6 (2015-01-03)** * Continue the regression fix from 6.0.5 which was not a complete fix. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/PKG-INFO new/pip-6.0.7/PKG-INFO --- old/pip-6.0.6/PKG-INFO 2015-01-03 10:32:20.000000000 +0100 +++ new/pip-6.0.7/PKG-INFO 2015-01-28 22:35:32.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pip -Version: 6.0.6 +Version: 6.0.7 Summary: The PyPA recommended tool for installing Python packages. Home-page: https://pip.pypa.io/ Author: The pip developers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/__init__.py new/pip-6.0.7/pip/__init__.py --- old/pip-6.0.6/pip/__init__.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/__init__.py 2015-01-28 22:35:25.000000000 +0100 @@ -30,7 +30,7 @@ cmdoptions = pip.cmdoptions # The version as used in the setup.py and the docs conf.py -__version__ = "6.0.6" +__version__ = "6.0.7" logger = logging.getLogger(__name__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/cachecontrol/__init__.py new/pip-6.0.7/pip/_vendor/cachecontrol/__init__.py --- old/pip-6.0.6/pip/_vendor/cachecontrol/__init__.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/cachecontrol/__init__.py 2015-01-28 22:35:25.000000000 +0100 @@ -2,6 +2,10 @@ Make it easy to import from cachecontrol without long namespaces. """ +__author__ = 'Eric Larson' +__email__ = '[email protected]' +__version__ = '0.11.1' + from .wrapper import CacheControl from .adapter import CacheControlAdapter from .controller import CacheController diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/cachecontrol/controller.py new/pip-6.0.7/pip/_vendor/cachecontrol/controller.py --- old/pip-6.0.6/pip/_vendor/cachecontrol/controller.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/cachecontrol/controller.py 2015-01-28 22:35:25.000000000 +0100 @@ -112,15 +112,19 @@ current_age = max(0, now - date) # TODO: There is an assumption that the result will be a - # urllib3 response object. This may not be best since we - # could probably avoid instantiating or constructing the - # response until we know we need it. + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. resp_cc = self.parse_cache_control(headers) # determine freshness freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header if 'max-age' in resp_cc and resp_cc['max-age'].isdigit(): freshness_lifetime = int(resp_cc['max-age']) + + # If there isn't a max-age, check for an expires header elif 'expires' in headers: expires = parsedate_tz(headers['expires']) if expires is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/cachecontrol/heuristics.py new/pip-6.0.7/pip/_vendor/cachecontrol/heuristics.py --- old/pip-6.0.6/pip/_vendor/cachecontrol/heuristics.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/cachecontrol/heuristics.py 2015-01-28 22:35:25.000000000 +0100 @@ -5,11 +5,24 @@ from datetime import datetime, timedelta +def expire_after(delta, date=None): + date = date or datetime.now() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + class BaseHeuristic(object): - def warning(self): + def warning(self, response): """ Return a valid 1xx warning header value describing the cache adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. """ return '110 - "Response is Stale"' @@ -17,15 +30,15 @@ """Update the response headers with any new headers. NOTE: This SHOULD always include some Warning header to - signify that the response was cached by the client, not by way - of the provided headers. - return response. + signify that the response was cached by the client, not + by way of the provided headers. """ return {} def apply(self, response): + warning_header = {'warning': self.warning(response)} response.headers.update(self.update_headers(response)) - response.headers.update({'warning': self.warning()}) + response.headers.update(warning_header) return response @@ -39,7 +52,28 @@ if 'expires' not in response.headers: date = parsedate(response.headers['date']) - expires = datetime(*date[:6]) + timedelta(days=1) - headers['expires'] = formatdate(calendar.timegm(expires.timetuple())) - + expires = expire_after(timedelta(days=1), + date=datetime(*date[:6])) + headers['expires'] = datetime_to_header(expires) + headers['cache-control'] = 'public' return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return { + 'expires': datetime_to_header(expires), + 'cache-control': 'public', + } + + def warning(self, response): + tmpl = '110 - Automatically cached for %s. Response might be stale' + return tmpl % self.delta diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/cachecontrol/serialize.py new/pip-6.0.7/pip/_vendor/cachecontrol/serialize.py --- old/pip-6.0.6/pip/_vendor/cachecontrol/serialize.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/cachecontrol/serialize.py 2015-01-28 22:35:25.000000000 +0100 @@ -1,10 +1,29 @@ +import base64 import io +import json +import zlib from pip._vendor.requests.structures import CaseInsensitiveDict from .compat import HTTPResponse, pickle +def _b64_encode_bytes(b): + return base64.b64encode(b).decode("ascii") + + +def _b64_encode_str(s): + return _b64_encode_bytes(s.encode("utf8")) + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + class Serializer(object): def dumps(self, request, response, body=None): @@ -12,15 +31,29 @@ if body is None: body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. response._fp = io.BytesIO(body) data = { "response": { - "body": body, - "headers": response.headers, + "body": _b64_encode_bytes(body), + "headers": dict( + (_b64_encode_str(k), _b64_encode_str(v)) + for k, v in response.headers.items() + ), "status": response.status, "version": response.version, - "reason": response.reason, + "reason": _b64_encode_str(response.reason), "strict": response.strict, "decode_content": response.decode_content, }, @@ -34,7 +67,20 @@ header = header.strip() data["vary"][header] = request.headers.get(header, None) - return b"cc=1," + pickle.dumps(data, pickle.HIGHEST_PROTOCOL) + # Encode our Vary headers to ensure they can be serialized as JSON + data["vary"] = dict( + (_b64_encode_str(k), _b64_encode_str(v) if v is not None else v) + for k, v in data["vary"].items() + ) + + return b",".join([ + b"cc=2", + zlib.compress( + json.dumps( + data, separators=(",", ":"), sort_keys=True, + ).encode("utf8"), + ), + ]) def loads(self, request, data): # Short circuit if we've been given an empty set of data @@ -65,18 +111,10 @@ # just treat it as a miss and return None return - def _loads_v0(self, request, data): - # The original legacy cache data. This doesn't contain enough - # information to construct everything we need, so we'll treat this as - # a miss. - return - - def _loads_v1(self, request, data): - try: - cached = pickle.loads(data) - except ValueError: - return - + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ # Special case the '*' Vary value as it means we cannot actually # determine if the cached response is suitable for this request. if "*" in cached.get("vary", {}): @@ -94,3 +132,41 @@ preload_content=False, **cached["response"] ) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except ValueError: + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes( + cached["response"]["body"] + ) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str( + cached["response"]["reason"], + ) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/colorama/__init__.py new/pip-6.0.7/pip/_vendor/colorama/__init__.py --- old/pip-6.0.6/pip/_vendor/colorama/__init__.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/colorama/__init__.py 2015-01-28 22:35:25.000000000 +0100 @@ -1,7 +1,7 @@ # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from .initialise import init, deinit, reinit -from .ansi import Fore, Back, Style +from .ansi import Fore, Back, Style, Cursor from .ansitowin32 import AnsiToWin32 -__version__ = '0.3.2' +__version__ = '0.3.3' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/colorama/ansi.py new/pip-6.0.7/pip/_vendor/colorama/ansi.py --- old/pip-6.0.6/pip/_vendor/colorama/ansi.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/colorama/ansi.py 2015-01-28 22:35:25.000000000 +0100 @@ -5,10 +5,14 @@ ''' CSI = '\033[' +OSC = '\033]' +BEL = '\007' + def code_to_chars(code): return CSI + str(code) + 'm' + class AnsiCodes(object): def __init__(self, codes): for name in dir(codes): @@ -16,27 +20,72 @@ value = getattr(codes, name) setattr(self, name, code_to_chars(value)) + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + "A" + def DOWN(self, n=1): + return CSI + str(n) + "B" + def FORWARD(self, n=1): + return CSI + str(n) + "C" + def BACK(self, n=1): + return CSI + str(n) + "D" + def POS(self, x=1, y=1): + return CSI + str(y) + ";" + str(x) + "H" + +def set_title(title): + return OSC + "2;" + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + "J" + +def clear_line(mode=2): + return CSI + str(mode) + "K" + + class AnsiFore: - BLACK = 30 - RED = 31 - GREEN = 32 - YELLOW = 33 - BLUE = 34 - MAGENTA = 35 - CYAN = 36 - WHITE = 37 - RESET = 39 + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + class AnsiBack: - BLACK = 40 - RED = 41 - GREEN = 42 - YELLOW = 43 - BLUE = 44 - MAGENTA = 45 - CYAN = 46 - WHITE = 47 - RESET = 49 + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + class AnsiStyle: BRIGHT = 1 @@ -47,4 +96,4 @@ Fore = AnsiCodes( AnsiFore ) Back = AnsiCodes( AnsiBack ) Style = AnsiCodes( AnsiStyle ) - +Cursor = AnsiCursor() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/colorama/ansitowin32.py new/pip-6.0.7/pip/_vendor/colorama/ansitowin32.py --- old/pip-6.0.6/pip/_vendor/colorama/ansitowin32.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/colorama/ansitowin32.py 2015-01-28 22:35:25.000000000 +0100 @@ -1,6 +1,7 @@ # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import re import sys +import os from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style from .winterm import WinTerm, WinColor, WinStyle @@ -41,7 +42,8 @@ sequences from the text, and if outputting to a tty, will convert them into win32 function calls. ''' - ANSI_RE = re.compile('\033\[((?:\d|;)*)([a-zA-Z])') + ANSI_CSI_RE = re.compile('\033\[((?:\d|;)*)([a-zA-Z])') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\033\]((?:.|;)*?)(\x07)') # Operating System Command def __init__(self, wrapped, convert=None, strip=None, autoreset=False): # The wrapped stream (normally sys.stdout or sys.stderr) @@ -53,16 +55,17 @@ # create the proxy wrapping our output stream self.stream = StreamWrapper(wrapped, self) - on_windows = sys.platform.startswith('win') + on_windows = os.name == 'nt' + on_emulated_windows = on_windows and 'TERM' in os.environ # should we strip ANSI sequences from our output? if strip is None: - strip = on_windows + strip = on_windows and not on_emulated_windows self.strip = strip # should we should convert ANSI sequences into win32 calls? if convert is None: - convert = on_windows and not wrapped.closed and is_a_tty(wrapped) + convert = on_windows and not wrapped.closed and not on_emulated_windows and is_a_tty(wrapped) self.convert = convert # dict of ansi codes to win32 functions and parameters @@ -71,7 +74,6 @@ # are we wrapping stderr? self.on_stderr = self.wrapped is sys.stderr - def should_wrap(self): ''' True if this class is actually needed. If false, then the output @@ -82,7 +84,6 @@ ''' return self.convert or self.strip or self.autoreset - def get_win32_calls(self): if self.convert and winterm: return { @@ -99,6 +100,14 @@ AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), AnsiFore.WHITE: (winterm.fore, WinColor.GREY), AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), AnsiBack.BLACK: (winterm.back, WinColor.BLACK), AnsiBack.RED: (winterm.back, WinColor.RED), AnsiBack.GREEN: (winterm.back, WinColor.GREEN), @@ -108,10 +117,17 @@ AnsiBack.CYAN: (winterm.back, WinColor.CYAN), AnsiBack.WHITE: (winterm.back, WinColor.GREY), AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), } return dict() - def write(self, text): if self.strip or self.convert: self.write_and_convert(text) @@ -136,7 +152,8 @@ calls. ''' cursor = 0 - for match in self.ANSI_RE.finditer(text): + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): start, end = match.span() self.write_plain_text(text, cursor, start) self.convert_ansi(*match.groups()) @@ -152,21 +169,29 @@ def convert_ansi(self, paramstring, command): if self.convert: - params = self.extract_params(paramstring) + params = self.extract_params(command, paramstring) self.call_win32(command, params) - def extract_params(self, paramstring): - def split(paramstring): - for p in paramstring.split(';'): - if p != '': - yield int(p) - return tuple(split(paramstring)) + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params def call_win32(self, command, params): - if params == []: - params = [0] if command == 'm': for param in params: if param in self.win32_calls: @@ -175,17 +200,29 @@ args = func_args[1:] kwargs = dict(on_stderr=self.on_stderr) func(*args, **kwargs) - elif command in ('H', 'f'): # set cursor position - func = winterm.set_cursor_position - func(params, on_stderr=self.on_stderr) - elif command in ('J'): - func = winterm.erase_data - func(params, on_stderr=self.on_stderr) - elif command == 'A': - if params == () or params == None: - num_rows = 1 - else: - num_rows = params[0] - func = winterm.cursor_up - func(num_rows, on_stderr=self.on_stderr) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/colorama/win32.py new/pip-6.0.7/pip/_vendor/colorama/win32.py --- old/pip-6.0.6/pip/_vendor/colorama/win32.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/colorama/win32.py 2015-01-28 22:35:25.000000000 +0100 @@ -13,18 +13,18 @@ windll = None SetConsoleTextAttribute = lambda *_: None else: - from ctypes import ( - byref, Structure, c_char, c_short, c_uint32, c_ushort, POINTER - ) + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD class CONSOLE_SCREEN_BUFFER_INFO(Structure): """struct in wincon.h.""" _fields_ = [ - ("dwSize", wintypes._COORD), - ("dwCursorPosition", wintypes._COORD), + ("dwSize", COORD), + ("dwCursorPosition", COORD), ("wAttributes", wintypes.WORD), ("srWindow", wintypes.SMALL_RECT), - ("dwMaximumWindowSize", wintypes._COORD), + ("dwMaximumWindowSize", COORD), ] def __str__(self): return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( @@ -58,7 +58,7 @@ _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition _SetConsoleCursorPosition.argtypes = [ wintypes.HANDLE, - wintypes._COORD, + COORD, ] _SetConsoleCursorPosition.restype = wintypes.BOOL @@ -67,7 +67,7 @@ wintypes.HANDLE, c_char, wintypes.DWORD, - wintypes._COORD, + COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputCharacterA.restype = wintypes.BOOL @@ -77,11 +77,17 @@ wintypes.HANDLE, wintypes.WORD, wintypes.DWORD, - wintypes._COORD, + COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputAttribute.restype = wintypes.BOOL + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleA + _SetConsoleTitleW.argtypes = [ + wintypes.LPCSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + handles = { STDOUT: _GetStdHandle(STDOUT), STDERR: _GetStdHandle(STDERR), @@ -98,26 +104,27 @@ handle = handles[stream_id] return _SetConsoleTextAttribute(handle, attrs) - def SetConsoleCursorPosition(stream_id, position): - position = wintypes._COORD(*position) + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) # If the position is out of range, do nothing. if position.Y <= 0 or position.X <= 0: return # Adjust for Windows' SetConsoleCursorPosition: # 1. being 0-based, while ANSI is 1-based. # 2. expecting (x,y), while ANSI uses (y,x). - adjusted_position = wintypes._COORD(position.Y - 1, position.X - 1) - # Adjust for viewport's scroll position - sr = GetConsoleScreenBufferInfo(STDOUT).srWindow - adjusted_position.Y += sr.Top - adjusted_position.X += sr.Left + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left # Resume normal processing handle = handles[stream_id] return _SetConsoleCursorPosition(handle, adjusted_position) def FillConsoleOutputCharacter(stream_id, char, length, start): handle = handles[stream_id] - char = c_char(char) + char = c_char(char.encode()) length = wintypes.DWORD(length) num_written = wintypes.DWORD(0) # Note that this is hard-coded for ANSI (vs wide) bytes. @@ -134,3 +141,6 @@ # Note that this is hard-coded for ANSI (vs wide) bytes. return _FillConsoleOutputAttribute( handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/colorama/winterm.py new/pip-6.0.7/pip/_vendor/colorama/winterm.py --- old/pip-6.0.6/pip/_vendor/colorama/winterm.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/colorama/winterm.py 2015-01-28 22:35:25.000000000 +0100 @@ -15,9 +15,9 @@ # from wincon.h class WinStyle(object): - NORMAL = 0x00 # dim text, dim background - BRIGHT = 0x08 # bright text, dim background - + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background class WinTerm(object): @@ -34,22 +34,26 @@ def set_attrs(self, value): self._fore = value & 7 self._back = (value >> 4) & 7 - self._style = value & WinStyle.BRIGHT + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) def reset_all(self, on_stderr=None): self.set_attrs(self._default) self.set_console(attrs=self._default) - def fore(self, fore=None, on_stderr=False): + def fore(self, fore=None, light=False, on_stderr=False): if fore is None: fore = self._default_fore self._fore = fore + if light: + self._style |= WinStyle.BRIGHT self.set_console(on_stderr=on_stderr) - def back(self, back=None, on_stderr=False): + def back(self, back=None, light=False, on_stderr=False): if back is None: back = self._default_back self._back = back + if light: + self._style |= WinStyle.BRIGHT_BACKGROUND self.set_console(on_stderr=on_stderr) def style(self, style=None, on_stderr=False): @@ -73,7 +77,7 @@ position.X += 1 position.Y += 1 return position - + def set_cursor_position(self, position=None, on_stderr=False): if position is None: #I'm not currently tracking the position, so there is no default. @@ -84,37 +88,64 @@ handle = win32.STDERR win32.SetConsoleCursorPosition(handle, position) - def cursor_up(self, num_rows=0, on_stderr=False): - if num_rows == 0: - return + def cursor_adjust(self, x, y, on_stderr=False): handle = win32.STDOUT if on_stderr: handle = win32.STDERR position = self.get_position(handle) - adjusted_position = (position.Y - num_rows, position.X) - self.set_cursor_position(adjusted_position, on_stderr) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) - def erase_data(self, mode=0, on_stderr=False): - # 0 (or None) should clear from the cursor to the end of the screen. + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. # 1 should clear from the cursor to the beginning of the screen. - # 2 should clear the entire screen. (And maybe move cursor to (1,1)?) - # - # At the moment, I only support mode 2. From looking at the API, it - # should be possible to calculate a different number of bytes to clear, - # and to do so relative to the cursor position. - if mode[0] not in (2,): - return + # 2 should clear the entire screen, and move cursor to (1,1) handle = win32.STDOUT if on_stderr: handle = win32.STDERR - # here's where we'll home the cursor - coord_screen = win32.COORD(0,0) csbi = win32.GetConsoleScreenBufferInfo(handle) # get the number of character cells in the current buffer - dw_con_size = csbi.dwSize.X * csbi.dwSize.Y + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen # fill the entire screen with blanks - win32.FillConsoleOutputCharacter(handle, ' ', dw_con_size, coord_screen) + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) # now set the buffer's attributes accordingly - win32.FillConsoleOutputAttribute(handle, self.get_attrs(), dw_con_size, coord_screen ); - # put the cursor at (0, 0) - win32.SetConsoleCursorPosition(handle, (coord_screen.X, coord_screen.Y)) + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/requests/__init__.py new/pip-6.0.7/pip/_vendor/requests/__init__.py --- old/pip-6.0.6/pip/_vendor/requests/__init__.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/requests/__init__.py 2015-01-28 22:35:25.000000000 +0100 @@ -42,8 +42,8 @@ """ __title__ = 'requests' -__version__ = '2.5.0' -__build__ = 0x020500 +__version__ = '2.5.1' +__build__ = 0x020501 __author__ = 'Kenneth Reitz' __license__ = 'Apache 2.0' __copyright__ = 'Copyright 2014 Kenneth Reitz' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/requests/auth.py new/pip-6.0.7/pip/_vendor/requests/auth.py --- old/pip-6.0.6/pip/_vendor/requests/auth.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/requests/auth.py 2015-01-28 22:35:25.000000000 +0100 @@ -67,6 +67,7 @@ self.nonce_count = 0 self.chal = {} self.pos = None + self.num_401_calls = 1 def build_digest_header(self, method, url): @@ -154,7 +155,7 @@ def handle_redirect(self, r, **kwargs): """Reset num_401_calls counter on redirects.""" if r.is_redirect: - setattr(self, 'num_401_calls', 1) + self.num_401_calls = 1 def handle_401(self, r, **kwargs): """Takes the given response and tries digest-auth, if needed.""" @@ -168,7 +169,7 @@ if 'digest' in s_auth.lower() and num_401_calls < 2: - setattr(self, 'num_401_calls', num_401_calls + 1) + self.num_401_calls += 1 pat = re.compile(r'digest ', flags=re.IGNORECASE) self.chal = parse_dict_header(pat.sub('', s_auth, count=1)) @@ -188,7 +189,7 @@ return _r - setattr(self, 'num_401_calls', num_401_calls + 1) + self.num_401_calls = 1 return r def __call__(self, r): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/requests/compat.py new/pip-6.0.7/pip/_vendor/requests/compat.py --- old/pip-6.0.6/pip/_vendor/requests/compat.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/requests/compat.py 2015-01-28 22:35:25.000000000 +0100 @@ -76,7 +76,7 @@ try: import simplejson as json except (ImportError, SyntaxError): - # simplejson does not support Python 3.2, it thows a SyntaxError + # simplejson does not support Python 3.2, it throws a SyntaxError # because of u'...' Unicode literals. import json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/requests/models.py new/pip-6.0.7/pip/_vendor/requests/models.py --- old/pip-6.0.6/pip/_vendor/requests/models.py 2015-01-03 10:32:01.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/requests/models.py 2015-01-28 22:35:25.000000000 +0100 @@ -20,11 +20,10 @@ from .packages.urllib3.filepost import encode_multipart_formdata from .packages.urllib3.util import parse_url from .packages.urllib3.exceptions import ( - DecodeError, ReadTimeoutError, ProtocolError) + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) from .exceptions import ( - HTTPError, RequestException, MissingSchema, InvalidURL, - ChunkedEncodingError, ContentDecodingError, ConnectionError, - StreamConsumedError) + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) from .utils import ( guess_filename, get_auth_from_url, requote_uri, stream_decode_response_unicode, to_key_val_list, parse_header_links, @@ -351,7 +350,10 @@ return # Support for unicode domain names and paths. - scheme, auth, host, port, path, query, fragment = parse_url(url) + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) if not scheme: raise MissingSchema("Invalid URL {0!r}: No schema supplied. " @@ -615,7 +617,7 @@ def ok(self): try: self.raise_for_status() - except RequestException: + except HTTPError: return False return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/requests/utils.py new/pip-6.0.7/pip/_vendor/requests/utils.py --- old/pip-6.0.6/pip/_vendor/requests/utils.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/requests/utils.py 2015-01-28 22:35:25.000000000 +0100 @@ -115,7 +115,7 @@ def guess_filename(obj): """Tries to guess the filename of the given object.""" name = getattr(obj, 'name', None) - if name and name[0] != '<' and name[-1] != '>': + if name and isinstance(name, builtin_str) and name[0] != '<' and name[-1] != '>': return os.path.basename(name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/six.py new/pip-6.0.7/pip/_vendor/six.py --- old/pip-6.0.6/pip/_vendor/six.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/six.py 2015-01-28 22:35:25.000000000 +0100 @@ -1,6 +1,6 @@ """Utilities for writing code that runs on Python 2 and 3""" -# Copyright (c) 2010-2014 Benjamin Peterson +# Copyright (c) 2010-2015 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,12 +23,13 @@ from __future__ import absolute_import import functools +import itertools import operator import sys import types __author__ = "Benjamin Peterson <[email protected]>" -__version__ = "1.8.0" +__version__ = "1.9.0" # Useful for very coarse version differentiation. @@ -88,8 +89,12 @@ def __get__(self, obj, tp): result = self._resolve() setattr(obj, self.name, result) # Invokes __set__. - # This is a bit ugly, but it avoids running this again. - delattr(obj.__class__, self.name) + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass return result @@ -554,6 +559,12 @@ def iterlists(d, **kw): return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") else: def iterkeys(d, **kw): return iter(d.iterkeys(**kw)) @@ -567,6 +578,12 @@ def iterlists(d, **kw): return iter(d.iterlists(**kw)) + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") _add_doc(iteritems, @@ -593,6 +610,9 @@ import io StringIO = io.StringIO BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" else: def b(s): return s @@ -605,14 +625,28 @@ return ord(bs[0]) def indexbytes(buf, i): return ord(buf[i]) - def iterbytes(buf): - return (ord(byte) for byte in buf) + iterbytes = functools.partial(itertools.imap, ord) import StringIO StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + if PY3: exec_ = getattr(moves.builtins, "exec") @@ -643,6 +677,21 @@ """) +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + print_ = getattr(moves.builtins, "print", None) if print_ is None: def print_(*args, **kwargs): @@ -697,6 +746,14 @@ write(sep) write(arg) write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() _add_doc(reraise, """Reraise an exception.""") @@ -704,7 +761,7 @@ def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): - f = functools.wraps(wrapped)(f) + f = functools.wraps(wrapped, assigned, updated)(f) f.__wrapped__ = wrapped return f return wrapper @@ -737,6 +794,25 @@ return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + # Complete the moves implementation. # This code is at the end of this module to speed up module loading. # Turn this module into a package. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/_vendor/vendor.txt new/pip-6.0.7/pip/_vendor/vendor.txt --- old/pip-6.0.6/pip/_vendor/vendor.txt 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/_vendor/vendor.txt 2015-01-28 22:35:25.000000000 +0100 @@ -1,10 +1,10 @@ distlib==0.2.0 html5lib==0.999 # See: https://github.com/html5lib/html5lib-python/issues/161 -six==1.8.0 -colorama==0.3.2 -requests==2.5.0 +six==1.9.0 +colorama==0.3.3 +requests==2.5.1 certifi==14.05.14 -CacheControl==0.10.7 +CacheControl==0.11.1 lockfile==0.10.2 progress==1.2 ipaddress==1.0.7 # Only needed on 2.6, 2.7, and 3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/commands/wheel.py new/pip-6.0.7/pip/commands/wheel.py --- old/pip-6.0.6/pip/commands/wheel.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/commands/wheel.py 2015-01-28 22:35:25.000000000 +0100 @@ -222,7 +222,7 @@ logger.error( "You must give at least one requirement to %s " "(see \"pip help %s\")", - self.name, + self.name, self.name, ) return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/download.py new/pip-6.0.7/pip/download.py --- old/pip-6.0.6/pip/download.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/download.py 2015-01-28 22:35:25.000000000 +0100 @@ -549,76 +549,75 @@ show_progress = False show_url = link.show_url - try: - def resp_read(chunk_size): - try: - # Special case for urllib3. - for chunk in resp.raw.stream( - chunk_size, - # We use decode_content=False here because we do - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = resp.raw.read(chunk_size) - if not chunk: - break - yield chunk - progress_indicator = lambda x, *a, **k: x - - if link.netloc == PyPI.netloc: - url = show_url - else: - url = link.url_without_fragment - - if show_progress: # We don't show progress on cached responses - if total_length: - logger.info( - "Downloading %s (%s)", url, format_size(total_length), - ) - progress_indicator = DownloadProgressBar( - max=total_length, - ).iter - else: - logger.info("Downloading %s", url) - progress_indicator = DownloadProgressSpinner().iter - elif cached_resp: - logger.info("Using cached %s", url) + def resp_read(chunk_size): + try: + # Special case for urllib3. + for chunk in resp.raw.stream( + chunk_size, + # We use decode_content=False here because we do + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = resp.raw.read(chunk_size) + if not chunk: + break + yield chunk + + progress_indicator = lambda x, *a, **k: x + + if link.netloc == PyPI.netloc: + url = show_url + else: + url = link.url_without_fragment + + if show_progress: # We don't show progress on cached responses + if total_length: + logger.info( + "Downloading %s (%s)", url, format_size(total_length), + ) + progress_indicator = DownloadProgressBar( + max=total_length, + ).iter else: logger.info("Downloading %s", url) - - logger.debug('Downloading from URL %s', link) - - for chunk in progress_indicator(resp_read(4096), 4096): - if download_hash is not None: - download_hash.update(chunk) - content_file.write(chunk) - finally: - if link.hash and link.hash_name: - _check_hash(download_hash, link) + progress_indicator = DownloadProgressSpinner().iter + elif cached_resp: + logger.info("Using cached %s", url) + else: + logger.info("Downloading %s", url) + + logger.debug('Downloading from URL %s', link) + + for chunk in progress_indicator(resp_read(4096), 4096): + if download_hash is not None: + download_hash.update(chunk) + content_file.write(chunk) + if link.hash and link.hash_name: + _check_hash(download_hash, link) return download_hash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/req/req_install.py new/pip-6.0.7/pip/req/req_install.py --- old/pip-6.0.6/pip/req/req_install.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/req/req_install.py 2015-01-28 22:35:25.000000000 +0100 @@ -557,33 +557,27 @@ dist = self.satisfied_by or self.conflicts_with paths_to_remove = UninstallPathSet(dist) - - pip_egg_info_path = os.path.join(dist.location, - dist.egg_name()) + '.egg-info' - dist_info_path = os.path.join(dist.location, - '-'.join(dist.egg_name().split('-')[:2]) - ) + '.dist-info' - # Workaround - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367 - debian_egg_info_path = pip_egg_info_path.replace( - '-py%s' % pkg_resources.PY_MAJOR, '') - easy_install_egg = dist.egg_name() + '.egg' develop_egg_link = egg_link_path(dist) - - pip_egg_info_exists = os.path.exists(pip_egg_info_path) - debian_egg_info_exists = os.path.exists(debian_egg_info_path) - dist_info_exists = os.path.exists(dist_info_path) - if pip_egg_info_exists or debian_egg_info_exists: - # package installed by pip - if pip_egg_info_exists: - egg_info_path = pip_egg_info_path - else: - egg_info_path = debian_egg_info_path - paths_to_remove.add(egg_info_path) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + if develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link %s does not match installed location of %s ' + '(at %s)' % (link_pointer, self.name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + elif egg_info_exists and dist.egg_info.endswith('.egg-info'): + paths_to_remove.add(dist.egg_info) if dist.has_metadata('installed-files.txt'): for installed_file in dist.get_metadata( 'installed-files.txt').splitlines(): path = os.path.normpath( - os.path.join(egg_info_path, installed_file) + os.path.join(dist.egg_info, installed_file) ) paths_to_remove.add(path) # FIXME: need a test for this elif block @@ -603,28 +597,23 @@ paths_to_remove.add(path + '.py') paths_to_remove.add(path + '.pyc') - elif dist.location.endswith(easy_install_egg): + elif dist.location.endswith('.egg'): # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] easy_install_pth = os.path.join(os.path.dirname(dist.location), 'easy-install.pth') paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) - elif develop_egg_link: - # develop egg - with open(develop_egg_link, 'r') as fh: - link_pointer = os.path.normcase(fh.readline().strip()) - assert (link_pointer == dist.location), ( - 'Egg-link %s does not match installed location of %s ' - '(at %s)' % (link_pointer, self.name, dist.location) - ) - paths_to_remove.add(develop_egg_link) - easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), - 'easy-install.pth') - paths_to_remove.add_pth(easy_install_pth, dist.location) - elif dist_info_exists: + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): for path in pip.wheel.uninstallation_paths(dist): paths_to_remove.add(path) + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location) # find distutils scripts= scripts if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/utils/build.py new/pip-6.0.7/pip/utils/build.py --- old/pip-6.0.6/pip/utils/build.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/utils/build.py 2015-01-28 22:35:25.000000000 +0100 @@ -1,5 +1,6 @@ from __future__ import absolute_import +import os.path import tempfile from pip.utils import rmtree @@ -14,7 +15,11 @@ delete = True if name is None: - name = tempfile.mkdtemp(prefix="pip-build-") + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + name = os.path.realpath(tempfile.mkdtemp(prefix="pip-build-")) # If we were not given an explicit directory, and we were not given # an explicit delete option, then we'll default to deleting. if delete is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip/utils/outdated.py new/pip-6.0.7/pip/utils/outdated.py --- old/pip-6.0.6/pip/utils/outdated.py 2015-01-03 10:32:02.000000000 +0100 +++ new/pip-6.0.7/pip/utils/outdated.py 2015-01-28 22:35:25.000000000 +0100 @@ -73,8 +73,11 @@ # Attempt to write out our version check file with lockfile.LockFile(self.statefile_path): - with open(self.statefile_path) as statefile: - state = json.load(statefile) + if os.path.exists(self.statefile_path): + with open(self.statefile_path) as statefile: + state = json.load(statefile) + else: + state = {} state[sys.prefix] = { "last_check": current_time.strftime(SELFCHECK_DATE_FMT), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip.egg-info/PKG-INFO new/pip-6.0.7/pip.egg-info/PKG-INFO --- old/pip-6.0.6/pip.egg-info/PKG-INFO 2015-01-03 10:32:20.000000000 +0100 +++ new/pip-6.0.7/pip.egg-info/PKG-INFO 2015-01-28 22:35:31.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pip -Version: 6.0.6 +Version: 6.0.7 Summary: The PyPA recommended tool for installing Python packages. Home-page: https://pip.pypa.io/ Author: The pip developers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pip-6.0.6/pip.egg-info/pbr.json new/pip-6.0.7/pip.egg-info/pbr.json --- old/pip-6.0.6/pip.egg-info/pbr.json 2015-01-03 10:32:20.000000000 +0100 +++ new/pip-6.0.7/pip.egg-info/pbr.json 2015-01-28 22:35:31.000000000 +0100 @@ -1 +1 @@ -{"git_version": "a898b9b", "is_release": true} \ No newline at end of file +{"git_version": "2a96914", "is_release": true} \ No newline at end of file -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
