summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordol-sen <brian.dolbec@gmail.com>2011-09-18 23:22:15 -0700
committerdol-sen <brian.dolbec@gmail.com>2011-09-22 20:12:00 -0700
commitf3e1976da8eeef942a95019669633255fa3b6c50 (patch)
treefd5abe96dd7a25684a81fd6508e7c5c86204f683
parent2413c2f4d2c5eb09063f477bcd158244ab8d32ff (diff)
downloadlayman-f3e1976da8eeef942a95019669633255fa3b6c50.tar.gz
layman-f3e1976da8eeef942a95019669633255fa3b6c50.tar.bz2
layman-f3e1976da8eeef942a95019669633255fa3b6c50.zip
py2, py3 compatability changes so 2to3 will work correctly.
-rwxr-xr-xlayman/api.py6
-rw-r--r--layman/compatibility.py29
-rw-r--r--layman/db.py26
-rw-r--r--layman/dbbase.py6
-rw-r--r--layman/output.py25
-rw-r--r--layman/overlays/cvs.py2
-rwxr-xr-xlayman/overlays/overlay.py54
-rw-r--r--layman/overlays/tar.py2
-rw-r--r--layman/utils.py16
9 files changed, 100 insertions, 66 deletions
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("""\
<?xml version="1.0" encoding="UTF-8"?>
""")
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 <http://effbot.org/zone/element-lib.htm>
# BEGIN
def indent(elem, level=0):