[F] views: fix 2 unicode errors
1. You can now use valid unicode strings in ValidationError exception.
Previously, if 'err' contains unicode, UnicodeDecodeError was raised by format_errors()
>>> templstr = '<li>%s</li>\n'
>>> e = ValidationError(None, {None: u'oué, une exception en unicode!'})
>>> templstr % e
'<li>None (None): ou\xc3\xa9, une exception en unicode!</li>\n'
>>> templstr = u'<li>%s</li>\n'
>>> templstr % e
u'<li>None (None): ou\xe9, une exception en unicode!</li>\n'
2. The message of an Exception can contains unicode. But it now properly managed by “informal” string representation.
We can easily fix the problem by using the Exception.message attribute that still contains the original message.
>>> a = AssertionError(u'séfdsdf')
>>> a.message
u's\xe9fdsdf'
>>> str(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 1: ordinal not in range(128)
>>> a = ValueError(u'fsdfsdéfsdfs')
>>> str(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)
>>> a
ValueError(u'fsdfsd\xe9fsdfs',)
>>> unicode(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)
>>> a.message
u'fsdfsd\xe9fsdfs'
""":organization: Logilab:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""importsysimportosfromos.pathimportdirname,join,abspathfromlogilab.common.modutilsimportcleanup_sys_modulesfromlogilab.common.testlibimportTestCase,unittest_mainfromlogilab.common.changelogimportVersionfromcubicweb.devtoolsimportApptestConfigurationdefunabsolutize(path):parts=path.split(os.sep)fori,partinreversed(tuple(enumerate(parts))):ifpart.startswith('cubicweb')orpart=='cubes':return'/'.join(parts[i+1:])raiseException('duh? %s'%path)CUSTOM_CUBES_DIR=abspath(join(dirname(__file__),'data','cubes'))classCubicWebConfigurationTC(TestCase):defsetUp(self):cleanup_sys_modules([CUSTOM_CUBES_DIR,ApptestConfiguration.CUBES_DIR])self.config=ApptestConfiguration('data')self.config._cubes=('email','file')deftearDown(self):os.environ.pop('CW_CUBES_PATH',None)deftest_reorder_cubes(self):# jpl depends on email and file and comment# email depends on fileself.assertEquals(self.config.reorder_cubes(['file','email','forge']),('forge','email','file'))self.assertEquals(self.config.reorder_cubes(['email','file','forge']),('forge','email','file'))self.assertEquals(self.config.reorder_cubes(['email','forge','file']),('forge','email','file'))self.assertEquals(self.config.reorder_cubes(['file','forge','email']),('forge','email','file'))self.assertEquals(self.config.reorder_cubes(['forge','file','email']),('forge','email','file'))self.assertEquals(self.config.reorder_cubes(('forge','email','file')),('forge','email','file'))deftest_reorder_cubes_recommends(self):fromcubes.commentimport__pkginfo__ascomment_pkginfocomment_pkginfo.__recommend__=('file',)try:# email recommends comment# comment recommends fileself.assertEquals(self.config.reorder_cubes(('forge','email','file','comment')),('forge','email','comment','file'))self.assertEquals(self.config.reorder_cubes(('forge','email','comment','file')),('forge','email','comment','file'))self.assertEquals(self.config.reorder_cubes(('forge','comment','email','file')),('forge','email','comment','file'))self.assertEquals(self.config.reorder_cubes(('comment','forge','email','file')),('forge','email','comment','file'))finally:comment_pkginfo.__use__=()# def test_vc_config(self):# vcconf = self.config.vc_config()# self.assertIsInstance(vcconf['EEMAIL'], Version)# self.assertEquals(vcconf['EEMAIL'], (0, 3, 1))# self.assertEquals(vcconf['CW'], (2, 31, 2))# self.assertRaises(KeyError, vcconf.__getitem__, 'CW_VERSION')# self.assertRaises(KeyError, vcconf.__getitem__, 'CRM')deftest_expand_cubes(self):self.assertEquals(self.config.expand_cubes(('email','blog')),['email','blog','file'])deftest_vregistry_path(self):self.assertEquals([unabsolutize(p)forpinself.config.vregistry_path()],['entities','web/views','sobjects','hooks','file/entities.py','file/views','file/hooks.py','email/entities.py','email/views','email/hooks.py','test/data/entities.py','test/data/views.py'])deftest_cubes_path(self):# make sure we don't import the email cube, but the stdlib email packageimportemailself.assertNotEquals(dirname(email.__file__),self.config.CUBES_DIR)os.environ['CW_CUBES_PATH']=CUSTOM_CUBES_DIRself.assertEquals(self.config.cubes_search_path(),[CUSTOM_CUBES_DIR,self.config.CUBES_DIR])os.environ['CW_CUBES_PATH']=os.pathsep.join([CUSTOM_CUBES_DIR,self.config.CUBES_DIR,'unexistant'])# filter out unexistant and duplicatesself.assertEquals(self.config.cubes_search_path(),[CUSTOM_CUBES_DIR,self.config.CUBES_DIR])self.failUnless('mycube'inself.config.available_cubes())# test cubes python pathself.config.adjust_sys_path()importcubesself.assertEquals(cubes.__path__,self.config.cubes_search_path())# this import should succeed once path is adjustedfromcubesimportmycubeself.assertEquals(mycube.__path__,[join(CUSTOM_CUBES_DIR,'mycube')])# file cube should be overriden by the one found in data/cubessys.modules.pop('cubes.file',None)delcubes.filefromcubesimportfileself.assertEquals(file.__path__,[join(CUSTOM_CUBES_DIR,'file')])if__name__=='__main__':unittest_main()