2014-04-24 29 views
2

您好我注意到assertRaisesRegexp在Python 2.7上不能與unicode一起使用。 我試圖運行下面的代碼assertRaisesRegexp在Python2中與unicode一起工作

import unittest 
def raise_exception(): 
    raise Exception(u'\u4e2d\u6587')  

class TestUnicode(unittest.TestCase): 
    def test_test1(self): 
     with self.assertRaisesRegexp(Exception, u'\u4e2d\u6587'): 
      raise_exception() 

if __name__ == '__main__': 
    unittest.main() 

但有以下錯誤

Traceback (most recent call last): 
File "C:\ZChenCode\unicode.py", line 27, in test_test1 
    raise_exception() 
    File "C:\Python27\ArcGIS10.3\Lib\unittest\case.py", line 127, in __exit__ 
    if not expected_regexp.search(str(exc_value)): 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) 

看起來像Python標準庫正試圖將unicode字符串轉換爲str導致錯誤類型。 如果我使用assertRaiseRegx,這個函數在Python3上運行良好,沒有unicode問題。 關於如何使它在Python2中工作的任何建議?

回答

2

我有同樣的問題在這裏,不幸的是我不能修復它,但我有一個工作以防萬一這一點,在我的情況下,我改變了我的引發異常此:

raise Exception(u'\u4e2d\u6587'.encode('utf8'))

這對我的作品在這裏...

0

這似乎更好地工作,如果你明確地傳遞一個RegExp對象:

with self.assertRaisesRegexp(Exception, re.compile(u'\u4e2d\u6587')): 

爲assertRaisesRegexp S中的文檔uggests,你可以傳入一個字符串,只要它可以用作正則表達式,但至少對於我使用的Python版本 - 2.7.8 - 似乎已經被破壞了。

1

還有一個辦法,這是使str(exc_value)工作:

class UnicodeMsgException(Exception): 
    def __str__(self): 
     return unicode(self).encode('utf-8') 
    def __unicode__(self): 
     return self.message 
0

你可以寫一個新的斷言方法支持Unicode的:

def assertRaisesRegexpUnicode(self, expected_exception, expected_regexp, callable_obj=None, *args, **kwargs): 
    """Asserts that the message in a raised exception matches a regexp. 

    Args: 
     expected_exception: Exception class expected to be raised. 
     expected_regexp: Regexp (re pattern object or string) expected 
       to be found in error message. 
     callable_obj: Function to be called. 
     args: Extra args. 
     kwargs: Extra kwargs. 
    """ 
    if callable_obj is None: 
     return _AssertRaisesContext(expected_exception, self, expected_regexp) 
    try: 
     callable_obj(*args, **kwargs) 
    except expected_exception, exc_value: 
     if isinstance(expected_regexp, basestring): 
      expected_regexp = re.compile(expected_regexp) 
     actual = exc_value.message 
     if not expected_regexp.search(actual): 
      raise self.failureException(u'"{expected}" does not match "{actual}"'. 
       format(expected=expected_regexp.pattern, actual=actual)) 
    else: 
     if hasattr(expected_exception, '__name__'): 
      excName = expected_exception.__name__ 
     else: 
      excName = str(expected_exception) 
     raise self.failureException, "%s not raised" % excName 
0

不是重寫assertRaisesRegex像由mtoloo建議,你可以也monkeypatch unittest2.case.str像這樣:

# unittest2's assertRaisesRegex doesn't do unicode comparison. 
# Let's monkeypatch the str() function to point to unicode() 
# so that it does :) 
# For reference, this is where this patch is required: 
# https://hg.python.org/unittest2/file/tip/unittest2/case.py#l227 
try: 
    unittest2.case.str = unicode 
except Exception: 
    pass # python 3 
相關問題