From e9de3e0245a0200b5a50e9ebdc374bfbcbe29936 Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Mon, 6 Feb 2012 22:59:30 -0800 Subject: [PATCH 001/181] Junit output --- tox.ini | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tox.ini b/tox.ini index 2d6fef2..69132e5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,7 @@ [tox] -envlist = py25,py27 -[testenv] -deps=nose -commands= - nosetests {posargs} - +envlist = py26,py27 +[testenv] +changedir=tests +deps=pytest +commands=py.test --junitxml=junit-{envname}.xml From 106e4faaf820e9e2ea3eadfe309b1d94931fcfc0 Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Mon, 6 Feb 2012 23:03:54 -0800 Subject: [PATCH 002/181] Removed test --- setup.py | 5 +---- tests/test_yolk_cli.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index ae1e9d9..2e08c6b 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python from setuptools import setup @@ -24,10 +24,7 @@ "Topic :: Software Development :: Libraries :: Python Modules", ], install_requires=["setuptools"], - tests_require=["nose"], packages=['yolk', 'yolk.plugins'], package_dir={'yolk':'yolk'}, entry_points={'console_scripts': ['yolk = yolk.cli:main',]}, - test_suite = 'nose.collector', ) - diff --git a/tests/test_yolk_cli.py b/tests/test_yolk_cli.py index 7c8d545..f4b5d3d 100644 --- a/tests/test_yolk_cli.py +++ b/tests/test_yolk_cli.py @@ -1,4 +1,4 @@ -from nose import SkipTest + class TestStdOut: def test_object_initialization(self): From 2e41dca7e67dd61f93fbec3da7a1b7d0b09cb8d8 Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Tue, 7 Feb 2012 09:12:02 -0800 Subject: [PATCH 003/181] Change python versions --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 69132e5..3f37c52 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27 +envlist = py26,py31 [testenv] changedir=tests From 384e86e11fe71589a9b6a53bfffc7c0992f13743 Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Mon, 12 Mar 2012 17:21:30 -0700 Subject: [PATCH 004/181] Add new interpreters --- tox.ini | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 3f37c52..da0c6d1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,21 @@ [tox] -envlist = py26,py31 - +envlist = py267,py271,py272,py321 [testenv] changedir=tests deps=pytest commands=py.test --junitxml=junit-{envname}.xml + +[testenv:py321] +basepython=/var/lib/jenkins/.pythonbrew/pythons/Python-3.2.1/bin/python3.2 + + +[testenv:py272] +basepython=/var/lib/jenkins/.pythonbrew/pythons/Python-2.7.2/bin/python2.7 + +[testenv:py271] +basepython=/var/lib/jenkins/.pythonbrew/pythons/Python-2.7.1/bin/python2.7 + +[testenv:py267] +basepython=/var/lib/jenkins/.pythonbrew/pythons/Python-2.6.7/bin/python2.6 + + From 6f83b692fa46a98945ad7e7be311a557b00793e1 Mon Sep 17 00:00:00 2001 From: Thibault Kruse Date: Tue, 3 Apr 2012 13:33:08 -0700 Subject: [PATCH 005/181] typo --- yolk/pypi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yolk/pypi.py b/yolk/pypi.py index 2c8f71d..cf6e6e0 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -223,7 +223,7 @@ def package_releases(self, package_name): return self.xmlrpc.package_releases(package_name) def get_download_urls(self, package_name, version="", pkg_type="all"): - """Query PyPI for pkg download URI for a packge""" + """Query PyPI for pkg download URI for a package""" if version: versions = [version] From 1d46b5a7e546fb5a5628f25a681862b9d0e8d51a Mon Sep 17 00:00:00 2001 From: Thibault Kruse Date: Tue, 3 Apr 2012 13:36:46 -0700 Subject: [PATCH 006/181] Actually sort versions --- tests/test_yolk_cli.py | 7 +++++++ yolk/yolklib.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_yolk_cli.py b/tests/test_yolk_cli.py index 7f217a9..98009b5 100644 --- a/tests/test_yolk_cli.py +++ b/tests/test_yolk_cli.py @@ -1,3 +1,6 @@ +import unittest + +import yolk.yolklib class TestStdOut: def test_object_initialization(self): @@ -107,3 +110,7 @@ class TestMain: def test_main(self): pass # TODO: implement your test here +class TestYolkLib (unittest.TestCase): + def test_get_highest_version(self): + versions = ['2.2', '3.0.5', '1.3', '3.1.2', '1.3.4', '0.3', '3.1.1', '1.2.4'] + self.assertEqual('3.1.2', yolk.yolklib.get_highest_version(versions)) diff --git a/yolk/yolklib.py b/yolk/yolklib.py index 754515f..9d7d903 100755 --- a/yolk/yolklib.py +++ b/yolk/yolklib.py @@ -166,7 +166,7 @@ def get_highest_version(versions): sorted_versions = [] for ver in versions: sorted_versions.append((pkg_resources.parse_version(ver), ver)) - + sorted_versions = sorted(sorted_versions) sorted_versions.reverse() return sorted_versions[0][1] From 018b6cf87e1be2bdb0ac33d8539c2a244de3dd53 Mon Sep 17 00:00:00 2001 From: Thibault Kruse Date: Tue, 3 Apr 2012 14:01:18 -0700 Subject: [PATCH 007/181] parallel search for upgradeable --- yolk/cli.py | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/yolk/cli.py b/yolk/cli.py index fccc2c5..5b77032 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -240,27 +240,41 @@ def show_updates(self): #Check for every installed package pkg_list = get_pkglist() found = None - for pkg in pkg_list: + + from multiprocessing import Process, Manager + manager = Manager() + def worker_function(pkg, result_list, index): for (dist, active) in dists.get_distributions("all", pkg, dists.get_highest_installed(pkg)): (project_name, versions) = \ self.pypi.query_versions_pypi(dist.project_name) - if versions: - - #PyPI returns them in chronological order, - #but who knows if its guaranteed in the API? - #Make sure we grab the highest version: - - newest = get_highest_version(versions) - if newest != dist.version: - - #We may have newer than what PyPI knows about - - if pkg_resources.parse_version(dist.version) < \ - pkg_resources.parse_version(newest): - found = True - print " %s %s (%s)" % (project_name, dist.version, - newest) + result_list[index] = (pkg, dist, project_name, versions) + + outputs = manager.list([None for _ in pkg_list]) + workers = [] + for index, pkg in enumerate(pkg_list): + p = Process(target = worker_function, args=(pkg, outputs, index)) + p.start() + workers.append(p) + for process in workers: + process.join() + for (pkg, dist, project_name, versions) in outputs: + if versions: + + #PyPI returns them in chronological order, + #but who knows if its guaranteed in the API? + #Make sure we grab the highest version: + + newest = get_highest_version(versions) + if newest != dist.version: + + #We may have newer than what PyPI knows about + + if pkg_resources.parse_version(dist.version) < \ + pkg_resources.parse_version(newest): + found = True + print " %s %s (%s)" % (project_name, dist.version, + newest) if not found and self.project_name: self.logger.info("You have the latest version installed.") elif not found: From 518893aee24b75ab7e1562a6faaafddd26b01de4 Mon Sep 17 00:00:00 2001 From: Thibault Kruse Date: Fri, 6 Apr 2012 16:22:09 -0700 Subject: [PATCH 008/181] prevent error on missing egg-file --- yolk/metadata.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/yolk/metadata.py b/yolk/metadata.py index 3690bae..5019608 100644 --- a/yolk/metadata.py +++ b/yolk/metadata.py @@ -35,9 +35,12 @@ def get_metadata(dist): if not dist.has_metadata('PKG-INFO'): return - msg = email.message_from_string(dist.get_metadata('PKG-INFO')) - metadata = {} - for header in [l for l in msg._headers]: - metadata[header[0]] = header[1] - + try: + metadata = {} + msg = email.message_from_string(dist.get_metadata('PKG-INFO')) + for header in [l for l in msg._headers]: + metadata[header[0]] = header[1] + except IOError as e: + # no egg-file, installed using other package manager + pass return metadata From 8dd30666fa68c5c4fb7be463712afc8e805aff5e Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Tue, 1 May 2012 17:52:39 -0700 Subject: [PATCH 009/181] Issue #3. Thanks David Bennett for python2.7 addinfourl fix --- yolk/pypi.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/yolk/pypi.py b/yolk/pypi.py index 2c8f71d..c998c9e 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -23,13 +23,34 @@ import time import logging import urllib2 +import urllib from yolk.utils import get_yolk_dir XML_RPC_SERVER = 'http://pypi.python.org/pypi' -#XML_RPC_SERVER = 'http://download.zope.org/ppix/' -#XML_RPC_SERVER = 'http://cheeseshop.python.org/simple' + +class addinfourl(urllib2.addinfourl): + """ + Replacement addinfourl class compatible with python-2.7's xmlrpclib + + In python-2.7, xmlrpclib expects that the response object that it receives + has a getheader method. httplib.HTTPResponse provides this but + urllib2.addinfourl does not. Add the necessary functions here, ported to + use the internal data structures of addinfourl. + """ + + def getheader(self, name, default=None): + if self.headers is None: + raise httplib.ResponseNotReady() + return self.headers.getheader(name, default) + + def getheaders(self): + if self.headers is None: + raise httplib.ResponseNotReady() + return self.headers.items() + +urllib2.addinfourl = addinfourl class ProxyTransport(xmlrpclib.Transport): From 5a6e53251b2236d44998cb639ee12257a05c50a9 Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Wed, 2 May 2012 07:29:48 -0700 Subject: [PATCH 010/181] Issue 4 thanks Omer Katz, new style classes --- yolk/pypi.py | 2 +- yolk/yolklib.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yolk/pypi.py b/yolk/pypi.py index c998c9e..207f80d 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -111,7 +111,7 @@ def check_proxy_setting(): return -class CheeseShop: +class CheeseShop(object): """Interface to Python Package Index""" diff --git a/yolk/yolklib.py b/yolk/yolklib.py index 754515f..0678034 100755 --- a/yolk/yolklib.py +++ b/yolk/yolklib.py @@ -21,7 +21,7 @@ -class Distributions: +class Distributions(object): """Helper class for pkg_resources""" From eec5ab8076711f2228a3e186536d372b39db0c60 Mon Sep 17 00:00:00 2001 From: Michele BOLOGNA Date: Sun, 21 Oct 2012 15:06:28 +0200 Subject: [PATCH 011/181] Added support for python3, while maintaining compatibility with python2 --- yolk/cli.py | 73 ++++++++++++++++++++------------------ yolk/plugins/__init__.py | 2 +- yolk/pypi.py | 12 +++++-- yolk/setuptools_support.py | 2 +- yolk/utils.py | 2 +- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/yolk/cli.py b/yolk/cli.py index fccc2c5..5d41155 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -29,11 +29,16 @@ import pkg_resources import webbrowser import logging -from xmlrpclib import Fault as XMLRPCFault +import platform +if platform.python_version().startswith('2'): + from xmlrpclib import Fault as XMLRPCFault + from urllib import urlretrieve + from urlparse import urlparse +else: + from xmlrpc.client import Fault as XMLRPCFault + from urllib.request import urlretrieve + from urllib.parse import urlparse from distutils.sysconfig import get_python_lib -from urllib import urlretrieve -from urlparse import urlparse - from yolk.metadata import get_metadata from yolk.yolklib import get_highest_version, Distributions from yolk.pypi import CheeseShop @@ -259,8 +264,8 @@ def show_updates(self): if pkg_resources.parse_version(dist.version) < \ pkg_resources.parse_version(newest): found = True - print " %s %s (%s)" % (project_name, dist.version, - newest) + print(" %s %s (%s)" % (project_name, dist.version, + newest)) if not found and self.project_name: self.logger.info("You have the latest version installed.") elif not found: @@ -313,7 +318,7 @@ def show_distributions(self, show): add_column_text += my_plugin.add_column(dist) + " " self.print_metadata(metadata, develop, active, add_column_text) else: - print str(dist) + " has no metadata" + print(str(dist) + " has no metadata") results = True if not results and self.project_name: if self.version: @@ -329,8 +334,8 @@ def show_distributions(self, show): (show, pkg_spec)) return 2 elif show == "all" and results and self.options.fields: - print "Versions with '*' are non-active." - print "Versions with '!' are deployed in development mode." + print("Versions with '*' are non-active.") + print("Versions with '!' are deployed in development mode.") def print_metadata(self, metadata, develop, active, installed_by): @@ -380,24 +385,24 @@ def print_metadata(self, metadata, develop, active, installed_by): development_status = installed_by status = "%s %s" % (active_status, development_status) if fields: - print '%s (%s)%s %s' % (metadata['Name'], version, active_status, - development_status) + print('%s (%s)%s %s' % (metadata['Name'], version, active_status, + development_status)) else: # Need intelligent justification - print metadata['Name'].ljust(15) + " - " + version.ljust(12) + \ - " - " + status + print(metadata['Name'].ljust(15) + " - " + version.ljust(12) + \ + " - " + status) if fields: #Only show specific fields, using case-insensitive search fields = map(str.lower, fields) for field in metadata.keys(): if field.lower() in fields: - print ' %s: %s' % (field, metadata[field]) - print + print(' %s: %s' % (field, metadata[field])) + print() elif show_metadata: #Print all available metadata fields for field in metadata.keys(): if field != 'Name' and field != 'Summary': - print ' %s: %s' % (field, metadata[field]) + print(' %s: %s' % (field, metadata[field])) def show_deps(self): """ @@ -410,7 +415,7 @@ def show_deps(self): for pkg in pkgs[self.project_name]: if not self.version: - print pkg.project_name, pkg.version + print(pkg.project_name, pkg.version) i = len(pkg._dep_map.values()[0]) if i: @@ -418,8 +423,8 @@ def show_deps(self): if not self.version or self.version and \ pkg.version == self.version: if self.version and i == len(pkg._dep_map.values()[0]): - print pkg.project_name, pkg.version - print " " + str(pkg._dep_map.values()[0][i - 1]) + print(pkg.project_name, pkg.version) + print(" " + str(pkg._dep_map.values()[0][i - 1])) i -= 1 else: self.logger.info(\ @@ -441,7 +446,7 @@ def show_pypi_changelog(self): try: changelog = self.pypi.changelog(int(hours)) - except XMLRPCFault, err_msg: + except XMLRPCFault as err_msg: self.logger.error(err_msg) self.logger.error("ERROR: Couldn't retrieve changelog.") return 1 @@ -450,10 +455,10 @@ def show_pypi_changelog(self): for entry in changelog: pkg = entry[0] if pkg != last_pkg: - print "%s %s\n\t%s" % (entry[0], entry[1], entry[3]) + print("%s %s\n\t%s" % (entry[0], entry[1], entry[3])) last_pkg = pkg else: - print "\t%s" % entry[3] + print("\t%s" % entry[3]) return 0 @@ -471,13 +476,13 @@ def show_pypi_releases(self): return 1 try: latest_releases = self.pypi.updated_releases(hours) - except XMLRPCFault, err_msg: + except XMLRPCFault as err_msg: self.logger.error(err_msg) self.logger.error("ERROR: Couldn't retrieve latest releases.") return 1 for release in latest_releases: - print "%s %s" % (release[0], release[1]) + print("%s %s" % (release[0], release[1])) return 0 def show_download_links(self): @@ -536,7 +541,7 @@ def print_download_uri(self, version, source): url = get_download_uri(self.project_name, version, source, self.options.pypi_index) if url: - print "%s" % url + print("%s" % url) else: self.logger.info("No download URL found for %s" % pkg_type) @@ -596,7 +601,7 @@ def fetch_uri(self, directory, uri): try: downloaded_filename, headers = urlretrieve(uri, filename) self.logger.info("Downloaded ./" + filename) - except IOError, err_msg: + except IOError as err_msg: self.logger.error("Error downloading package %s from URL %s" \ % (filename, uri)) self.logger.error(str(err_msg)) @@ -635,7 +640,7 @@ def fetch_svn(self, svn_uri, directory): return 1 try: os.mkdir(directory) - except OSError, err_msg: + except OSError as err_msg: self.logger.error("ERROR: " + str(err_msg)) return 1 cwd = os.path.realpath(os.curdir) @@ -693,7 +698,7 @@ def query_metadata_pypi(self): for key in metadata.keys(): if not self.options.fields or (self.options.fields and \ self.options.fields==key): - print "%s: %s" % (key, metadata[key]) + print("%s: %s" % (key, metadata[key])) return 0 def versions_available(self): @@ -816,10 +821,10 @@ def pypi_search(self): summary = pkg['summary'].encode('utf-8') else: summary = "" - print """%s (%s): + print("""%s (%s): %s """ % (pkg['name'].encode('utf-8'), pkg["version"], - summary) + summary)) return 0 def show_entry_map(self): @@ -855,10 +860,10 @@ def show_entry_points(self): found = True try: plugin = entry_point.load() - print plugin.__module__ - print " %s" % entry_point + print(plugin.__module__) + print(" %s" % entry_point) if plugin.__doc__: - print plugin.__doc__ + print(plugin.__doc__) print except ImportError: pass @@ -1059,7 +1064,7 @@ def print_pkg_versions(project_name, versions): """ for ver in versions: - print "%s %s" % (project_name, ver) + print("%s %s" % (project_name, ver)) def validate_pypi_opts(opt_parser): """ diff --git a/yolk/plugins/__init__.py b/yolk/plugins/__init__.py index cad9fbb..827ed04 100644 --- a/yolk/plugins/__init__.py +++ b/yolk/plugins/__init__.py @@ -95,7 +95,7 @@ def load_plugins(builtin=True, others=True): plugin = entry_point.load() except KeyboardInterrupt: raise - except Exception, err_msg: + except Exception as err_msg: # never want a plugin load to exit yolk # but we can't log here because the logger is not yet # configured diff --git a/yolk/pypi.py b/yolk/pypi.py index 207f80d..3ba3ba0 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -17,12 +17,18 @@ __docformat__ = 'restructuredtext' import re -import xmlrpclib -import cPickle +import platform +if platform.python_version().startswith('2'): + import xmlrpclib + import cPickle + import urllib2 +else: + import xmlrpc.client as xmlrpclib + import pickle + import urllib.request as urllib2 import os import time import logging -import urllib2 import urllib from yolk.utils import get_yolk_dir diff --git a/yolk/setuptools_support.py b/yolk/setuptools_support.py index c5811da..527c822 100644 --- a/yolk/setuptools_support.py +++ b/yolk/setuptools_support.py @@ -69,7 +69,7 @@ def get_download_uri(package_name, version, source, index_url=None): try: pkg_index.fetch_distribution(req, tmpdir, force_scan, source, develop_ok) - except DownloadURI, url: + except DownloadURI as url: #Remove #egg=pkg-dev clean_url = url.value.split("#")[0] #If setuptools is asked for an egg and there isn't one, it will diff --git a/yolk/utils.py b/yolk/utils.py index 0ac3aad..3b40ccf 100644 --- a/yolk/utils.py +++ b/yolk/utils.py @@ -37,7 +37,7 @@ def run_command(cmd, env=None, max_timeout=None): output = os.tmpfile() try: pipe = Popen(arglist, stdout=output, stderr=STDOUT, env=env) - except Exception, errmsg: + except Exception as errmsg: return 1, errmsg # Wait only max_timeout seconds. From 1df2e0dc217b304889235b0730830edfe3166249 Mon Sep 17 00:00:00 2001 From: Michele BOLOGNA Date: Sun, 21 Oct 2012 15:06:28 +0200 Subject: [PATCH 012/181] Added support for python3, while maintaining compatibility with python2 --- yolk/cli.py | 73 ++++++++++++++++++++------------------ yolk/plugins/__init__.py | 2 +- yolk/pypi.py | 12 +++++-- yolk/setuptools_support.py | 2 +- yolk/utils.py | 2 +- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/yolk/cli.py b/yolk/cli.py index fccc2c5..5d41155 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -29,11 +29,16 @@ import pkg_resources import webbrowser import logging -from xmlrpclib import Fault as XMLRPCFault +import platform +if platform.python_version().startswith('2'): + from xmlrpclib import Fault as XMLRPCFault + from urllib import urlretrieve + from urlparse import urlparse +else: + from xmlrpc.client import Fault as XMLRPCFault + from urllib.request import urlretrieve + from urllib.parse import urlparse from distutils.sysconfig import get_python_lib -from urllib import urlretrieve -from urlparse import urlparse - from yolk.metadata import get_metadata from yolk.yolklib import get_highest_version, Distributions from yolk.pypi import CheeseShop @@ -259,8 +264,8 @@ def show_updates(self): if pkg_resources.parse_version(dist.version) < \ pkg_resources.parse_version(newest): found = True - print " %s %s (%s)" % (project_name, dist.version, - newest) + print(" %s %s (%s)" % (project_name, dist.version, + newest)) if not found and self.project_name: self.logger.info("You have the latest version installed.") elif not found: @@ -313,7 +318,7 @@ def show_distributions(self, show): add_column_text += my_plugin.add_column(dist) + " " self.print_metadata(metadata, develop, active, add_column_text) else: - print str(dist) + " has no metadata" + print(str(dist) + " has no metadata") results = True if not results and self.project_name: if self.version: @@ -329,8 +334,8 @@ def show_distributions(self, show): (show, pkg_spec)) return 2 elif show == "all" and results and self.options.fields: - print "Versions with '*' are non-active." - print "Versions with '!' are deployed in development mode." + print("Versions with '*' are non-active.") + print("Versions with '!' are deployed in development mode.") def print_metadata(self, metadata, develop, active, installed_by): @@ -380,24 +385,24 @@ def print_metadata(self, metadata, develop, active, installed_by): development_status = installed_by status = "%s %s" % (active_status, development_status) if fields: - print '%s (%s)%s %s' % (metadata['Name'], version, active_status, - development_status) + print('%s (%s)%s %s' % (metadata['Name'], version, active_status, + development_status)) else: # Need intelligent justification - print metadata['Name'].ljust(15) + " - " + version.ljust(12) + \ - " - " + status + print(metadata['Name'].ljust(15) + " - " + version.ljust(12) + \ + " - " + status) if fields: #Only show specific fields, using case-insensitive search fields = map(str.lower, fields) for field in metadata.keys(): if field.lower() in fields: - print ' %s: %s' % (field, metadata[field]) - print + print(' %s: %s' % (field, metadata[field])) + print() elif show_metadata: #Print all available metadata fields for field in metadata.keys(): if field != 'Name' and field != 'Summary': - print ' %s: %s' % (field, metadata[field]) + print(' %s: %s' % (field, metadata[field])) def show_deps(self): """ @@ -410,7 +415,7 @@ def show_deps(self): for pkg in pkgs[self.project_name]: if not self.version: - print pkg.project_name, pkg.version + print(pkg.project_name, pkg.version) i = len(pkg._dep_map.values()[0]) if i: @@ -418,8 +423,8 @@ def show_deps(self): if not self.version or self.version and \ pkg.version == self.version: if self.version and i == len(pkg._dep_map.values()[0]): - print pkg.project_name, pkg.version - print " " + str(pkg._dep_map.values()[0][i - 1]) + print(pkg.project_name, pkg.version) + print(" " + str(pkg._dep_map.values()[0][i - 1])) i -= 1 else: self.logger.info(\ @@ -441,7 +446,7 @@ def show_pypi_changelog(self): try: changelog = self.pypi.changelog(int(hours)) - except XMLRPCFault, err_msg: + except XMLRPCFault as err_msg: self.logger.error(err_msg) self.logger.error("ERROR: Couldn't retrieve changelog.") return 1 @@ -450,10 +455,10 @@ def show_pypi_changelog(self): for entry in changelog: pkg = entry[0] if pkg != last_pkg: - print "%s %s\n\t%s" % (entry[0], entry[1], entry[3]) + print("%s %s\n\t%s" % (entry[0], entry[1], entry[3])) last_pkg = pkg else: - print "\t%s" % entry[3] + print("\t%s" % entry[3]) return 0 @@ -471,13 +476,13 @@ def show_pypi_releases(self): return 1 try: latest_releases = self.pypi.updated_releases(hours) - except XMLRPCFault, err_msg: + except XMLRPCFault as err_msg: self.logger.error(err_msg) self.logger.error("ERROR: Couldn't retrieve latest releases.") return 1 for release in latest_releases: - print "%s %s" % (release[0], release[1]) + print("%s %s" % (release[0], release[1])) return 0 def show_download_links(self): @@ -536,7 +541,7 @@ def print_download_uri(self, version, source): url = get_download_uri(self.project_name, version, source, self.options.pypi_index) if url: - print "%s" % url + print("%s" % url) else: self.logger.info("No download URL found for %s" % pkg_type) @@ -596,7 +601,7 @@ def fetch_uri(self, directory, uri): try: downloaded_filename, headers = urlretrieve(uri, filename) self.logger.info("Downloaded ./" + filename) - except IOError, err_msg: + except IOError as err_msg: self.logger.error("Error downloading package %s from URL %s" \ % (filename, uri)) self.logger.error(str(err_msg)) @@ -635,7 +640,7 @@ def fetch_svn(self, svn_uri, directory): return 1 try: os.mkdir(directory) - except OSError, err_msg: + except OSError as err_msg: self.logger.error("ERROR: " + str(err_msg)) return 1 cwd = os.path.realpath(os.curdir) @@ -693,7 +698,7 @@ def query_metadata_pypi(self): for key in metadata.keys(): if not self.options.fields or (self.options.fields and \ self.options.fields==key): - print "%s: %s" % (key, metadata[key]) + print("%s: %s" % (key, metadata[key])) return 0 def versions_available(self): @@ -816,10 +821,10 @@ def pypi_search(self): summary = pkg['summary'].encode('utf-8') else: summary = "" - print """%s (%s): + print("""%s (%s): %s """ % (pkg['name'].encode('utf-8'), pkg["version"], - summary) + summary)) return 0 def show_entry_map(self): @@ -855,10 +860,10 @@ def show_entry_points(self): found = True try: plugin = entry_point.load() - print plugin.__module__ - print " %s" % entry_point + print(plugin.__module__) + print(" %s" % entry_point) if plugin.__doc__: - print plugin.__doc__ + print(plugin.__doc__) print except ImportError: pass @@ -1059,7 +1064,7 @@ def print_pkg_versions(project_name, versions): """ for ver in versions: - print "%s %s" % (project_name, ver) + print("%s %s" % (project_name, ver)) def validate_pypi_opts(opt_parser): """ diff --git a/yolk/plugins/__init__.py b/yolk/plugins/__init__.py index cad9fbb..827ed04 100644 --- a/yolk/plugins/__init__.py +++ b/yolk/plugins/__init__.py @@ -95,7 +95,7 @@ def load_plugins(builtin=True, others=True): plugin = entry_point.load() except KeyboardInterrupt: raise - except Exception, err_msg: + except Exception as err_msg: # never want a plugin load to exit yolk # but we can't log here because the logger is not yet # configured diff --git a/yolk/pypi.py b/yolk/pypi.py index 207f80d..3ba3ba0 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -17,12 +17,18 @@ __docformat__ = 'restructuredtext' import re -import xmlrpclib -import cPickle +import platform +if platform.python_version().startswith('2'): + import xmlrpclib + import cPickle + import urllib2 +else: + import xmlrpc.client as xmlrpclib + import pickle + import urllib.request as urllib2 import os import time import logging -import urllib2 import urllib from yolk.utils import get_yolk_dir diff --git a/yolk/setuptools_support.py b/yolk/setuptools_support.py index c5811da..527c822 100644 --- a/yolk/setuptools_support.py +++ b/yolk/setuptools_support.py @@ -69,7 +69,7 @@ def get_download_uri(package_name, version, source, index_url=None): try: pkg_index.fetch_distribution(req, tmpdir, force_scan, source, develop_ok) - except DownloadURI, url: + except DownloadURI as url: #Remove #egg=pkg-dev clean_url = url.value.split("#")[0] #If setuptools is asked for an egg and there isn't one, it will diff --git a/yolk/utils.py b/yolk/utils.py index 0ac3aad..3b40ccf 100644 --- a/yolk/utils.py +++ b/yolk/utils.py @@ -37,7 +37,7 @@ def run_command(cmd, env=None, max_timeout=None): output = os.tmpfile() try: pipe = Popen(arglist, stdout=output, stderr=STDOUT, env=env) - except Exception, errmsg: + except Exception as errmsg: return 1, errmsg # Wait only max_timeout seconds. From 1b5117943ea0620f0d635907f9de9dc895ef2b6e Mon Sep 17 00:00:00 2001 From: Rob Cakebread Date: Sat, 3 Nov 2012 12:32:23 -0700 Subject: [PATCH 013/181] Fix stdout warning in python 3.2 --- yolk/cli.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/yolk/cli.py b/yolk/cli.py index 5d41155..f7354c6 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -66,6 +66,12 @@ def __getattr__(self, attribute): return getattr(self.stdout, attribute) return self.__dict__[attribute] + def flush(self): + """Bug workaround for Python 3.2+: + Exception AttributeError: 'flush' in Date: Sat, 3 Nov 2012 13:43:30 -0700 Subject: [PATCH 014/181] Fixes #7 -U - Thanks mordillo123 --- tests/test_yolk_cli.py | 11 ++++++++++- yolk/yolklib.py | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_yolk_cli.py b/tests/test_yolk_cli.py index f4b5d3d..64f9447 100644 --- a/tests/test_yolk_cli.py +++ b/tests/test_yolk_cli.py @@ -1,3 +1,7 @@ +import unittest + +import yolk.yolklib + class TestStdOut: @@ -107,4 +111,9 @@ def test_validate_pypi_opts(self): class TestMain: def test_main(self): pass # TODO: implement your test here - + + +class TestYolkLib (unittest.TestCase): + def test_get_highest_version(self): + versions = ['2.2', '3.0.5', '1.3', '3.1.2', '1.3.4', '0.3', '3.1.1', '1.2.4'] + self.assertEqual('3.1.2', yolk.yolklib.get_highest_version(versions)) diff --git a/yolk/yolklib.py b/yolk/yolklib.py index 0678034..5a0a695 100755 --- a/yolk/yolklib.py +++ b/yolk/yolklib.py @@ -167,6 +167,7 @@ def get_highest_version(versions): for ver in versions: sorted_versions.append((pkg_resources.parse_version(ver), ver)) + sorted_versions = sorted(sorted_versions) sorted_versions.reverse() return sorted_versions[0][1] From b3ca516ddc6c9d3b96143ae09427a3fd6ec57a47 Mon Sep 17 00:00:00 2001 From: myint Date: Sun, 11 Nov 2012 08:49:37 -0800 Subject: [PATCH 015/181] Add more Python 3 compatibility --- yolk/cli.py | 6 +++--- yolk/pypi.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/yolk/cli.py b/yolk/cli.py index f7354c6..39051e9 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -62,7 +62,7 @@ def __init__(self, stream, modulenames): self.modulenames = modulenames def __getattr__(self, attribute): - if not self.__dict__.has_key(attribute) or attribute == '__doc__': + if attribute not in self.__dict__ or attribute == '__doc__': return getattr(self.stdout, attribute) return self.__dict__[attribute] @@ -613,7 +613,7 @@ def fetch_uri(self, directory, uri): self.logger.error(str(err_msg)) return 1 - if headers.gettype() in ["text/html"]: + if "text/html" in headers: dfile = open(downloaded_filename) if re.search("404 Not Found", "".join(dfile.readlines())): dfile.close() @@ -672,7 +672,7 @@ def browse_website(self, browser=None): metadata = self.pypi.release_data(self.project_name, \ self.all_versions[0]) self.logger.debug("DEBUG: browser: %s" % browser) - if metadata.has_key("home_page"): + if "home_page" in metadata: self.logger.info("Launching browser: %s" \ % metadata["home_page"]) if browser == 'konqueror': diff --git a/yolk/pypi.py b/yolk/pypi.py index 3ba3ba0..f01d53f 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -20,7 +20,7 @@ import platform if platform.python_version().startswith('2'): import xmlrpclib - import cPickle + import cPickle as pickle import urllib2 else: import xmlrpc.client as xmlrpclib @@ -164,7 +164,7 @@ def get_xmlrpc_server(self): Returns PyPI's XML-RPC server instance """ check_proxy_setting() - if os.environ.has_key('XMLRPC_DEBUG'): + if 'XMLRPC_DEBUG' in os.environ: debug = 1 else: debug = 0 @@ -203,13 +203,13 @@ def query_cached_package_list(self): """Return list of pickled package names from PYPI""" if self.debug: self.logger.debug("DEBUG: reading pickled cache file") - return cPickle.load(open(self.pkg_cache_file, "r")) + return pickle.load(open(self.pkg_cache_file, "rb")) def fetch_pkg_list(self): """Fetch and cache master list of package names from PYPI""" self.logger.debug("DEBUG: Fetching package name list from PyPI") package_list = self.list_packages() - cPickle.dump(package_list, open(self.pkg_cache_file, "w")) + pickle.dump(package_list, open(self.pkg_cache_file, "wb")) self.pkg_list = package_list def search(self, spec, operator): @@ -275,7 +275,7 @@ def get_download_urls(self, package_name, version="", pkg_type="all"): #Try the package's metadata directly in case there's nothing #returned by XML-RPC's release_urls() - if metadata and metadata.has_key('download_url') and \ + if metadata and 'download_url' in metadata and \ metadata['download_url'] != "UNKNOWN" and \ metadata['download_url'] != None: if metadata['download_url'] not in all_urls: From 3243f4922e9001040347b7be91bcab03306ec959 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Thu, 3 Jan 2013 17:57:28 +0000 Subject: [PATCH 016/181] fix upgrade all oneliner Now does not cause "Double requirement given" error --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index aadc8f2..5981588 100644 --- a/README.rst +++ b/README.rst @@ -85,7 +85,7 @@ Tips and Tricks Warning: You only want to do this inside a virtualenv. If you're using Linux, use your package manager to install Python packages globally whenever possible. Think twice before upgrading all packages system-wide on OSX. - $ pip install -U `yolk -U | awk '{print $1}'` + $ pip install -U `yolk -U | awk '{print $1}' | uniq` From 1df1159c8c0037a238400fc33c3c4d5d19e1c60f Mon Sep 17 00:00:00 2001 From: Steven Myint Date: Wed, 17 Apr 2013 12:09:16 -0700 Subject: [PATCH 017/181] Put Python 3 variant on PyPI --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 2e08c6b..390de9a 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ -setup(name="yolk", +setup(name="yolk3k", license = "BSD License", version=VERSION, description="Command-line tool for querying PyPI and Python packages installed on your system.", @@ -15,7 +15,7 @@ maintainer="Rob Cakebread", author="Rob Cakebread", author_email="cakebread @ gmail", - url="https://github.com/cakebread/yolk", + url="https://github.com/myint/yolk", keywords="PyPI setuptools cheeseshop distutils eggs package management", classifiers=["Development Status :: 4 - Beta", "Intended Audience :: Developers", From f9a1e4e2101442d26c681366e440fba887fdedb5 Mon Sep 17 00:00:00 2001 From: Steven Myint Date: Wed, 17 Apr 2013 12:13:14 -0700 Subject: [PATCH 018/181] Format --- setup.py | 33 +- yolk/__init__.py | 2 - yolk/cli.py | 662 ++++++++++++++++++------------------- yolk/metadata.py | 3 +- yolk/plugins/__init__.py | 28 +- yolk/plugins/base.py | 34 +- yolk/pypi.py | 172 +++++----- yolk/setuptools_support.py | 42 ++- yolk/utils.py | 20 +- yolk/yolklib.py | 54 ++- 10 files changed, 503 insertions(+), 547 deletions(-) diff --git a/setup.py b/setup.py index 390de9a..51452ef 100644 --- a/setup.py +++ b/setup.py @@ -6,25 +6,24 @@ from yolk.__init__ import __version__ as VERSION - -setup(name="yolk3k", - license = "BSD License", +setup(name='yolk3k', + license='BSD License', version=VERSION, - description="Command-line tool for querying PyPI and Python packages installed on your system.", - long_description=open("README", "r").read(), - maintainer="Rob Cakebread", - author="Rob Cakebread", - author_email="cakebread @ gmail", - url="https://github.com/myint/yolk", - keywords="PyPI setuptools cheeseshop distutils eggs package management", - classifiers=["Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Programming Language :: Python", - "Topic :: Software Development :: Libraries :: Python Modules", + description='Command-line tool for querying PyPI and Python packages installed on your system.', + long_description=open('README', 'r').read(), + maintainer='Rob Cakebread', + author='Rob Cakebread', + author_email='cakebread @ gmail', + url='https://github.com/myint/yolk', + keywords='PyPI setuptools cheeseshop distutils eggs package management', + classifiers=['Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', ], - install_requires=["setuptools"], + install_requires=['setuptools'], packages=['yolk', 'yolk.plugins'], - package_dir={'yolk':'yolk'}, + package_dir={'yolk': 'yolk'}, entry_points={'console_scripts': ['yolk = yolk.cli:main',]}, ) diff --git a/yolk/__init__.py b/yolk/__init__.py index 9c58573..53d9539 100644 --- a/yolk/__init__.py +++ b/yolk/__init__.py @@ -11,5 +11,3 @@ __docformat__ = 'restructuredtext' __version__ = '0.4.3' - - diff --git a/yolk/cli.py b/yolk/cli.py index 39051e9..ee676fa 100755 --- a/yolk/cli.py +++ b/yolk/cli.py @@ -48,17 +48,14 @@ from yolk.__init__ import __version__ as VERSION - class StdOut: - """ - Filter stdout or stderr from specific modules - So far this is just used for pkg_resources - """ + """Filter stdout or stderr from specific modules So far this is just used + for pkg_resources.""" def __init__(self, stream, modulenames): self.stdout = stream - #Modules to squelch + # Modules to squelch self.modulenames = modulenames def __getattr__(self, attribute): @@ -67,18 +64,16 @@ def __getattr__(self, attribute): return self.__dict__[attribute] def flush(self): - """Bug workaround for Python 3.2+: - Exception AttributeError: 'flush' in