Skip to content

Commit

Permalink
Merge remote branch 'y-p/fix_unicode'
Browse files Browse the repository at this point in the history
* y-p/fix_unicode:
  re-introduce fix for console_encode()
  Add test to catch broken console_encode()
  Add testing helpers for mocking and encoding tests.
  Break console_encode again.
  • Loading branch information
wesm committed Oct 1, 2012
2 parents 0c12d0a + 9406ef3 commit 3a11f00
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
21 changes: 8 additions & 13 deletions pandas/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,22 +309,17 @@ def test_2d_float32(self):
tm.assert_almost_equal(result, expected)

def test_console_encode(self):
import sys

if py3compat.PY3 or sys.stdin.encoding is None:
"""
On Python 2, if sys.stdin.encoding is None (IPython with zmq frontend)
common.console_encode should encode things as utf-8.
"""
if py3compat.PY3:
raise nose.SkipTest

# stub test
# need to mock-out sys.stdin.encoding=None for real test
result = com.console_encode(u"\u05d0")
try:
expected = u"\u05d0".encode(sys.stdin.encoding)

# lot of console encodings, ISO-8869-1, cp850, etc. won't encode
# this character
with tm.stdin_encoding(encoding=None):
result = com.console_encode(u"\u05d0")
expected = u"\u05d0".encode('utf-8')
self.assertEqual(result, expected)
except UnicodeEncodeError:
pass


if __name__ == '__main__':
Expand Down
50 changes: 49 additions & 1 deletion pandas/util/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import string
import sys

from contextlib import contextmanager # contextlib is available since 2.5

from distutils.version import LooseVersion

from numpy.random import randn
Expand All @@ -23,7 +25,6 @@
from pandas.tseries.period import PeriodIndex
from pandas.tseries.interval import IntervalIndex


Index = index.Index
Series = series.Series
DataFrame = frame.DataFrame
Expand Down Expand Up @@ -385,3 +386,50 @@ def test_network(self):

t.network = True
return t


class SimpleMock(object):
"""
Poor man's mocking object
Note: only works for new-style classes, assumes __getattribute__ exists.
>>> a = type("Duck",(),{})
>>> a.attr1,a.attr2 ="fizz","buzz"
>>> b = SimpleMock(a,"attr1","bar")
>>> b.attr1 == "bar" and b.attr2 == "buzz"
True
>>> a.attr1 == "fizz" and a.attr2 == "buzz"
True
"""
def __init__(self, obj, *args, **kwds):
assert(len(args) % 2 == 0)
attrs = kwds.get("attrs", {})
attrs.update({k:v for k, v in zip(args[::2], args[1::2])})
self.attrs = attrs
self.obj = obj

def __getattribute__(self,name):
attrs = object.__getattribute__(self, "attrs")
obj = object.__getattribute__(self, "obj")
return attrs.get(name, type(obj).__getattribute__(obj,name))

@contextmanager
def stdin_encoding(encoding=None):
"""
Context manager for running bits of code while emulating an arbitrary
stdin encoding.
>>> import sys
>>> _encoding = sys.stdin.encoding
>>> with stdin_encoding('AES'): sys.stdin.encoding
'AES'
>>> sys.stdin.encoding==_encoding
True
"""
import sys
_stdin = sys.stdin
sys.stdin = SimpleMock(sys.stdin, "encoding", encoding)
yield
sys.stdin = _stdin

0 comments on commit 3a11f00

Please sign in to comment.