From b15c61b8422c4157be4ae9b3ac2580855cf0e0a2 Mon Sep 17 00:00:00 2001 From: y-p Date: Wed, 12 Dec 2012 13:01:57 +0200 Subject: [PATCH 1/5] ENH: Support callback functions to be called on config.option set/reset --- pandas/core/config.py | 16 ++++++++++++---- pandas/tests/test_config.py | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/pandas/core/config.py b/pandas/core/config.py index 9bd62c38fa8e5..5a2e6ef093f30 100644 --- a/pandas/core/config.py +++ b/pandas/core/config.py @@ -25,7 +25,9 @@ - all options in a certain sub - namespace can be reset at once. - the user can set / get / reset or ask for the description of an option. - a developer can register and mark an option as deprecated. - +- you can register a callback to be invoked when the the option value + is set or reset. Changing the stored value is considered misuse, but + is not verboten. Implementation ============== @@ -54,7 +56,7 @@ import warnings DeprecatedOption = namedtuple('DeprecatedOption', 'key msg rkey removal_ver') -RegisteredOption = namedtuple('RegisteredOption', 'key defval doc validator') +RegisteredOption = namedtuple('RegisteredOption', 'key defval doc validator cb') _deprecated_options = {} # holds deprecated option metdata _registered_options = {} # holds registered option metdata @@ -105,6 +107,9 @@ def _set_option(pat, value): root, k = _get_root(key) root[k] = value + if o and o.cb: + o.cb(key) + def _describe_option(pat='', _print_desc=True): @@ -270,7 +275,7 @@ def __doc__(self): ###################################################### # Functions for use by pandas developers, in addition to User - api -def register_option(key, defval, doc='', validator=None): +def register_option(key, defval, doc='', validator=None, cb=None): """Register an option in the package-wide pandas config object Parameters @@ -280,6 +285,9 @@ def register_option(key, defval, doc='', validator=None): doc - a string description of the option validator - a function of a single argument, should raise `ValueError` if called with a value which is not a legal value for the option. + cb - a function of a single argument "key", which is called + immediately after an option value is set/reset. key is + the full name of the option. Returns ------- @@ -321,7 +329,7 @@ def register_option(key, defval, doc='', validator=None): # save the option metadata _registered_options[key] = RegisteredOption(key=key, defval=defval, - doc=doc, validator=validator) + doc=doc, validator=validator,cb=cb) def deprecate_option(key, msg=None, rkey=None, removal_ver=None): diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index 814281dfc25e9..828bc85df4289 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -282,6 +282,31 @@ def test_config_prefix(self): self.assertEqual(self.cf.get_option('a'), 1) self.assertEqual(self.cf.get_option('b'), 2) + def test_callback(self): + k=[None] + v=[None] + def callback(key): + k.append(key) + v.append(self.cf.get_option(key)) + + self.cf.register_option('d.a', 'foo',cb=callback) + self.cf.register_option('d.b', 'foo',cb=callback) + + del k[-1],v[-1] + self.cf.set_option("d.a","fooz") + self.assertEqual(k[-1],"d.a") + self.assertEqual(v[-1],"fooz") + + del k[-1],v[-1] + self.cf.set_option("d.b","boo") + self.assertEqual(k[-1],"d.b") + self.assertEqual(v[-1],"boo") + + del k[-1],v[-1] + self.cf.reset_option("d.b") + self.assertEqual(k[-1],"d.b") + + # fmt.reset_printoptions and fmt.set_printoptions were altered # to use core.config, test_format exercises those paths. From d923c914bf0646461c1e0413f05c50a37466c19a Mon Sep 17 00:00:00 2001 From: y-p Date: Thu, 13 Dec 2012 09:55:53 +0200 Subject: [PATCH 2/5] CLN: create mode.use_inf_as_null, mode.sim_interactive options --- pandas/core/common.py | 7 ++++--- pandas/core/config_init.py | 23 ++++++++++++++++++++--- pandas/tests/test_common.py | 9 +++++---- pandas/tests/test_format.py | 32 ++++++++++++++++---------------- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/pandas/core/common.py b/pandas/core/common.py index d77d413d39571..386343dc38704 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -94,8 +94,8 @@ def isnull_old(obj): else: return obj is None -def use_inf_as_null(flag): - ''' +def _use_inf_as_null(key): + '''Option change callback for null/inf behaviour Choose which replacement for numpy.isnan / -numpy.isfinite is used. Parameters @@ -113,6 +113,7 @@ def use_inf_as_null(flag): * http://stackoverflow.com/questions/4859217/ programmatically-creating-variables-in-python/4859312#4859312 ''' + flag = get_option(key) if flag == True: globals()['isnull'] = isnull_old else: @@ -1179,7 +1180,7 @@ def in_interactive_session(): returns True if running under python/ipython interactive shell """ import __main__ as main - return not hasattr(main, '__file__') or get_option('test.interactive') + return not hasattr(main, '__file__') or get_option('mode.sim_interactive') def in_qtconsole(): """ diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index a854c012226cf..b2443e5b0b14e 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -139,10 +139,27 @@ cf.register_option('expand_frame_repr', True, pc_expand_repr_doc) cf.register_option('line_width', 80, pc_line_width_doc) -tc_interactive_doc=""" +tc_sim_interactive_doc=""" : boolean Default False Whether to simulate interactive mode for purposes of testing """ -with cf.config_prefix('test'): - cf.register_option('interactive', False, tc_interactive_doc) +with cf.config_prefix('mode'): + cf.register_option('sim_interactive', False, tc_sim_interactive_doc) + +use_inf_as_null_doc=""" +: boolean + True means treat None, NaN, INF, -INF as null (old way), + False means None and NaN are null, but INF, -INF are not null + (new way). +""" + +# we don't want to start importing evrything at the global context level +# or we'll hit circular deps. +def use_inf_as_null_cb(key): + from pandas.core.common import _use_inf_as_null + _use_inf_as_null(key) + +with cf.config_prefix('mode'): + cf.register_option('use_inf_as_null', False, use_inf_as_null_doc, + cb=use_inf_as_null_cb) diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index e8be2a5cc9c4c..1646d71164834 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -5,9 +5,10 @@ import unittest from pandas import Series, DataFrame, date_range, DatetimeIndex -from pandas.core.common import notnull, isnull, use_inf_as_null +from pandas.core.common import notnull, isnull import pandas.core.common as com import pandas.util.testing as tm +import pandas.core.config as cf import numpy as np @@ -29,15 +30,15 @@ def test_notnull(): assert not notnull(None) assert not notnull(np.NaN) - use_inf_as_null(False) + cf.set_option("mode.use_inf_as_null",False) assert notnull(np.inf) assert notnull(-np.inf) - use_inf_as_null(True) + cf.set_option("mode.use_inf_as_null",True) assert not notnull(np.inf) assert not notnull(-np.inf) - use_inf_as_null(False) + cf.set_option("mode.use_inf_as_null",False) float_series = Series(np.random.randn(5)) obj_series = Series(np.random.randn(5), dtype=object) diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index 8b4866a643dde..7c93ece23237b 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -112,11 +112,11 @@ def test_repr_should_return_str (self): self.assertTrue(type(df.__repr__() == str)) # both py2 / 3 def test_repr_no_backslash(self): - pd.set_option('test.interactive', True) + pd.set_option('mode.sim_interactive', True) df = DataFrame(np.random.randn(10, 4)) self.assertTrue('\\' not in repr(df)) - pd.reset_option('test.interactive') + pd.reset_option('mode.sim_interactive') def test_to_string_repr_unicode(self): buf = StringIO() @@ -409,7 +409,7 @@ def test_frame_info_encoding(self): fmt.set_printoptions(max_rows=200) def test_wide_repr(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) col = lambda l, k: [tm.rands(k) for _ in xrange(l)] df = DataFrame([col(20, 25) for _ in range(10)]) set_option('print.expand_frame_repr', False) @@ -423,19 +423,19 @@ def test_wide_repr(self): self.assert_(len(wider_repr) < len(wide_repr)) reset_option('print.expand_frame_repr') - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) set_option('print.line_width', 80) def test_wide_repr_wide_columns(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) df = DataFrame(randn(5, 3), columns=['a' * 90, 'b' * 90, 'c' * 90]) rep_str = repr(df) self.assert_(len(rep_str.splitlines()) == 20) - reset_option('test.interactive') + reset_option('mode.sim_interactive') def test_wide_repr_named(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) col = lambda l, k: [tm.rands(k) for _ in xrange(l)] df = DataFrame([col(20, 25) for _ in range(10)]) df.index.name = 'DataFrame Index' @@ -454,11 +454,11 @@ def test_wide_repr_named(self): self.assert_('DataFrame Index' in line) reset_option('print.expand_frame_repr') - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) set_option('print.line_width', 80) def test_wide_repr_multiindex(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) col = lambda l, k: [tm.rands(k) for _ in xrange(l)] midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), np.array(col(10, 5))]) @@ -479,11 +479,11 @@ def test_wide_repr_multiindex(self): self.assert_('Level 0 Level 1' in line) reset_option('print.expand_frame_repr') - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) set_option('print.line_width', 80) def test_wide_repr_multiindex_cols(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) col = lambda l, k: [tm.rands(k) for _ in xrange(l)] midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), np.array(col(10, 5))]) @@ -505,11 +505,11 @@ def test_wide_repr_multiindex_cols(self): self.assert_(len(wide_repr.splitlines()) == 14 * 10 - 1) reset_option('print.expand_frame_repr') - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) set_option('print.line_width', 80) def test_wide_repr_unicode(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) col = lambda l, k: [tm.randu(k) for _ in xrange(l)] df = DataFrame([col(20, 25) for _ in range(10)]) set_option('print.expand_frame_repr', False) @@ -523,18 +523,18 @@ def test_wide_repr_unicode(self): self.assert_(len(wider_repr) < len(wide_repr)) reset_option('print.expand_frame_repr') - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) set_option('print.line_width', 80) def test_wide_repr_wide_long_columns(self): - set_option('test.interactive', True) + set_option('mode.sim_interactive', True) df = DataFrame({'a': ['a'*30, 'b'*30], 'b': ['c'*70, 'd'*80]}) result = repr(df) self.assertTrue('ccccc' in result) self.assertTrue('ddddd' in result) - set_option('test.interactive', False) + set_option('mode.sim_interactive', False) def test_to_string(self): from pandas import read_table From 7d14136614866b4a23226168b68076a641a0e2bb Mon Sep 17 00:00:00 2001 From: y-p Date: Wed, 12 Dec 2012 13:42:18 +0200 Subject: [PATCH 3/5] DOC: update docs to reflect new mode.use_inf_as_null option --- RELEASE.rst | 2 +- doc/source/missing_data.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE.rst b/RELEASE.rst index 26f3265029696..890425b729324 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -99,7 +99,7 @@ pandas 0.10.0 instead. This is a legacy hack and can lead to subtle bugs. - inf/-inf are no longer considered as NA by isnull/notnull. To be clear, this is legacy cruft from early pandas. This behavior can be globally re-enabled - using pandas.core.common.use_inf_as_na (#2050, #1919) + using the new option ``mode.use_inf_as_null`` (#2050, #1919) - ``pandas.merge`` will now default to ``sort=False``. For many use cases sorting the join keys is not necessary, and doing it by default is wasteful - ``names`` handling in file parsing: if explicit column `names` passed, diff --git a/doc/source/missing_data.rst b/doc/source/missing_data.rst index f514139a9170f..b8f3468f82098 100644 --- a/doc/source/missing_data.rst +++ b/doc/source/missing_data.rst @@ -61,7 +61,7 @@ arise and we wish to also consider that "missing" or "null". Until recently, for legacy reasons ``inf`` and ``-inf`` were also considered to be "null" in computations. This is no longer the case by -default; use the :func: `~pandas.core.common.use_inf_as_null` function to recover it. +default; use the ``mode.use_inf_as_null`` option to recover it. .. _missing.isnull: From 59315380b5cc3a10c68ec281569b37ceb4f4c99f Mon Sep 17 00:00:00 2001 From: y-p Date: Thu, 13 Dec 2012 09:52:37 +0200 Subject: [PATCH 4/5] ENH: implement option_context context manager --- pandas/core/config.py | 52 +++++++++++++++++++++++++------------ pandas/tests/test_config.py | 15 +++++++++++ 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/pandas/core/config.py b/pandas/core/config.py index 5a2e6ef093f30..87f0b205058cd 100644 --- a/pandas/core/config.py +++ b/pandas/core/config.py @@ -67,37 +67,33 @@ ########################################## # User API -def _get_option(pat): +def _get_single_key(pat, silent): keys = _select_options(pat) if len(keys) == 0: - _warn_if_deprecated(pat) + if not silent: + _warn_if_deprecated(pat) raise KeyError('No such keys(s)') if len(keys) > 1: raise KeyError('Pattern matched multiple keys') key = keys[0] - _warn_if_deprecated(key) + if not silent: + _warn_if_deprecated(key) key = _translate_key(key) + return key + +def _get_option(pat, silent=False): + key = _get_single_key(pat,silent) + # walk the nested dict root, k = _get_root(key) - return root[k] -def _set_option(pat, value): - - keys = _select_options(pat) - if len(keys) == 0: - _warn_if_deprecated(pat) - raise KeyError('No such keys(s)') - if len(keys) > 1: - raise KeyError('Pattern matched multiple keys') - key = keys[0] - - _warn_if_deprecated(key) - key = _translate_key(key) +def _set_option(pat, value, silent=False): + key = _get_single_key(pat,silent) o = _get_registered_option(key) if o and o.validator: @@ -107,7 +103,7 @@ def _set_option(pat, value): root, k = _get_root(key) root[k] = value - if o and o.cb: + if o.cb: o.cb(key) @@ -275,6 +271,28 @@ def __doc__(self): ###################################################### # Functions for use by pandas developers, in addition to User - api +class option_context(object): + def __init__(self,*args): + assert len(args) % 2 == 0 and len(args)>=2, \ + "Need to invoke as option_context(pat,val,[(pat,val),..))." + ops = zip(args[::2],args[1::2]) + undo=[] + for pat,val in ops: + undo.append((pat,_get_option(pat,silent=True))) + + self.undo = undo + + for pat,val in ops: + _set_option(pat,val,silent=True) + + def __enter__(self): + pass + + def __exit__(self, *args): + if self.undo: + for pat, val in self.undo: + _set_option(pat, val) + def register_option(key, defval, doc='', validator=None, cb=None): """Register an option in the package-wide pandas config object diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index 828bc85df4289..14d0a115c6c20 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -307,6 +307,21 @@ def callback(key): self.assertEqual(k[-1],"d.b") + def test_set_ContextManager(self): + def eq(val): + self.assertEqual(self.cf.get_option("a"),val) + + self.cf.register_option('a',0) + eq(0) + with self.cf.option_context("a",15): + eq(15) + with self.cf.option_context("a",25): + eq(25) + eq(15) + eq(0) + + self.cf.set_option("a",17) + eq(17) # fmt.reset_printoptions and fmt.set_printoptions were altered # to use core.config, test_format exercises those paths. From f5972bd266bbac5772cd9dc7ddaa2b66cf83cfc3 Mon Sep 17 00:00:00 2001 From: y-p Date: Thu, 13 Dec 2012 10:12:52 +0200 Subject: [PATCH 5/5] TST: convert tests to use option_context --- pandas/tests/test_common.py | 27 ++--- pandas/tests/test_format.py | 230 +++++++++++++++++------------------- 2 files changed, 121 insertions(+), 136 deletions(-) diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index 1646d71164834..e86df7204ab5c 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -30,20 +30,19 @@ def test_notnull(): assert not notnull(None) assert not notnull(np.NaN) - cf.set_option("mode.use_inf_as_null",False) - assert notnull(np.inf) - assert notnull(-np.inf) - - cf.set_option("mode.use_inf_as_null",True) - assert not notnull(np.inf) - assert not notnull(-np.inf) - - cf.set_option("mode.use_inf_as_null",False) - - float_series = Series(np.random.randn(5)) - obj_series = Series(np.random.randn(5), dtype=object) - assert(isinstance(notnull(float_series), Series)) - assert(isinstance(notnull(obj_series), Series)) + with cf.option_context("mode.use_inf_as_null",False): + assert notnull(np.inf) + assert notnull(-np.inf) + + with cf.option_context("mode.use_inf_as_null",True): + assert not notnull(np.inf) + assert not notnull(-np.inf) + + with cf.option_context("mode.use_inf_as_null",False): + float_series = Series(np.random.randn(5)) + obj_series = Series(np.random.randn(5), dtype=object) + assert(isinstance(notnull(float_series), Series)) + assert(isinstance(notnull(obj_series), Series)) def test_isnull(): assert not isnull(1.) diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index 7c93ece23237b..0caef2cd58ef3 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -21,7 +21,7 @@ import pandas import pandas as pd from pandas.core.config import (set_option, get_option, - reset_option) + option_context, reset_option) _frame = DataFrame(tm.getSeriesData()) @@ -75,26 +75,26 @@ def test_repr_tuples(self): def test_repr_truncation(self): max_len = 20 - set_option("print.max_colwidth", max_len) - df = DataFrame({'A': np.random.randn(10), - 'B': [tm.rands(np.random.randint(max_len - 1, - max_len + 1)) for i in range(10)]}) - r = repr(df) - r = r[r.find('\n') + 1:] - - _strlen = fmt._strlen_func() - - for line, value in zip(r.split('\n'), df['B']): - if _strlen(value) + 1 > max_len: - self.assert_('...' in line) - else: - self.assert_('...' not in line) + with option_context("print.max_colwidth", max_len): + df = DataFrame({'A': np.random.randn(10), + 'B': [tm.rands(np.random.randint(max_len - 1, + max_len + 1)) for i in range(10)]}) + r = repr(df) + r = r[r.find('\n') + 1:] + + _strlen = fmt._strlen_func() + + for line, value in zip(r.split('\n'), df['B']): + if _strlen(value) + 1 > max_len: + self.assert_('...' in line) + else: + self.assert_('...' not in line) - set_option("print.max_colwidth", 999999) - self.assert_('...' not in repr(df)) + with option_context("print.max_colwidth", 999999): + self.assert_('...' not in repr(df)) - set_option("print.max_colwidth", max_len + 2) - self.assert_('...' not in repr(df)) + with option_context("print.max_colwidth", max_len + 2): + self.assert_('...' not in repr(df)) def test_repr_should_return_str (self): """ @@ -112,11 +112,10 @@ def test_repr_should_return_str (self): self.assertTrue(type(df.__repr__() == str)) # both py2 / 3 def test_repr_no_backslash(self): - pd.set_option('mode.sim_interactive', True) - df = DataFrame(np.random.randn(10, 4)) + with option_context('mode.sim_interactive', True): + df = DataFrame(np.random.randn(10, 4)) + self.assertTrue('\\' not in repr(df)) - self.assertTrue('\\' not in repr(df)) - pd.reset_option('mode.sim_interactive') def test_to_string_repr_unicode(self): buf = StringIO() @@ -409,132 +408,119 @@ def test_frame_info_encoding(self): fmt.set_printoptions(max_rows=200) def test_wide_repr(self): - set_option('mode.sim_interactive', True) - col = lambda l, k: [tm.rands(k) for _ in xrange(l)] - df = DataFrame([col(20, 25) for _ in range(10)]) - set_option('print.expand_frame_repr', False) - rep_str = repr(df) - set_option('print.expand_frame_repr', True) - wide_repr = repr(df) - self.assert_(rep_str != wide_repr) - - set_option('print.line_width', 120) - wider_repr = repr(df) - self.assert_(len(wider_repr) < len(wide_repr)) + with option_context('mode.sim_interactive', True): + col = lambda l, k: [tm.rands(k) for _ in xrange(l)] + df = DataFrame([col(20, 25) for _ in range(10)]) + set_option('print.expand_frame_repr', False) + rep_str = repr(df) + set_option('print.expand_frame_repr', True) + wide_repr = repr(df) + self.assert_(rep_str != wide_repr) + + with option_context('print.line_width', 120): + wider_repr = repr(df) + self.assert_(len(wider_repr) < len(wide_repr)) reset_option('print.expand_frame_repr') - set_option('mode.sim_interactive', False) - set_option('print.line_width', 80) def test_wide_repr_wide_columns(self): - set_option('mode.sim_interactive', True) - df = DataFrame(randn(5, 3), columns=['a' * 90, 'b' * 90, 'c' * 90]) - rep_str = repr(df) + with option_context('mode.sim_interactive', True): + df = DataFrame(randn(5, 3), columns=['a' * 90, 'b' * 90, 'c' * 90]) + rep_str = repr(df) - self.assert_(len(rep_str.splitlines()) == 20) - reset_option('mode.sim_interactive') + self.assert_(len(rep_str.splitlines()) == 20) def test_wide_repr_named(self): - set_option('mode.sim_interactive', True) - col = lambda l, k: [tm.rands(k) for _ in xrange(l)] - df = DataFrame([col(20, 25) for _ in range(10)]) - df.index.name = 'DataFrame Index' - set_option('print.expand_frame_repr', False) + with option_context('mode.sim_interactive', True): + col = lambda l, k: [tm.rands(k) for _ in xrange(l)] + df = DataFrame([col(20, 25) for _ in range(10)]) + df.index.name = 'DataFrame Index' + set_option('print.expand_frame_repr', False) - rep_str = repr(df) - set_option('print.expand_frame_repr', True) - wide_repr = repr(df) - self.assert_(rep_str != wide_repr) + rep_str = repr(df) + set_option('print.expand_frame_repr', True) + wide_repr = repr(df) + self.assert_(rep_str != wide_repr) - set_option('print.line_width', 120) - wider_repr = repr(df) - self.assert_(len(wider_repr) < len(wide_repr)) + with option_context('print.line_width', 120): + wider_repr = repr(df) + self.assert_(len(wider_repr) < len(wide_repr)) - for line in wide_repr.splitlines()[1::13]: - self.assert_('DataFrame Index' in line) + for line in wide_repr.splitlines()[1::13]: + self.assert_('DataFrame Index' in line) reset_option('print.expand_frame_repr') - set_option('mode.sim_interactive', False) - set_option('print.line_width', 80) def test_wide_repr_multiindex(self): - set_option('mode.sim_interactive', True) - col = lambda l, k: [tm.rands(k) for _ in xrange(l)] - midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), - np.array(col(10, 5))]) - df = DataFrame([col(20, 25) for _ in range(10)], - index=midx) - df.index.names = ['Level 0', 'Level 1'] - set_option('print.expand_frame_repr', False) - rep_str = repr(df) - set_option('print.expand_frame_repr', True) - wide_repr = repr(df) - self.assert_(rep_str != wide_repr) - - set_option('print.line_width', 120) - wider_repr = repr(df) - self.assert_(len(wider_repr) < len(wide_repr)) - - for line in wide_repr.splitlines()[1::13]: - self.assert_('Level 0 Level 1' in line) + with option_context('mode.sim_interactive', True): + col = lambda l, k: [tm.rands(k) for _ in xrange(l)] + midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), + np.array(col(10, 5))]) + df = DataFrame([col(20, 25) for _ in range(10)], + index=midx) + df.index.names = ['Level 0', 'Level 1'] + set_option('print.expand_frame_repr', False) + rep_str = repr(df) + set_option('print.expand_frame_repr', True) + wide_repr = repr(df) + self.assert_(rep_str != wide_repr) + + with option_context('print.line_width', 120): + wider_repr = repr(df) + self.assert_(len(wider_repr) < len(wide_repr)) + + for line in wide_repr.splitlines()[1::13]: + self.assert_('Level 0 Level 1' in line) reset_option('print.expand_frame_repr') - set_option('mode.sim_interactive', False) - set_option('print.line_width', 80) def test_wide_repr_multiindex_cols(self): - set_option('mode.sim_interactive', True) - col = lambda l, k: [tm.rands(k) for _ in xrange(l)] - midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), - np.array(col(10, 5))]) - mcols = pandas.MultiIndex.from_arrays([np.array(col(20, 3)), - np.array(col(20, 3))]) - df = DataFrame([col(20, 25) for _ in range(10)], - index=midx, columns=mcols) - df.index.names = ['Level 0', 'Level 1'] - set_option('print.expand_frame_repr', False) - rep_str = repr(df) - set_option('print.expand_frame_repr', True) - wide_repr = repr(df) - self.assert_(rep_str != wide_repr) - - set_option('print.line_width', 120) - wider_repr = repr(df) - self.assert_(len(wider_repr) < len(wide_repr)) - - self.assert_(len(wide_repr.splitlines()) == 14 * 10 - 1) + with option_context('mode.sim_interactive', True): + col = lambda l, k: [tm.rands(k) for _ in xrange(l)] + midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)), + np.array(col(10, 5))]) + mcols = pandas.MultiIndex.from_arrays([np.array(col(20, 3)), + np.array(col(20, 3))]) + df = DataFrame([col(20, 25) for _ in range(10)], + index=midx, columns=mcols) + df.index.names = ['Level 0', 'Level 1'] + set_option('print.expand_frame_repr', False) + rep_str = repr(df) + set_option('print.expand_frame_repr', True) + wide_repr = repr(df) + self.assert_(rep_str != wide_repr) + + with option_context('print.line_width', 120): + wider_repr = repr(df) + self.assert_(len(wider_repr) < len(wide_repr)) + self.assert_(len(wide_repr.splitlines()) == 14 * 10 - 1) reset_option('print.expand_frame_repr') - set_option('mode.sim_interactive', False) - set_option('print.line_width', 80) def test_wide_repr_unicode(self): - set_option('mode.sim_interactive', True) - col = lambda l, k: [tm.randu(k) for _ in xrange(l)] - df = DataFrame([col(20, 25) for _ in range(10)]) - set_option('print.expand_frame_repr', False) - rep_str = repr(df) - set_option('print.expand_frame_repr', True) - wide_repr = repr(df) - self.assert_(rep_str != wide_repr) - - set_option('print.line_width', 120) - wider_repr = repr(df) - self.assert_(len(wider_repr) < len(wide_repr)) + with option_context('mode.sim_interactive', True): + col = lambda l, k: [tm.randu(k) for _ in xrange(l)] + df = DataFrame([col(20, 25) for _ in range(10)]) + set_option('print.expand_frame_repr', False) + rep_str = repr(df) + set_option('print.expand_frame_repr', True) + wide_repr = repr(df) + self.assert_(rep_str != wide_repr) + + with option_context('print.line_width', 120): + wider_repr = repr(df) + self.assert_(len(wider_repr) < len(wide_repr)) reset_option('print.expand_frame_repr') - set_option('mode.sim_interactive', False) - set_option('print.line_width', 80) - def test_wide_repr_wide_long_columns(self): - set_option('mode.sim_interactive', True) - df = DataFrame({'a': ['a'*30, 'b'*30], 'b': ['c'*70, 'd'*80]}) + def test_wide_repr_wide_long_columns(self): + with option_context('mode.sim_interactive', True): + df = DataFrame({'a': ['a'*30, 'b'*30], 'b': ['c'*70, 'd'*80]}) - result = repr(df) - self.assertTrue('ccccc' in result) - self.assertTrue('ddddd' in result) - set_option('mode.sim_interactive', False) + result = repr(df) + self.assertTrue('ccccc' in result) + self.assertTrue('ddddd' in result) def test_to_string(self): from pandas import read_table