From f3e1976da8eeef942a95019669633255fa3b6c50 Mon Sep 17 00:00:00 2001 From: dol-sen Date: Sun, 18 Sep 2011 23:22:15 -0700 Subject: py2, py3 compatability changes so 2to3 will work correctly. --- layman/api.py | 6 ++++-- layman/compatibility.py | 29 +++++++++++++++++++++++++ layman/db.py | 26 +++++++++++++--------- layman/dbbase.py | 6 ++++-- layman/output.py | 25 ++++++++++----------- layman/overlays/cvs.py | 2 +- layman/overlays/overlay.py | 54 +++++++++++++++++++++++----------------------- layman/overlays/tar.py | 2 +- layman/utils.py | 16 +++++--------- 9 files changed, 100 insertions(+), 66 deletions(-) create mode 100644 layman/compatibility.py diff --git a/layman/api.py b/layman/api.py index 5e624d1..c1a0e97 100755 --- a/layman/api.py +++ b/layman/api.py @@ -22,6 +22,8 @@ from layman.dbbase import UnknownOverlayException, UnknownOverlayMessage from layman.db import DB, RemoteDB from layman.overlays.source import require_supported #from layman.utils import path, delete_empty_directory +from layman.compatibility import encode, fileopen + UNKNOWN_REPO_ID = "Repo ID '%s' " + \ "is not listed in the current available overlays list" @@ -91,7 +93,7 @@ class LaymanAPI(object): if isinstance(repos, basestring): repos = [repos] # else assume it is an iterable, if not it will error - return repos + return [encode(i) for i in repos] def delete_repos(self, repos): @@ -411,7 +413,7 @@ class LaymanAPI(object): >>> api.get_errors() [] >>> filename = api._get_remote_db().filepath(config['overlays'])+'.xml' - >>> b = open(filename) + >>> b = fileopen(filename, 'r') >>> b.readlines()[24] ' A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].\\n' diff --git a/layman/compatibility.py b/layman/compatibility.py new file mode 100644 index 0000000..b71a8af --- /dev/null +++ b/layman/compatibility.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" Copyright 2005 - 2008 Gunnar Wrobel + 2011 - Brian Dolbec + Distributed under the terms of the GNU General Public License v2 +""" + +import sys, types + + +def encode(text, enc="UTF-8"): + """py2, py3 compatibility function""" + if hasattr(text, 'decode'): + try: + return text.decode(enc) + except UnicodeEncodeError: + return unicode(text) + return str(text) + + +def fileopen(path, mode='r', enc="UTF-8"): + """py2, py3 compatibility function""" + try: + f = open(path, mode, encoding=enc) + except TypeError: + f = open(path, mode) + return f + diff --git a/layman/db.py b/layman/db.py index 49069b7..807a740 100644 --- a/layman/db.py +++ b/layman/db.py @@ -30,10 +30,11 @@ import os, os.path import urllib2 import hashlib -from layman.utils import path, delete_empty_directory +from layman.utils import path, delete_empty_directory, encoder from layman.dbbase import DbBase from layman.makeconf import MakeConf from layman.version import VERSION +from layman.compatibility import fileopen #from layman.debug import OUT @@ -315,7 +316,7 @@ class RemoteDB(DbBase): >>> a = RemoteDB(config) >>> a.cache() (True, True) - >>> b = open(a.filepath(config['overlays'])+'.xml') + >>> b = fileopen(a.filepath(config['overlays'])+'.xml') >>> b.readlines()[24] ' A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].\\n' @@ -341,7 +342,7 @@ class RemoteDB(DbBase): opener.addheaders = [('User-Agent', 'Layman-' + VERSION)] if os.path.exists(tpath): - with open(tpath,'r') as previous: + with fileopen(tpath,'r') as previous: timestamp = previous.read() request.add_header('If-Modified-Since', timestamp) @@ -350,10 +351,12 @@ class RemoteDB(DbBase): try: connection = opener.open(request) - if 'last-modified' in connection.headers.keys(): - timestamp = connection.headers['last-modified'] - elif 'date' in connection.headers.keys(): - timestamp = connection.headers['date'] + # py2, py3 compatibility, since only py2 returns keys as lower() + headers = dict((x.lower(), x) for x in connection.headers.keys()) + if 'last-modified' in headers: + timestamp = connection.headers[headers['last-modified']] + elif 'date' in headers: + timestamp = connection.headers[headers['date']] else: timestamp = None except urllib2.HTTPError, e: @@ -406,12 +409,14 @@ class RemoteDB(DbBase): # Ok, now we can overwrite the old cache try: - out_file = open(mpath, 'w') + out_file = fileopen(mpath, 'w') + if hasattr(olist, 'decode'): + olist = olist.decode("UTF-8") out_file.write(olist) out_file.close() if timestamp is not None: - out_file = open(tpath, 'w') + out_file = fileopen(tpath, 'w') out_file.write(str(timestamp)) out_file.close() @@ -431,8 +436,9 @@ class RemoteDB(DbBase): base = self.config['cache'] self.output.debug('Generating cache path.', 6) + url_encoded = encoder(url, "UTF-8") - return base + '_' + hashlib.md5(url).hexdigest() + return base + '_' + hashlib.md5(url_encoded).hexdigest() def check_path(self, paths, hint=True): diff --git a/layman/dbbase.py b/layman/dbbase.py index ccd5806..149988b 100644 --- a/layman/dbbase.py +++ b/layman/dbbase.py @@ -34,6 +34,7 @@ import xml.etree.ElementTree as ET # Python 2.5 #from layman.debug import OUT from layman.utils import indent +from layman.compatibility import fileopen from layman.overlays.overlay import Overlay #=============================================================================== @@ -114,7 +115,8 @@ class DbBase(object): '''Read the overlay definition file.''' try: - document = open(path, 'r').read() + df = fileopen(path, 'r') + document = df.read() except Exception, error: if not self.ignore_init_read_errors: @@ -214,7 +216,7 @@ class DbBase(object): indent(tree) tree = ET.ElementTree(tree) try: - f = open(path, 'w') + f = fileopen(path, 'w') f.write("""\ """) diff --git a/layman/output.py b/layman/output.py index 37da0c5..7b42b81 100644 --- a/layman/output.py +++ b/layman/output.py @@ -13,6 +13,7 @@ __version__ = "0.1" import sys, types from layman.constants import codes, INFO_LEVEL, WARN_LEVEL, DEBUG_LEVEL, OFF +from layman.compatibility import encode class MessageBase(object): @@ -110,8 +111,8 @@ class Message(MessageBase): """empty debug function, does nothing, declared here for compatibility with DebugMessage """ - if type(info) not in types.StringTypes: - info = str(info) + if type(info) != str:#not in types.StringTypes: + info = encode(info) if level > self.debug_lev: return @@ -126,8 +127,8 @@ class Message(MessageBase): def info (self, info, level = INFO_LEVEL): - if type(info) not in types.StringTypes: - info = str(info) + if type(info) != str:#not in types.StringTypes: + info = encode(info) if level > self.info_lev: return @@ -138,8 +139,8 @@ class Message(MessageBase): def status (self, message, status, info = 'ignored'): - if type(message) not in types.StringTypes: - message = str(message) + if type(message) != str:#not in types.StringTypes: + message = encode(message) lines = message.split('\n') @@ -167,8 +168,8 @@ class Message(MessageBase): def warn (self, warn, level = WARN_LEVEL): - if type(warn) not in types.StringTypes: - warn = str(warn) + if type(warn) != str:#not in types.StringTypes: + warn = encode(warn) if level > self.warn_lev: return @@ -179,8 +180,8 @@ class Message(MessageBase): def error (self, error): - if type(error) not in types.StringTypes: - error = str(error) + if type(error) != str:#not in types.StringTypes: + error = encode(error) for i in error.split('\n'): # NOTE: Forced flushing ensures that stdout and stderr @@ -195,8 +196,8 @@ class Message(MessageBase): def die (self, error): - if type(error) not in types.StringTypes: - error = str(error) + if type(error) != str:#not in types.StringTypes: + error = encode(error) for i in error.split('\n'): self.error(self.color_func('red', 'Fatal error: ') + i) diff --git a/layman/overlays/cvs.py b/layman/overlays/cvs.py index 883baa3..2bb6791 100644 --- a/layman/overlays/cvs.py +++ b/layman/overlays/cvs.py @@ -26,7 +26,7 @@ __version__ = "$Id$" import xml.etree.ElementTree as ET # Python 2.5 -from layman.utils import path, ensure_unicode +from layman.utils import path from layman.overlays.source import OverlaySource, require_supported #=============================================================================== diff --git a/layman/overlays/overlay.py b/layman/overlays/overlay.py index 7eb76bb..8eb0870 100755 --- a/layman/overlays/overlay.py +++ b/layman/overlays/overlay.py @@ -33,8 +33,8 @@ import codecs import locale import xml.etree.ElementTree as ET # Python 2.5 -from layman.utils import (pad, terminal_width, get_encoding, encoder, - ensure_unicode) +from layman.utils import pad, terminal_width, get_encoding, encoder +from layman.compatibility import encode from layman.overlays.bzr import BzrOverlay from layman.overlays.darcs import DarcsOverlay @@ -119,9 +119,9 @@ class Overlay(object): _name = xml.find('name') if _name != None: - self.name = ensure_unicode(strip_text(_name)) + self.name = encode(strip_text(_name)) elif 'name' in xml.attrib: - self.name = ensure_unicode(xml.attrib['name']) + self.name = encode(xml.attrib['name']) else: raise Exception('Overlay from_xml(), "' + self.name + \ 'is missing a "name" entry!') @@ -144,7 +144,7 @@ class Overlay(object): except KeyError: raise Exception('Overlay from_xml(), "' + self.name + \ 'Unknown overlay type "%s"!' % _type) - _location = ensure_unicode(strip_text(source_elem)) + _location = encode(strip_text(source_elem)) return _class(parent=self, config=self.config, _location=_location, ignore=ignore) @@ -156,9 +156,9 @@ class Overlay(object): _subpath = xml.find('subpath') if _subpath != None: - self.subpath = ensure_unicode(_subpath.text.strip()) + self.subpath = encode(_subpath.text.strip()) elif 'subpath' in xml.attrib: - self.subpath = ensure_unicode(xml.attrib['subpath']) + self.subpath = encode(xml.attrib['subpath']) else: self.subpath = '' @@ -168,14 +168,14 @@ class Overlay(object): else: _email = _owner.find('email') if _owner != None and _email != None: - self.owner_email = ensure_unicode(strip_text(_email)) + self.owner_email = encode(strip_text(_email)) _name = _owner.find('name') if _name != None: - self.owner_name = ensure_unicode(strip_text(_name)) + self.owner_name = encode(strip_text(_name)) else: self.owner_name = None elif 'contact' in xml.attrib: - self.owner_email = ensure_unicode(xml.attrib['contact']) + self.owner_email = encode(xml.attrib['contact']) self.owner_name = None else: self.owner_email = '' @@ -190,7 +190,7 @@ class Overlay(object): _desc = xml.find('description') if _desc != None: d = WHITESPACE_REGEX.sub(' ', strip_text(_desc)) - self.description = ensure_unicode(d) + self.description = encode(d) del d else: self.description = '' @@ -202,14 +202,14 @@ class Overlay(object): '"description" entry!', 4) if 'status' in xml.attrib: - self.status = ensure_unicode(xml.attrib['status']) + self.status = encode(xml.attrib['status']) else: self.status = None self.quality = u'experimental' if 'quality' in xml.attrib: if xml.attrib['quality'] in set(QUALITY_LEVELS): - self.quality = ensure_unicode(xml.attrib['quality']) + self.quality = encode(xml.attrib['quality']) if 'priority' in xml.attrib: self.priority = int(xml.attrib['priority']) @@ -219,18 +219,18 @@ class Overlay(object): h = xml.find('homepage') l = xml.find('link') if h != None: - self.homepage = ensure_unicode(strip_text(h)) + self.homepage = encode(strip_text(h)) elif l != None: - self.homepage = ensure_unicode(strip_text(l)) + self.homepage = encode(strip_text(l)) else: self.homepage = None - self.feeds = [ensure_unicode(strip_text(e)) \ + self.feeds = [encode(strip_text(e)) \ for e in xml.findall('feed')] _irc = xml.find('irc') if _irc != None: - self.irc = ensure_unicode(strip_text(_irc)) + self.irc = encode(strip_text(_irc)) else: self.irc = None @@ -241,7 +241,7 @@ class Overlay(object): self.output.debug("Overlay from_dict(); overlay" + str(overlay)) _name = overlay['name'] if _name != None: - self.name = ensure_unicode(_name) + self.name = encode(_name) else: raise Exception('Overlay from_dict(), "' + self.name + 'is missing a "name" entry!') @@ -259,7 +259,7 @@ class Overlay(object): except KeyError: raise Exception('Overlay from_dict(), "' + self.name + 'Unknown overlay type "%s"!' % _type) - _location = ensure_unicode(_src) + _location = encode(_src) return _class(parent=self, config=self.config, _location=_location, ignore=ignore) @@ -270,10 +270,10 @@ class Overlay(object): self.owner_name = None _email = None else: - self.owner_name = ensure_unicode(_owner) + self.owner_name = encode(_owner) _email = overlay['owner_email'] if _email != None: - self.owner_email = ensure_unicode(_email) + self.owner_email = encode(_email) else: self.owner_email = None if not ignore: @@ -286,7 +286,7 @@ class Overlay(object): _desc = overlay['description'] if _desc != None: d = WHITESPACE_REGEX.sub(' ', _desc) - self.description = ensure_unicode(d) + self.description = encode(d) del d else: self.description = '' @@ -298,14 +298,14 @@ class Overlay(object): '" is missing a "description" entry!', 4) if overlay['status']: - self.status = ensure_unicode(overlay['status']) + self.status = encode(overlay['status']) else: self.status = None self.quality = u'experimental' if len(overlay['quality']): if overlay['quality'] in set(QUALITY_LEVELS): - self.quality = ensure_unicode(overlay['quality']) + self.quality = encode(overlay['quality']) if overlay['priority']: self.priority = int(overlay['priority']) @@ -314,16 +314,16 @@ class Overlay(object): h = overlay['homepage'] if h != None: - self.homepage = ensure_unicode(h) + self.homepage = encode(h) else: self.homepage = None - self.feeds = [ensure_unicode(e) \ + self.feeds = [encode(e) \ for e in overlay['feeds']] _irc = overlay['irc'] if _irc != None: - self.irc = ensure_unicode(_irc) + self.irc = encode(_irc) else: self.irc = None diff --git a/layman/overlays/tar.py b/layman/overlays/tar.py index 6fd5ba8..546c134 100644 --- a/layman/overlays/tar.py +++ b/layman/overlays/tar.py @@ -27,7 +27,7 @@ __version__ = "$Id: tar.py 310 2007-04-09 16:30:40Z wrobel $" import os, os.path, sys, urllib2, shutil, tempfile import xml.etree.ElementTree as ET # Python 2.5 -from layman.utils import path, ensure_unicode +from layman.utils import path #from layman.debug import OUT from layman.overlays.source import OverlaySource, require_supported diff --git a/layman/utils.py b/layman/utils.py index 6f144be..9ffdda0 100644 --- a/layman/utils.py +++ b/layman/utils.py @@ -43,6 +43,10 @@ from layman.debug import OUT # #------------------------------------------------------------------------------- +def encoder(text, _encoding_): + return codecs.encode(text, _encoding_, 'replace') + + def decode_selection(selection): '''utility function to decode a list of strings accoring to the filesystem encoding @@ -51,14 +55,10 @@ def decode_selection(selection): selection = selection or [] enc = sys.getfilesystemencoding() if enc is not None: - return [i.decode(enc) for i in selection] + return [encoder(i, enc) for i in selection] return selection -def encoder(unicode_text, _encoding_): - return codecs.encode(unicode_text, _encoding_, 'replace') - - def get_encoding(output): if hasattr(output, 'encoding') \ and output.encoding != None: @@ -104,12 +104,6 @@ def terminal_width(): return 80 -def ensure_unicode(obj, encoding='utf-8'): - if isinstance(obj, basestring): - if not isinstance(obj, unicode): - obj = unicode(obj, encoding) - return obj - # From # BEGIN def indent(elem, level=0): -- cgit v1.2.3-1-g7c22