diff --git a/README.rst b/README.rst index aadc8f2..f5be8ab 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ As of 0.0.7 yolk is in Gentoo's Portage tree as dev-python/yolk and a plugin for Summary ------- -Yolk is a Python tool for obtaining information about installed Python packages and querying packages avilable on PyPI (Python Package Index). +Yolk is a Python tool for obtaining information about installed Python packages and querying packages available on PyPI (Python Package Index). You can see which packages are active, non-active or in development mode and show you which have newer versions available by querying PyPI. @@ -28,7 +28,7 @@ Usage Examples:: $ yolk -n List only the non-activated (--multi-version) packages installed - + $ yolk -l -f License,Author nose==1.0 Show the license and author for version 1.0 of the package `nose` @@ -94,21 +94,21 @@ Changes **0.4.3**: Added missing documentation and license files - + **0.4.2**: Fix for -C when an integer isn't supplied - + Fix for --entry-map from Jesus Rivero (Neurogeek) neurogeek@gentoo.org. Thanks, Jesus! - - Switch to BSD license from GPL-2 + + Switch to BSD license from GPL-2 **0.4.1**: Fix for -f fields - + Add check for integer with -L **0.4.0**: Added http proxy support for XML-RPC - + Added case-insensitive search for -f Non-existent packages with -S no longer show entire index (bug was with PyPI) @@ -130,7 +130,7 @@ Changes Removed dependency on elementtree - + **0.2.0**: Added 'svn' type for -T A kablillion bug fixes @@ -148,7 +148,7 @@ Changes **0.0.7**: New options: --entry-map and -entry-points - + Improved results with --download-links New plugin system. First plugin available: yolk-portage diff --git a/setup.py b/setup.py index 2e08c6b..b937d6b 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ long_description=open("README", "r").read(), maintainer="Rob Cakebread", author="Rob Cakebread", - author_email="cakebread @ gmail", + author_email="cakebread @ gmail dot com", url="https://github.com/cakebread/yolk", keywords="PyPI setuptools cheeseshop distutils eggs package management", classifiers=["Development Status :: 4 - Beta", diff --git a/tests/rss_feed.py b/tests/rss_feed.py index 9f21e98..bb32f60 100755 --- a/tests/rss_feed.py +++ b/tests/rss_feed.py @@ -23,7 +23,7 @@ #Python <2.5 has elementtree as 3rd party module from cElementTree import iterparse except ImportError: - print "You need to install cElementTree" + print("You need to install cElementTree") sys.exit(2) @@ -52,7 +52,7 @@ def get_pkg_ver(pv, add_quotes=True): def test_api(pypi_xml): """Basic API tests""" - print "Testing API""" + print("Testing API""") skipped = 0 skipped_msgs = [] failed = 0 @@ -68,29 +68,30 @@ def test_api(pypi_xml): % (pkg_name, "- space in project name")) try: assert versions[0] == ver - print "Testing %s... passed" % elem.text + print("Testing %s... passed" % elem.text) except: failed += 1 failed_msgs.append("%s %s" % (pkg_name, versions)) - print "Testing %s... failed" % elem.text + print("Testing %s... failed" % elem.text) - print "%s tests failed." % failed + print("%s tests failed." % failed) for msg in failed_msgs: - print "\t%s" % msg - print "%s tests skipped." % skipped + print("\t%s" % msg) + print("%s tests skipped." % skipped) for msg in skipped_msgs: - print "\t%s" % msg + print("\t%s" % msg) + def test_cli(pypi_xml): """Test the command-line tool""" - print "Testing CLI" + print("Testing CLI") for event, elem in iterparse(pypi_xml): if elem.tag == "title": if not elem.text.startswith('Cheese Shop recent updates'): - print "Testing %s..." % elem.text + print("Testing %s..." % elem.text) pkg_name, ver = get_pkg_ver(elem.text) if " " in pkg_name: - print "Space in package name, skipping: %s" % pkg_name + print("Space in package name, skipping: %s" % pkg_name) else: os.system("yolk -V '%s'" % pkg_name) os.system("yolk -D %s==%s" % (pkg_name, ver)) diff --git a/yolk/__init__.py b/yolk/__init__.py index 9c58573..3b302d3 100644 --- a/yolk/__init__.py +++ b/yolk/__init__.py @@ -10,6 +10,6 @@ """ __docformat__ = 'restructuredtext' -__version__ = '0.4.3' +__version__ = '0.5.0' diff --git a/yolk/cli.py b/yolk/cli.py index f7354c6..f143850 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] @@ -237,9 +237,9 @@ def show_updates(self): """ Check installed packages for available updates on PyPI - @param project_name: optional package name to check; checks every - installed pacakge if none specified - @type project_name: string + self.project_name: optional package name to check; checks every + installed package if none specified + self.project_name: string @returns: None """ @@ -310,7 +310,7 @@ def show_distributions(self, show): for prefix in ignores: if dist.location.startswith(prefix): dist.location = dist.location.replace(prefix, "") - #Case-insensitve search because of Windows + #Case-insensitive search because of Windows if dist.location.lower().startswith(get_python_lib().lower()): develop = "" else: @@ -414,7 +414,7 @@ def show_deps(self): """ Show dependencies for package(s) - @returns: 0 - sucess 1 - No dependency info supplied + @returns: 0 - success 1 - No dependency info supplied """ pkgs = pkg_resources.Environment() @@ -442,7 +442,7 @@ def show_pypi_changelog(self): """ Show detailed PyPI ChangeLog for the last `hours` - @returns: 0 = sucess or 1 if failed to retrieve from XML-RPC server + @returns: 0 = success or 1 if failed to retrieve from XML-RPC server """ hours = self.options.show_pypi_changelog @@ -493,7 +493,7 @@ def show_pypi_releases(self): def show_download_links(self): """ - Query PyPI for pkg download URI for a packge + Query PyPI for pkg download URI for a package @returns: 0 @@ -565,7 +565,7 @@ def fetch(self): if self.options.file_type == "svn": version = "dev" svn_uri = get_download_uri(self.project_name, \ - "dev", True) + "dev", True) if svn_uri: directory = self.project_name + "_svn" return self.fetch_svn(svn_uri, directory) @@ -584,7 +584,7 @@ def fetch(self): return self.fetch_uri(directory, uri) else: self.logger.error("No %s URI found for package: %s " % \ - (self.options.file_type, self.project_name)) + (self.options.file_type, self.project_name)) return 1 def fetch_uri(self, directory, uri): @@ -612,8 +612,12 @@ def fetch_uri(self, directory, uri): % (filename, uri)) self.logger.error(str(err_msg)) return 1 + try: + content_type = headers.gettype() + except AttributeError: + content_type = headers.get_content_type() - if headers.gettype() in ["text/html"]: + if content_type == "text/html": dfile = open(downloaded_filename) if re.search("404 Not Found", "".join(dfile.readlines())): dfile.close() @@ -672,14 +676,14 @@ 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': browser = webbrowser.Konqueror() else: browser = webbrowser.get() - browser.open(metadata["home_page"], 2) + browser.open(metadata["home_page"], 2) return 0 self.logger.error("No homepage URL found.") @@ -725,10 +729,10 @@ def versions_available(self): print_pkg_versions(self.project_name, self.all_versions) else: if self.version: - self.logger.error("No pacakge found for version %s" \ + self.logger.error("No package found for version %s" \ % self.version) else: - self.logger.error("No pacakge found for %s" % self.project_name) + self.logger.error("No package found for %s" % self.project_name) return 1 return 0 @@ -784,13 +788,11 @@ def parse_search_spec(self, spec): first = spec (key1, term1) = first.split('=') key1 = key1.strip() + spec = {key1: term1} + if second: (key2, term2) = second.split('=') key2 = key2.strip() - - spec = {} - spec[key1] = term1 - if second: spec[key2] = term2 except: self.logger.error(usage) @@ -803,8 +805,8 @@ def pypi_search(self): Search PyPI by metadata keyword e.g. yolk -S name=yolk AND license=GPL - @param spec: Cheese Shop search spec - @type spec: list of strings + self.pkg_spec: Cheese Shop search spec + self.pkg_spec: list of strings spec examples: ["name=yolk"] @@ -815,7 +817,7 @@ def pypi_search(self): """ spec = self.pkg_spec - #Add remainging cli arguments to options.pypi_search + #Add remaining cli arguments to options.pypi_search search_arg = self.options.pypi_search spec.insert(0, search_arg.strip()) @@ -837,9 +839,6 @@ def show_entry_map(self): """ Show entry map for a package - @param dist: package - @param type: srting - @returns: 0 for success or 1 if error """ pprinter = pprint.PrettyPrinter() @@ -870,7 +869,7 @@ def show_entry_points(self): print(" %s" % entry_point) if plugin.__doc__: print(plugin.__doc__) - print + print() except ImportError: pass if not found: diff --git a/yolk/pypi.py b/yolk/pypi.py index 3ba3ba0..78fa6f5 100644 --- a/yolk/pypi.py +++ b/yolk/pypi.py @@ -20,21 +20,24 @@ import platform if platform.python_version().startswith('2'): import xmlrpclib - import cPickle + import cPickle as pickle import urllib2 + import httplib else: import xmlrpc.client as xmlrpclib import pickle import urllib.request as urllib2 + import http.client as httplib import os import time import logging -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): """ @@ -64,7 +67,7 @@ class ProxyTransport(xmlrpclib.Transport): Provides an XMl-RPC transport routing via a http proxy. This is done by using urllib2, which in turn uses the environment - varable http_proxy and whatever else it is built to use (e.g. the + variable http_proxy and whatever else it is built to use (e.g. the windows registry). NOTE: the environment variable http_proxy should be set correctly. @@ -82,7 +85,10 @@ def request(self, host, handler, request_body, verbose): self.verbose = verbose url = 'http://' + host + handler request = urllib2.Request(url) - request.add_data(request_body) + try: + request.add_data(request_body) + except AttributeError: + request.data = request_body # Note: 'Host' and 'Content-Length' are added automatically request.add_header('User-Agent', self.user_agent) request.add_header('Content-Type', 'text/xml') @@ -164,7 +170,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 +209,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): @@ -238,7 +244,7 @@ def release_data(self, package_name, version): try: return self.xmlrpc.release_data(package_name, version) except xmlrpclib.Fault: - #XXX Raises xmlrpclib.Fault if you give non-existant version + #XXX Raises xmlrpclib.Fault if you give non-existent version #Could this be server bug? return @@ -250,7 +256,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] @@ -275,9 +281,9 @@ 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 \ - metadata['download_url'] != "UNKNOWN" and \ - metadata['download_url'] != None: + if metadata and 'download_url' in metadata and\ + metadata['download_url'] != "UNKNOWN" and\ + metadata['download_url'] is not None: if metadata['download_url'] not in all_urls: if pkg_type != "all": url = filter_url(pkg_type, metadata['download_url']) diff --git a/yolk/utils.py b/yolk/utils.py index 3b40ccf..f137329 100644 --- a/yolk/utils.py +++ b/yolk/utils.py @@ -5,7 +5,7 @@ utils.py =========== -Misc funcitions +Misc functions --------------- run_command borrowed from Cheesecake - See CREDITS. @@ -17,7 +17,11 @@ import signal import time from subprocess import Popen, STDOUT - +import platform +if platform.python_version().startswith('2'): + from os import tmpfile +else: + from tempfile import TemporaryFile as tmpfile def get_yolk_dir(): @@ -34,7 +38,7 @@ def run_command(cmd, env=None, max_timeout=None): """ arglist = cmd.split() - output = os.tmpfile() + output = tmpfile() try: pipe = Popen(arglist, stdout=output, stderr=STDOUT, env=env) except Exception as errmsg: diff --git a/yolk/yolklib.py b/yolk/yolklib.py index 5a0a695..4691aa8 100755 --- a/yolk/yolklib.py +++ b/yolk/yolklib.py @@ -1,4 +1,3 @@ - ''' yolklib.py @@ -34,7 +33,7 @@ def __init__(self): def query_activated(self, dist): """ Return True if distribution is active - Return Falsee if distribution is non-active + Return False if distribution is non-active @param dist: pkg_resources Distribution object @@ -131,8 +130,8 @@ def case_sensitive_name(self, package_name): """ Return case-sensitive package name given any-case package name - @param project_name: PyPI project name - @type project_name: string + @param package_name: PyPI project name + @type package_name: string """ if len(self.environment[package_name]):