summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Douard <david.douard@logilab.fr>2012-11-14 17:02:48 +0100
committerDavid Douard <david.douard@logilab.fr>2012-11-14 17:02:48 +0100
commit9fc4653fc67300e02b0d0a0ecd2fb4fe647780ab (patch)
treeae8761455ad3edecb8e59b94972357f6d7159a77
parentd9ae7d4a40d65160de9ff07b69ea880f7fb2040d (diff)
parent1d0f11913a66d5410c65a9c039a1630218b2e3ae (diff)
downloadlogilab-common-9fc4653fc67300e02b0d0a0ecd2fb4fe647780ab.tar.gz
backport stable
-rw-r--r--ChangeLog28
-rw-r--r--__pkginfo__.py2
-rw-r--r--date.py54
-rw-r--r--debian/changelog18
-rw-r--r--modutils.py33
-rw-r--r--registry.py7
-rw-r--r--setup.py19
-rw-r--r--shellutils.py2
-rw-r--r--table.py10
-rw-r--r--test/data/lmfp/__init__.py2
-rw-r--r--test/data/lmfp/foo.py6
-rw-r--r--test/data/test1.msg4
-rw-r--r--test/unittest_cache.py10
-rw-r--r--test/unittest_changelog.py7
-rw-r--r--test/unittest_date.py4
-rw-r--r--test/unittest_decorators.py10
-rw-r--r--test/unittest_fileutils.py64
-rw-r--r--test/unittest_modutils.py45
-rw-r--r--test/unittest_shellutils.py14
-rw-r--r--test/unittest_table.py18
-rw-r--r--test/unittest_testlib.py40
-rw-r--r--test/unittest_umessage.py2
-rw-r--r--testlib.py30
-rw-r--r--umessage.py93
24 files changed, 303 insertions, 219 deletions
diff --git a/ChangeLog b/ChangeLog
index e3ab3b1..bffa78b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,32 @@
ChangeLog for logilab.common
============================
-2012-04-12 -- 0.58.0
+2012-11-14 -- 0.58.3
+ * date: fix ustrftime() impl. for python3 (closes #82161, patch by Arfrever
+ Frehtes Taifersar Arahesis) and encoding detection for python2 (closes
+ #109740)
+
+ * other python3 code and test fixes (closes #104047)
+
+ * registry: setdefault shouldn't raise RegistryNotFound (closes #111010)
+
+ * table: stop encoding to iso-8859-1, use unicode (closes #105847)
+
+ * setup: properly install additional files during build instead of install (closes #104045)
+
+
+
+2012-07-30 -- 0.58.2
+ * modutils: fixes (closes #100757 and #100935)
+
+
+
+2012-07-17 -- 0.58.1
+ * modutils, testlib: be more python implementation independant (closes #99493 and #99627)
+
+
+
+2012-04-12 -- 0.58.0
* new `registry` module containing a backport of CubicWeb selectable objects registry (closes #84654)
* testlib: DocTestCase fix builtins pollution after doctest execution.
@@ -11,6 +36,7 @@ ChangeLog for logilab.common
* deprecated: new DeprecationWrapper class (closes #88942)
+
2012-03-22 -- 0.57.2
* texutils: apply_units raise ValueError if string isn'nt valid (closes #88808)
diff --git a/__pkginfo__.py b/__pkginfo__.py
index d6c6332..5f47663 100644
--- a/__pkginfo__.py
+++ b/__pkginfo__.py
@@ -24,7 +24,7 @@ modname = 'common'
subpackage_of = 'logilab'
subpackage_master = True
-numversion = (0, 58, 0)
+numversion = (0, 58, 3)
version = '.'.join([str(num) for num in numversion])
license = 'LGPL' # 2.1 or later
diff --git a/date.py b/date.py
index b069a6f..ae5025e 100644
--- a/date.py
+++ b/date.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -22,7 +22,8 @@ __docformat__ = "restructuredtext en"
import math
import re
-from locale import getpreferredencoding
+import sys
+from locale import getlocale, LC_TIME
from datetime import date, time, datetime, timedelta
from time import strptime as time_strptime
from calendar import monthrange, timegm
@@ -279,29 +280,34 @@ def last_day(somedate):
def ustrftime(somedate, fmt='%Y-%m-%d'):
"""like strftime, but returns a unicode string instead of an encoded
- string which' may be problematic with localized date.
-
- encoding is guessed by locale.getpreferredencoding()
+ string which may be problematic with localized date.
"""
- encoding = getpreferredencoding(do_setlocale=False) or 'UTF-8'
- try:
- return unicode(somedate.strftime(str(fmt)), encoding)
- except ValueError, exc:
- if somedate.year >= 1900:
- raise
- # datetime is not happy with dates before 1900
- # we try to work around this, assuming a simple
- # format string
- fields = {'Y': somedate.year,
- 'm': somedate.month,
- 'd': somedate.day,
- }
- if isinstance(somedate, datetime):
- fields.update({'H': somedate.hour,
- 'M': somedate.minute,
- 'S': somedate.second})
- fmt = re.sub('%([YmdHMS])', r'%(\1)02d', fmt)
- return unicode(fmt) % fields
+ if sys.version_info >= (3, 3):
+ # datetime.date.strftime() supports dates since year 1 in Python >=3.3.
+ return somedate.strftime(fmt)
+ else:
+ try:
+ if sys.version_info < (3, 0):
+ encoding = getlocale(LC_TIME)[1] or 'ascii'
+ return unicode(somedate.strftime(str(fmt)), encoding)
+ else:
+ return somedate.strftime(fmt)
+ except ValueError, exc:
+ if somedate.year >= 1900:
+ raise
+ # datetime is not happy with dates before 1900
+ # we try to work around this, assuming a simple
+ # format string
+ fields = {'Y': somedate.year,
+ 'm': somedate.month,
+ 'd': somedate.day,
+ }
+ if isinstance(somedate, datetime):
+ fields.update({'H': somedate.hour,
+ 'M': somedate.minute,
+ 'S': somedate.second})
+ fmt = re.sub('%([YmdHMS])', r'%(\1)02d', fmt)
+ return unicode(fmt) % fields
def utcdatetime(dt):
if dt.tzinfo is None:
diff --git a/debian/changelog b/debian/changelog
index e501433..21428ff 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
+logilab-common (0.58.3-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- David Douard <david.douard@logilab.fr> Wed, 14 Nov 2012 16:18:53 +0100
+
+logilab-common (0.58.2-1) precise; urgency=low
+
+ * new upstream release
+
+ -- David Douard <david.douard@logilab.fr> Mon, 30 Jul 2012 12:26:15 +0200
+
+logilab-common (0.58.1-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr> Tue, 17 Jul 2012 16:01:54 +0200
+
logilab-common (0.58.0-1) unstable; urgency=low
* new upstream release
diff --git a/modutils.py b/modutils.py
index 95c400a..2cae005 100644
--- a/modutils.py
+++ b/modutils.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -34,6 +34,7 @@ import os
from os.path import splitext, join, abspath, isdir, dirname, exists, basename
from imp import find_module, load_module, C_BUILTIN, PY_COMPILED, PKG_DIRECTORY
from distutils.sysconfig import get_config_var, get_python_lib, get_python_version
+from distutils.errors import DistutilsPlatformError
try:
import zipimport
@@ -53,12 +54,18 @@ from logilab.common import STD_BLACKLIST, _handle_blacklist
if sys.platform.startswith('win'):
PY_SOURCE_EXTS = ('py', 'pyw')
PY_COMPILED_EXTS = ('dll', 'pyd')
- STD_LIB_DIR = get_python_lib(standard_lib=1)
else:
PY_SOURCE_EXTS = ('py',)
PY_COMPILED_EXTS = ('so',)
- # extend lib dir with some arch-dependant paths
- STD_LIB_DIR = join(get_config_var("LIBDIR"), "python%s" % get_python_version())
+
+try:
+ STD_LIB_DIR = get_python_lib(standard_lib=1)
+# get_python_lib(standard_lib=1) is not available on pypy, set STD_LIB_DIR to
+# non-valid path, see https://bugs.pypy.org/issue1164
+except DistutilsPlatformError:
+ STD_LIB_DIR = '//'
+
+EXT_LIB_DIR = get_python_lib()
BUILTIN_MODULES = dict(zip(sys.builtin_module_names,
[1]*len(sys.builtin_module_names)))
@@ -151,6 +158,9 @@ def load_module_from_modpath(parts, path=None, use_sys=1):
if len(modpath) != len(parts):
# even with use_sys=False, should try to get outer packages from sys.modules
module = sys.modules.get(curname)
+ elif use_sys:
+ # because it may have been indirectly loaded through a parent
+ module = sys.modules.get(curname)
if module is None:
mp_file, mp_filename, mp_desc = find_module(part, path)
module = load_module(curname, mp_file, mp_filename, mp_desc)
@@ -230,10 +240,7 @@ def modpath_from_file(filename, extrapath=None):
return extrapath[path_].split('.') + submodpath
for path in sys.path:
path = abspath(path)
- if path and base[:len(path)] == path:
- if filename.find('site-packages') != -1 and \
- path.find('site-packages') == -1:
- continue
+ if path and base.startswith(path):
modpath = [pkg for pkg in base[len(path):].split(os.sep) if pkg]
if _check_init(path, modpath[:-1]):
return modpath
@@ -493,13 +500,11 @@ def is_standard_module(modname, std_path=(STD_LIB_DIR,)):
if filename is None:
return 1
filename = abspath(filename)
+ if filename.startswith(EXT_LIB_DIR):
+ return 0
for path in std_path:
- path = abspath(path)
- if filename.startswith(path):
- pfx_len = len(path)
- if filename[pfx_len+1:pfx_len+14] != 'site-packages':
- return 1
- return 0
+ if filename.startswith(abspath(path)):
+ return 1
return False
diff --git a/registry.py b/registry.py
index 29f3c56..86065c5 100644
--- a/registry.py
+++ b/registry.py
@@ -218,7 +218,8 @@ class Registry(dict):
assert not '__abstract__' in obj.__dict__
assert obj.__select__
oid = oid or obj.__regid__
- assert oid
+ assert oid, ('no explicit name supplied to register object %s, '
+ 'which has no __regid__ set' % obj)
if clear:
objects = self[oid] = []
else:
@@ -500,7 +501,7 @@ class RegistryStore(dict):
def setdefault(self, regid):
try:
return self[regid]
- except KeyError:
+ except RegistryNotFound:
self[regid] = self.registry_class(regid)(self.debugmode)
return self[regid]
@@ -519,6 +520,8 @@ class RegistryStore(dict):
:meth:`~logilab.common.registry.RegistryStore.register_and_replace`
for instance)
"""
+ assert isinstance(modname, basestring), \
+ 'modname expected to be a module name (ie string), got %r' % modname
for obj in objects:
try:
if obj.__module__ != modname or obj in butclasses:
diff --git a/setup.py b/setup.py
index 5cca4c8..47cca43 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pylint: disable=W0404,W0622,W0704,W0613
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -105,8 +105,7 @@ except ImportError:
'''
class MyInstallLib(install_lib.install_lib):
- """extend install_lib command to handle package __init__.py and
- include_dirs variable if necessary
+ """extend install_lib command to handle package __init__.py if necessary
"""
def run(self):
"""overridden from install_lib class"""
@@ -119,17 +118,27 @@ class MyInstallLib(install_lib.install_lib):
stream = open(product_init, 'w')
stream.write(EMPTY_FILE)
stream.close()
+
+
+class MyBuildPy(build_py):
+ """extend build_by command to handle include_dirs variable if necessary
+ """
+ def run(self):
+ """overridden from install_lib class"""
+ build_py.run(self)
# manually install included directories if any
if include_dirs:
if subpackage_of:
base = join(subpackage_of, modname)
else:
base = modname
+ basedir = os.path.join(self.build_lib, base)
for directory in include_dirs:
- dest = join(self.install_dir, base, directory)
+ dest = join(basedir, directory)
shutil.rmtree(dest, ignore_errors=True)
shutil.copytree(directory, dest)
+
def install(**kwargs):
"""setup entry point"""
if USE_SETUPTOOLS:
@@ -164,7 +173,7 @@ def install(**kwargs):
data_files = data_files,
ext_modules = ext_modules,
cmdclass = {'install_lib': MyInstallLib,
- 'build_py': build_py},
+ 'build_py': MyBuildPy},
**kwargs
)
diff --git a/shellutils.py b/shellutils.py
index 749cbac..60ef602 100644
--- a/shellutils.py
+++ b/shellutils.py
@@ -338,7 +338,7 @@ class ProgressBar(object):
def refresh(self):
"""Refresh the progression bar display."""
- self._stream.write(self._fstr % ('.' * min(self._progress, self._size)) )
+ self._stream.write(self._fstr % ('=' * min(self._progress, self._size)) )
if self._last_text_write_size or self._current_text:
template = ' %%-%is' % (self._last_text_write_size)
text = self._current_text
diff --git a/table.py b/table.py
index 744bb78..5fdc148 100644
--- a/table.py
+++ b/table.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -440,7 +440,7 @@ class Table(object):
# The first cell <=> an empty one
col_names_line = [' '*col_start]
for col_name in self.col_names:
- col_names_line.append(col_name.encode('iso-8859-1') + ' '*5)
+ col_names_line.append(col_name + ' '*5)
lines.append('|' + '|'.join(col_names_line) + '|')
max_line_length = len(lines[0])
@@ -448,7 +448,7 @@ class Table(object):
for row_index, row in enumerate(self.data):
line = []
# First, build the row_name's cell
- row_name = self.row_names[row_index].encode('iso-8859-1')
+ row_name = self.row_names[row_index]
line.append(row_name + ' '*(col_start-len(row_name)))
# Then, build all the table's cell for this line.
@@ -743,14 +743,14 @@ class TableCellRenderer:
def render_row_cell(self, row_name, table, table_style):
"""Renders the cell for 'row_id' row
"""
- cell_value = row_name.encode('iso-8859-1')
+ cell_value = row_name
return self._render_cell_content(cell_value, table_style, 0)
def render_col_cell(self, col_name, table, table_style):
"""Renders the cell for 'col_id' row
"""
- cell_value = col_name.encode('iso-8859-1')
+ cell_value = col_name
col_index = table.col_names.index(col_name)
return self._render_cell_content(cell_value, table_style, col_index +1)
diff --git a/test/data/lmfp/__init__.py b/test/data/lmfp/__init__.py
new file mode 100644
index 0000000..74b26b8
--- /dev/null
+++ b/test/data/lmfp/__init__.py
@@ -0,0 +1,2 @@
+# force a "direct" python import
+from . import foo
diff --git a/test/data/lmfp/foo.py b/test/data/lmfp/foo.py
new file mode 100644
index 0000000..8f7de1e
--- /dev/null
+++ b/test/data/lmfp/foo.py
@@ -0,0 +1,6 @@
+import sys
+if not getattr(sys, 'bar', None):
+ sys.just_once = []
+# there used to be two numbers here because
+# of a load_module_from_path bug
+sys.just_once.append(42)
diff --git a/test/data/test1.msg b/test/data/test1.msg
index e9c044d..33b75c8 100644
--- a/test/data/test1.msg
+++ b/test/data/test1.msg
@@ -13,7 +13,7 @@ To: Nicolas Chauvat <nico@logilab.fr>
Subject: autre message
Message-ID: <20050720100320.GA8371@logilab.fr>
Mime-Version: 1.0
-Content-Type: text/plain; charset=iso-8859-1
+Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
User-Agent: Mutt/1.5.9i
@@ -26,5 +26,5 @@ bonjour
--
Nicolas Chauvat
-logilab.fr - services en informatique avancée et gestion de connaissances
+logilab.fr - services en informatique avancée et gestion de connaissances
diff --git a/test/unittest_cache.py b/test/unittest_cache.py
index c184cca..9b02b39 100644
--- a/test/unittest_cache.py
+++ b/test/unittest_cache.py
@@ -1,5 +1,5 @@
# unit tests for the cache module
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -68,9 +68,9 @@ class CacheTestCase(TestCase):
self.cache[4] = 'foz'
self.cache[5] = 'fuz'
self.cache[6] = 'spam'
- self.assert_(1 not in self.cache,
+ self.assertTrue(1 not in self.cache,
'key 1 has not been suppressed from the cache dictionnary')
- self.assert_(1 not in self.cache._usage,
+ self.assertTrue(1 not in self.cache._usage,
'key 1 has not been suppressed from the cache LRU list')
self.assertEqual(len(self.cache._usage), 5, "lenght of usage list is not 5")
self.assertEqual(self.cache._usage[-1], 6, '6 is not the most recently used key')
@@ -95,8 +95,8 @@ class CacheTestCase(TestCase):
"""
self.cache['foo'] = 'bar'
del self.cache['foo']
- self.assert_('foo' not in self.cache.keys(), "Element 'foo' was not removed cache dictionnary")
- self.assert_('foo' not in self.cache._usage, "Element 'foo' was not removed usage list")
+ self.assertTrue('foo' not in self.cache.keys(), "Element 'foo' was not removed cache dictionnary")
+ self.assertTrue('foo' not in self.cache._usage, "Element 'foo' was not removed usage list")
self.assertItemsEqual(self.cache._usage,
self.cache.keys())# usage list and data keys are different
diff --git a/test/unittest_changelog.py b/test/unittest_changelog.py
index 4db67ef..dff9979 100644
--- a/test/unittest_changelog.py
+++ b/test/unittest_changelog.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -15,6 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
+from __future__ import with_statement
+
from os.path import join, dirname
from cStringIO import StringIO
@@ -30,7 +32,8 @@ class ChangeLogTC(TestCase):
cl = self.cl_class(self.cl_file)
out = StringIO()
cl.write(out)
- self.assertStreamEquals(open(self.cl_file), out)
+ with open(self.cl_file) as stream:
+ self.assertMultiLineEqual(stream.read(), out.getvalue())
if __name__ == '__main__':
diff --git a/test/unittest_date.py b/test/unittest_date.py
index 8fa7776..0aa1de8 100644
--- a/test/unittest_date.py
+++ b/test/unittest_date.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -147,7 +147,7 @@ class MxDateTC(DateTC):
def check_mx(self):
if mxDate is None:
- self.skip('mx.DateTime is not installed')
+ self.skipTest('mx.DateTime is not installed')
def setUp(self):
self.check_mx()
diff --git a/test/unittest_decorators.py b/test/unittest_decorators.py
index 49661a6..72d8b07 100644
--- a/test/unittest_decorators.py
+++ b/test/unittest_decorators.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -46,14 +46,14 @@ class DecoratorsTC(TestCase):
return 12
class XXX(object):
def __call__(self, other):
- tester.assertTrue(isinstance(other, MyClass))
+ tester.assertIsInstance(other, MyClass)
return 12
try:
monkeypatch(MyClass)(XXX())
except AttributeError, err:
self.assertTrue(str(err).endswith('has no __name__ attribute: you should provide an explicit `methodname`'))
monkeypatch(MyClass, 'foo')(XXX())
- self.assertTrue(isinstance(MyClass.prop1, property))
+ self.assertIsInstance(MyClass.prop1, property)
self.assertTrue(callable(MyClass.foo))
self.assertEqual(MyClass().prop1, 12)
self.assertEqual(MyClass().foo(), 12)
@@ -177,9 +177,9 @@ class DecoratorsTC(TestCase):
foo = Foo()
self.assertEqual(Foo.x, 0)
- self.failIf('bar' in foo.__dict__)
+ self.assertFalse('bar' in foo.__dict__)
self.assertEqual(foo.bar, 1)
- self.failUnless('bar' in foo.__dict__)
+ self.assertTrue('bar' in foo.__dict__)
self.assertEqual(foo.bar, 1)
self.assertEqual(foo.quux, 42)
self.assertEqual(Foo.bar.__doc__,
diff --git a/test/unittest_fileutils.py b/test/unittest_fileutils.py
index b7ffd71..927347d 100644
--- a/test/unittest_fileutils.py
+++ b/test/unittest_fileutils.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -73,10 +73,10 @@ class ExportTC(TestCase):
def test(self):
export(DATA_DIR, self.tempdir, verbose=0)
- self.assert_(exists(join(self.tempdir, '__init__.py')))
- self.assert_(exists(join(self.tempdir, 'sub')))
- self.assert_(not exists(join(self.tempdir, '__init__.pyc')))
- self.assert_(not exists(join(self.tempdir, 'CVS')))
+ self.assertTrue(exists(join(self.tempdir, '__init__.py')))
+ self.assertTrue(exists(join(self.tempdir, 'sub')))
+ self.assertTrue(not exists(join(self.tempdir, '__init__.pyc')))
+ self.assertTrue(not exists(join(self.tempdir, 'CVS')))
def tearDown(self):
shutil.rmtree(self.tempdir)
@@ -93,50 +93,52 @@ class ProtectedFileTC(TestCase):
def test_mode_change(self):
"""tests that mode is changed when needed"""
# test on non-writable file
- #self.assert_(not os.access(self.rpath, os.W_OK))
- self.assert_(not os.stat(self.rpath).st_mode & S_IWRITE)
+ #self.assertTrue(not os.access(self.rpath, os.W_OK))
+ self.assertTrue(not os.stat(self.rpath).st_mode & S_IWRITE)
wp_file = ProtectedFile(self.rpath, 'w')
- self.assert_(os.stat(self.rpath).st_mode & S_IWRITE)
- self.assert_(os.access(self.rpath, os.W_OK))
+ self.assertTrue(os.stat(self.rpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rpath, os.W_OK))
# test on writable-file
- self.assert_(os.stat(self.rwpath).st_mode & S_IWRITE)
- self.assert_(os.access(self.rwpath, os.W_OK))
+ self.assertTrue(os.stat(self.rwpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rwpath, os.W_OK))
wp_file = ProtectedFile(self.rwpath, 'w')
- self.assert_(os.stat(self.rwpath).st_mode & S_IWRITE)
- self.assert_(os.access(self.rwpath, os.W_OK))
+ self.assertTrue(os.stat(self.rwpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rwpath, os.W_OK))
def test_restore_on_close(self):
"""tests original mode is restored on close"""
# test on non-writable file
- #self.assert_(not os.access(self.rpath, os.W_OK))
- self.assert_(not os.stat(self.rpath).st_mode & S_IWRITE)
+ #self.assertTrue(not os.access(self.rpath, os.W_OK))
+ self.assertTrue(not os.stat(self.rpath).st_mode & S_IWRITE)
ProtectedFile(self.rpath, 'w').close()
- #self.assert_(not os.access(self.rpath, os.W_OK))
- self.assert_(not os.stat(self.rpath).st_mode & S_IWRITE)
+ #self.assertTrue(not os.access(self.rpath, os.W_OK))
+ self.assertTrue(not os.stat(self.rpath).st_mode & S_IWRITE)
# test on writable-file
- self.assert_(os.access(self.rwpath, os.W_OK))
- self.assert_(os.stat(self.rwpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rwpath, os.W_OK))
+ self.assertTrue(os.stat(self.rwpath).st_mode & S_IWRITE)
ProtectedFile(self.rwpath, 'w').close()
- self.assert_(os.access(self.rwpath, os.W_OK))
- self.assert_(os.stat(self.rwpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rwpath, os.W_OK))
+ self.assertTrue(os.stat(self.rwpath).st_mode & S_IWRITE)
def test_mode_change_on_append(self):
"""tests that mode is changed when file is opened in 'a' mode"""
- #self.assert_(not os.access(self.rpath, os.W_OK))
- self.assert_(not os.stat(self.rpath).st_mode & S_IWRITE)
+ #self.assertTrue(not os.access(self.rpath, os.W_OK))
+ self.assertTrue(not os.stat(self.rpath).st_mode & S_IWRITE)
wp_file = ProtectedFile(self.rpath, 'a')
- self.assert_(os.access(self.rpath, os.W_OK))
- self.assert_(os.stat(self.rpath).st_mode & S_IWRITE)
+ self.assertTrue(os.access(self.rpath, os.W_OK))
+ self.assertTrue(os.stat(self.rpath).st_mode & S_IWRITE)
wp_file.close()
- #self.assert_(not os.access(self.rpath, os.W_OK))
- self.assert_(not os.stat(self.rpath).st_mode & S_IWRITE)
+ #self.assertTrue(not os.access(self.rpath, os.W_OK))
+ self.assertTrue(not os.stat(self.rpath).st_mode & S_IWRITE)
from logilab.common.testlib import DocTest
-class ModuleDocTest(DocTest):
- """relative_path embed tests in docstring"""
- from logilab.common import fileutils as module
- skipped = ('abspath_listdir',)
+if sys.version_info < (3, 0):
+ # skip if python3, test fail because of traceback display incompatibility :(
+ class ModuleDocTest(DocTest):
+ """relative_path embed tests in docstring"""
+ from logilab.common import fileutils as module
+ skipped = ('abspath_listdir',)
del DocTest # necessary if we don't want it to be executed (we don't...)
diff --git a/test/unittest_modutils.py b/test/unittest_modutils.py
index 4fe2baf..2218da5 100644
--- a/test/unittest_modutils.py
+++ b/test/unittest_modutils.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -128,6 +128,16 @@ class modpath_from_file_tc(ModutilsTestCase):
self.assertRaises(Exception, modutils.modpath_from_file, '/turlututu')
+class load_module_from_path_tc(ModutilsTestCase):
+
+ def test_do_not_load_twice(self):
+ sys.path.insert(0, self.datadir)
+ foo = modutils.load_module_from_modpath(['lmfp', 'foo'])
+ lmfp = modutils.load_module_from_modpath(['lmfp'])
+ self.assertEqual(len(sys.just_once), 1)
+ sys.path.pop(0)
+ del sys.just_once
+
class file_from_modpath_tc(ModutilsTestCase):
"""given a mod path (i.e. splited module / package name), return the
corresponding file, giving priority to source file over precompiled file
@@ -175,7 +185,7 @@ class is_standard_module_tc(ModutilsTestCase):
library
"""
- def test_knownValues_is_standard_module_0(self):
+ def test_knownValues_is_standard_module_builtins(self):
if sys.version_info < (3, 0):
self.assertEqual(modutils.is_standard_module('__builtin__'), True)
self.assertEqual(modutils.is_standard_module('builtins'), False)
@@ -183,30 +193,27 @@ class is_standard_module_tc(ModutilsTestCase):
self.assertEqual(modutils.is_standard_module('__builtin__'), False)
self.assertEqual(modutils.is_standard_module('builtins'), True)
- def test_knownValues_is_standard_module_1(self):
+ def test_knownValues_is_standard_module_builtin(self):
self.assertEqual(modutils.is_standard_module('sys'), True)
- def test_knownValues_is_standard_module_2(self):
+ def test_knownValues_is_standard_module_nonstandard(self):
self.assertEqual(modutils.is_standard_module('logilab'), False)
- def test_knownValues_is_standard_module_3(self):
+ def test_knownValues_is_standard_module_unknown(self):
self.assertEqual(modutils.is_standard_module('unknown'), False)
def test_knownValues_is_standard_module_4(self):
- if sys.version_info < (3, 0):
- self.assertEqual(modutils.is_standard_module('StringIO'), True)
- else:
- self.assertEqual(modutils.is_standard_module('StringIO'), False)
- if sys.version_info < (2, 6):
- self.assertEqual(modutils.is_standard_module('io'), False)
- else:
- self.assertEqual(modutils.is_standard_module('io'), True)
-
- def test_knownValues_is_standard_module_5(self):
+ self.assertEqual(modutils.is_standard_module('marshal'), True)
+ self.assertEqual(modutils.is_standard_module('hashlib'), True)
+ self.assertEqual(modutils.is_standard_module('pickle'), True)
+ self.assertEqual(modutils.is_standard_module('email'), True)
+ self.assertEqual(modutils.is_standard_module('io'), sys.version_info >= (2, 6))
+ self.assertEqual(modutils.is_standard_module('StringIO'), sys.version_info < (3, 0))
+
+ def test_knownValues_is_standard_module_custom_path(self):
self.assertEqual(modutils.is_standard_module('data.module', (DATADIR,)), True)
self.assertEqual(modutils.is_standard_module('data.module', (path.abspath(DATADIR),)), True)
-
class is_relative_tc(ModutilsTestCase):
@@ -253,9 +260,9 @@ class get_modules_files_tc(ModutilsTestCase):
del logilab.common.fileutils
del sys.modules['logilab.common.fileutils']
m = modutils.load_module_from_modpath(['logilab', 'common', 'fileutils'])
- self.assert_( hasattr(logilab, 'common') )
- self.assert_( hasattr(logilab.common, 'fileutils') )
- self.assert_( m is logilab.common.fileutils )
+ self.assertTrue( hasattr(logilab, 'common') )
+ self.assertTrue( hasattr(logilab.common, 'fileutils') )
+ self.assertTrue( m is logilab.common.fileutils )
from logilab.common.testlib import DocTest
class ModuleDocTest(DocTest):
diff --git a/test/unittest_shellutils.py b/test/unittest_shellutils.py
index fb9e1ca..d883c08 100644
--- a/test/unittest_shellutils.py
+++ b/test/unittest_shellutils.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -117,7 +117,7 @@ class ProgressBarTC(TestCase):
pgb.update()
if update or (update is None and dots != last):
last = dots
- expected_stream.write("\r["+('.'*dots)+(' '*(size-dots))+"]")
+ expected_stream.write("\r["+('='*dots)+(' '*(size-dots))+"]")
self.assertEqual(pgb_stream.getvalue(), expected_stream.getvalue())
def test_default(self):
@@ -152,10 +152,10 @@ class ProgressBarTC(TestCase):
last = 0
for dots in xrange(10, 105, 15):
pgb.update(dots, exact=True)
- dots /= 5
- expected_stream.write("\r["+('.'*dots)+(' '*(size-dots))+"]")
+ dots //= 5
+ expected_stream.write("\r["+('='*dots)+(' '*(size-dots))+"]")
self.assertEqual(pgb_stream.getvalue(), expected_stream.getvalue())
-
+
def test_update_relative(self):
pgb_stream = StringIO()
expected_stream = StringIO()
@@ -164,8 +164,8 @@ class ProgressBarTC(TestCase):
last = 0
for dots in xrange(5, 105, 5):
pgb.update(5, exact=False)
- dots /= 5
- expected_stream.write("\r["+('.'*dots)+(' '*(size-dots))+"]")
+ dots //= 5
+ expected_stream.write("\r["+('='*dots)+(' '*(size-dots))+"]")
self.assertEqual(pgb_stream.getvalue(), expected_stream.getvalue())
diff --git a/test/unittest_table.py b/test/unittest_table.py
index 57fea86..d2db8b7 100644
--- a/test/unittest_table.py
+++ b/test/unittest_table.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -65,14 +65,14 @@ class TableTC(TestCase):
def test_indexation(self):
"""we should be able to use [] to access rows"""
- self.assert_(self.table[0] == self.table.data[0])
- self.assert_(self.table[1] == self.table.data[1])
+ self.assertTrue(self.table[0] == self.table.data[0])
+ self.assertTrue(self.table[1] == self.table.data[1])
def test_iterable(self):
"""test iter(table)"""
it = iter(self.table)
- self.assert_(it.next() == self.table.data[0])
- self.assert_(it.next() == self.table.data[1])
+ self.assertTrue(it.next() == self.table.data[0])
+ self.assertTrue(it.next() == self.table.data[1])
def test_get_rows(self):
"""tests Table.get_rows()"""
@@ -308,7 +308,7 @@ class TableStyleSheetTC(TestCase):
self.stylesheet.add_rowavg_rule((0, 2), 0, 0, 1)
self.table.apply_stylesheet(self.stylesheet)
val = self.table[0, 2]
- self.assert_(int(val) == 15)
+ self.assertTrue(int(val) == 15)
def test_rowsum_rule(self):
@@ -318,7 +318,7 @@ class TableStyleSheetTC(TestCase):
self.stylesheet.add_rowsum_rule((0, 2), 0, 0, 1)
self.table.apply_stylesheet(self.stylesheet)
val = self.table[0, 2]
- self.assert_(val == 30)
+ self.assertTrue(val == 30)
def test_colavg_rule(self):
@@ -330,7 +330,7 @@ class TableStyleSheetTC(TestCase):
self.stylesheet.add_colavg_rule((2, 0), 0, 0, 1)
self.table.apply_stylesheet(self.stylesheet)
val = self.table[2, 0]
- self.assert_(int(val) == 11)
+ self.assertTrue(int(val) == 11)
def test_colsum_rule(self):
@@ -342,7 +342,7 @@ class TableStyleSheetTC(TestCase):
self.stylesheet.add_colsum_rule((2, 0), 0, 0, 1)
self.table.apply_stylesheet(self.stylesheet)
val = self.table[2, 0]
- self.assert_(val == 22)
+ self.assertTrue(val == 22)
diff --git a/test/unittest_testlib.py b/test/unittest_testlib.py
index dad561a..4ea8242 100644
--- a/test/unittest_testlib.py
+++ b/test/unittest_testlib.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -121,29 +121,6 @@ class TestlibTC(TestCase):
invalid = """<root><h2 </h2> </root>"""
self.assertRaises(AssertionError, self.tc.assertXMLStringWellFormed, invalid)
- def test_unordered_equality_for_lists(self):
- l1 = [0, 1, 2]
- l2 = [1, 2, 3]
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, l1, l2)
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, l1, l2)
- self.tc.assertItemsEqual(l1, l1)
- self.tc.assertItemsEqual(l1, l1)
- self.tc.assertItemsEqual([], [])
- self.tc.assertItemsEqual([], [])
- l1 = [0, 1, 1]
- l2 = [0, 1]
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, l1, l2)
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, l1, l2)
- self.tc.assertItemsEqual(l1, l1)
- self.tc.assertItemsEqual(l1, l1)
-
- def test_unordered_equality_for_dicts(self):
- d1 = {'a' : 1, 'b' : 2}
- d2 = {'a' : 1}
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, d1, d2)
- self.tc.assertItemsEqual(d1, d1)
- self.tc.assertItemsEqual({}, {})
-
def test_equality_for_sets(self):
s1 = set('ab')
s2 = set('a')
@@ -151,14 +128,6 @@ class TestlibTC(TestCase):
self.tc.assertSetEqual(s1, s1)
self.tc.assertSetEqual(set(), set())
- def test_unordered_equality_for_iterables(self):
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, xrange(5), xrange(6))
- self.assertRaises(AssertionError, self.tc.assertItemsEqual, xrange(5), xrange(6))
- self.tc.assertItemsEqual(xrange(5), range(5))
- self.tc.assertItemsEqual(xrange(5), range(5))
- self.tc.assertItemsEqual([], ())
- self.tc.assertItemsEqual([], ())
-
def test_file_equality(self):
foo = join(dirname(__file__), 'data', 'foo.txt')
spam = join(dirname(__file__), 'data', 'spam.txt')
@@ -235,10 +204,6 @@ class TestlibTC(TestCase):
# class' custom datadir
tc = MyTC('test_1')
self.assertEqual(tc.datapath('bar'), join('foo', 'bar'))
- # instance's custom datadir
- self.skipTest('should this really work?')
- tc.datadir = 'spam'
- self.assertEqual(tc.datapath('bar'), join('spam', 'bar'))
def test_cached_datadir(self):
"""test datadir is cached on the class"""
@@ -788,6 +753,9 @@ class TagTC(TestCase):
self.assertTrue(tags.match('other or (testing and bob)'))
def test_tagged_class(self):
+ if sys.version_info > (3, 0):
+ self.skipTest('fix me for py3k')
+
def options(tags):
class Options(object):
tags_pattern = tags
diff --git a/test/unittest_umessage.py b/test/unittest_umessage.py
index 2d14a26..6bf56c6 100644
--- a/test/unittest_umessage.py
+++ b/test/unittest_umessage.py
@@ -1,5 +1,5 @@
# encoding: iso-8859-15
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
diff --git a/testlib.py b/testlib.py
index a35ad98..fe519ec 100644
--- a/testlib.py
+++ b/testlib.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -53,9 +53,11 @@ import warnings
from shutil import rmtree
from operator import itemgetter
from ConfigParser import ConfigParser
-from logilab.common.deprecation import deprecated
from itertools import dropwhile
+from logilab.common.deprecation import deprecated
+from logilab.common.compat import builtins
+
import unittest as unittest_legacy
if not getattr(unittest_legacy, "__package__", None):
try:
@@ -950,7 +952,7 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
def assertTextEquals(self, text1, text2, junk=None,
msg_prefix='Text differ', striplines=False):
"""compare two multiline strings (using difflib and splitlines())
-
+
:param text1: a Python BaseString
:param text2: a second Python Basestring
:param junk: List of Caracters
@@ -1022,7 +1024,7 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
partial_iter = True
- self.assert_(ipath_a == ipath_b,
+ self.assertTrue(ipath_a == ipath_b,
"unexpected %s in %s while looking %s from %s" %
(ipath_a, path_a, ipath_b, path_b))
@@ -1080,9 +1082,9 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
msg = '%r is not an instance of %s but of %s'
msg = msg % (obj, klass, type(obj))
if strict:
- self.assert_(obj.__class__ is klass, msg)
+ self.assertTrue(obj.__class__ is klass, msg)
else:
- self.assert_(isinstance(obj, klass), msg)
+ self.assertTrue(isinstance(obj, klass), msg)
@deprecated('Please use assertIsNone instead.')
def assertNone(self, obj, msg=None):
@@ -1092,14 +1094,14 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
"""
if msg is None:
msg = "reference to %r when None expected"%(obj,)
- self.assert_( obj is None, msg )
+ self.assertTrue( obj is None, msg )
@deprecated('Please use assertIsNotNone instead.')
def assertNotNone(self, obj, msg=None):
"""assert obj is not None"""
if msg is None:
msg = "unexpected reference to None"
- self.assert_( obj is not None, msg )
+ self.assertTrue( obj is not None, msg )
@deprecated('Non-standard. Please use assertAlmostEqual instead.')
def assertFloatAlmostEquals(self, obj, other, prec=1e-5,
@@ -1117,7 +1119,7 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
msg = "%r != %r" % (obj, other)
if relative:
prec = prec*math.fabs(obj)
- self.assert_(math.fabs(obj - other) < prec, msg)
+ self.assertTrue(math.fabs(obj - other) < prec, msg)
def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs):
"""override default failUnlessRaises method to return the raised
@@ -1166,6 +1168,10 @@ succeeded test into", osp.join(os.getcwd(), FILE_RESTART)
assertRaises = failUnlessRaises
+ if not hasattr(unittest.TestCase, 'assertItemsEqual'):
+ # python 3.2 has deprecated assertSameElements and is missing
+ # assertItemsEqual
+ assertItemsEqual = unittest.TestCase.assertSameElements
import doctest
@@ -1216,12 +1222,12 @@ class DocTest(TestCase):
suite = SkippedSuite()
# doctest may gork the builtins dictionnary
# This happen to the "_" entry used by gettext
- old_builtins = __builtins__.copy()
+ old_builtins = builtins.__dict__.copy()
try:
return suite.run(result)
finally:
- __builtins__.clear()
- __builtins__.update(old_builtins)
+ builtins.__dict__.clear()
+ builtins.__dict__.update(old_builtins)
run = __call__
def test(self):
diff --git a/umessage.py b/umessage.py
index 85d564c..c597c17 100644
--- a/umessage.py
+++ b/umessage.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
@@ -15,12 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
-"""Unicode email support (extends email from stdlib).
+"""Unicode email support (extends email from stdlib)"""
-
-
-
-"""
__docformat__ = "restructuredtext en"
import email
@@ -79,27 +75,13 @@ class UMessage:
return decode_QP(value)
return value
+ def __getitem__(self, header):
+ return self.get(header)
+
def get_all(self, header, default=()):
return [decode_QP(val) for val in self.message.get_all(header, default)
if val is not None]
- def get_payload(self, index=None, decode=False):
- message = self.message
- if index is None:
- payload = message.get_payload(index, decode)
- if isinstance(payload, list):
- return [UMessage(msg) for msg in payload]
- if message.get_content_maintype() != 'text':
- return payload
-
- charset = message.get_content_charset() or 'iso-8859-1'
- if search_function(charset) is None:
- charset = 'iso-8859-1'
- return unicode(payload or '', charset, "replace")
- else:
- payload = UMessage(message.get_payload(index, decode))
- return payload
-
def is_multipart(self):
return self.message.is_multipart()
@@ -110,20 +92,61 @@ class UMessage:
for part in self.message.walk():
yield UMessage(part)
- def get_content_maintype(self):
- return unicode(self.message.get_content_maintype())
+ if sys.version_info < (3, 0):
+
+ def get_payload(self, index=None, decode=False):
+ message = self.message
+ if index is None:
+ payload = message.get_payload(index, decode)
+ if isinstance(payload, list):
+ return [UMessage(msg) for msg in payload]
+ if message.get_content_maintype() != 'text':
+ return payload
+
+ charset = message.get_content_charset() or 'iso-8859-1'
+ if search_function(charset) is None:
+ charset = 'iso-8859-1'
+ return unicode(payload or '', charset, "replace")
+ else:
+ payload = UMessage(message.get_payload(index, decode))
+ return payload
+
+ def get_content_maintype(self):
+ return unicode(self.message.get_content_maintype())
+
+ def get_content_type(self):
+ return unicode(self.message.get_content_type())
+
+ def get_filename(self, failobj=None):
+ value = self.message.get_filename(failobj)
+ if value is failobj:
+ return value
+ try:
+ return unicode(value)
+ except UnicodeDecodeError:
+ return u'error decoding filename'
+
+ else:
+
+ def get_payload(self, index=None, decode=False):
+ message = self.message
+ if index is None:
+ payload = message.get_payload(index, decode)
+ if isinstance(payload, list):
+ return [UMessage(msg) for msg in payload]
+ return payload
+ else:
+ payload = UMessage(message.get_payload(index, decode))
+ return payload
+
+ def get_content_maintype(self):
+ return self.message.get_content_maintype()
- def get_content_type(self):
- return unicode(self.message.get_content_type())
+ def get_content_type(self):
+ return self.message.get_content_type()
- def get_filename(self, failobj=None):
- value = self.message.get_filename(failobj)
- if value is failobj:
- return value
- try:
- return unicode(value)
- except UnicodeDecodeError:
- return u'error decoding filename'
+ def get_filename(self, failobj=None):
+ return self.message.get_filename(failobj)
# other convenience methods ###############################################