Skip to content

Commit 3a11f00

Browse files
committed
Merge remote branch 'y-p/fix_unicode'
* 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.
2 parents 0c12d0a + 9406ef3 commit 3a11f00

File tree

2 files changed

+57
-14
lines changed

2 files changed

+57
-14
lines changed

pandas/tests/test_common.py

+8-13
Original file line numberDiff line numberDiff line change
@@ -309,22 +309,17 @@ def test_2d_float32(self):
309309
tm.assert_almost_equal(result, expected)
310310

311311
def test_console_encode(self):
312-
import sys
313-
314-
if py3compat.PY3 or sys.stdin.encoding is None:
312+
"""
313+
On Python 2, if sys.stdin.encoding is None (IPython with zmq frontend)
314+
common.console_encode should encode things as utf-8.
315+
"""
316+
if py3compat.PY3:
315317
raise nose.SkipTest
316318

317-
# stub test
318-
# need to mock-out sys.stdin.encoding=None for real test
319-
result = com.console_encode(u"\u05d0")
320-
try:
321-
expected = u"\u05d0".encode(sys.stdin.encoding)
322-
323-
# lot of console encodings, ISO-8869-1, cp850, etc. won't encode
324-
# this character
319+
with tm.stdin_encoding(encoding=None):
320+
result = com.console_encode(u"\u05d0")
321+
expected = u"\u05d0".encode('utf-8')
325322
self.assertEqual(result, expected)
326-
except UnicodeEncodeError:
327-
pass
328323

329324

330325
if __name__ == '__main__':

pandas/util/testing.py

+49-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import string
88
import sys
99

10+
from contextlib import contextmanager # contextlib is available since 2.5
11+
1012
from distutils.version import LooseVersion
1113

1214
from numpy.random import randn
@@ -23,7 +25,6 @@
2325
from pandas.tseries.period import PeriodIndex
2426
from pandas.tseries.interval import IntervalIndex
2527

26-
2728
Index = index.Index
2829
Series = series.Series
2930
DataFrame = frame.DataFrame
@@ -385,3 +386,50 @@ def test_network(self):
385386

386387
t.network = True
387388
return t
389+
390+
391+
class SimpleMock(object):
392+
"""
393+
Poor man's mocking object
394+
395+
Note: only works for new-style classes, assumes __getattribute__ exists.
396+
397+
>>> a = type("Duck",(),{})
398+
>>> a.attr1,a.attr2 ="fizz","buzz"
399+
>>> b = SimpleMock(a,"attr1","bar")
400+
>>> b.attr1 == "bar" and b.attr2 == "buzz"
401+
True
402+
>>> a.attr1 == "fizz" and a.attr2 == "buzz"
403+
True
404+
"""
405+
def __init__(self, obj, *args, **kwds):
406+
assert(len(args) % 2 == 0)
407+
attrs = kwds.get("attrs", {})
408+
attrs.update({k:v for k, v in zip(args[::2], args[1::2])})
409+
self.attrs = attrs
410+
self.obj = obj
411+
412+
def __getattribute__(self,name):
413+
attrs = object.__getattribute__(self, "attrs")
414+
obj = object.__getattribute__(self, "obj")
415+
return attrs.get(name, type(obj).__getattribute__(obj,name))
416+
417+
@contextmanager
418+
def stdin_encoding(encoding=None):
419+
"""
420+
Context manager for running bits of code while emulating an arbitrary
421+
stdin encoding.
422+
423+
>>> import sys
424+
>>> _encoding = sys.stdin.encoding
425+
>>> with stdin_encoding('AES'): sys.stdin.encoding
426+
'AES'
427+
>>> sys.stdin.encoding==_encoding
428+
True
429+
430+
"""
431+
import sys
432+
_stdin = sys.stdin
433+
sys.stdin = SimpleMock(sys.stdin, "encoding", encoding)
434+
yield
435+
sys.stdin = _stdin

0 commit comments

Comments
 (0)