From cb131b3a36f1a6e47b8ce3fa18a101360cd217fe Mon Sep 17 00:00:00 2001 From: jayfoad Date: Tue, 20 Feb 2018 14:48:42 +0000 Subject: [PATCH 1/8] Raise OptionError instead of KeyError in __getattr__. Fixes #19789. --- pandas/core/config.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/core/config.py b/pandas/core/config.py index 692aed178719d..2566a8271c476 100644 --- a/pandas/core/config.py +++ b/pandas/core/config.py @@ -196,7 +196,10 @@ def __getattr__(self, key): if prefix: prefix += "." prefix += key - v = object.__getattribute__(self, "d")[key] + d = object.__getattribute__(self, "d") + if not key in d: + raise OptionError("No such option") + v = d[key] if isinstance(v, dict): return DictWrapper(v, prefix) else: From 2adb51bd4bd8ac9b57d5de8023928033a868f939 Mon Sep 17 00:00:00 2001 From: jayfoad Date: Tue, 20 Feb 2018 15:15:31 +0000 Subject: [PATCH 2/8] Fix PEP8 issue. --- pandas/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/config.py b/pandas/core/config.py index 2566a8271c476..ac5d41b1762ff 100644 --- a/pandas/core/config.py +++ b/pandas/core/config.py @@ -197,7 +197,7 @@ def __getattr__(self, key): prefix += "." prefix += key d = object.__getattribute__(self, "d") - if not key in d: + if key not in d: raise OptionError("No such option") v = d[key] if isinstance(v, dict): From 4d7e5ac8e6369ca75e25b6d1d7733c3377ce5575 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Wed, 21 Feb 2018 14:48:28 +0000 Subject: [PATCH 3/8] Add a test. --- pandas/tests/test_config.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index 8d6f36ac6a798..d7bfe97b3304d 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -428,3 +428,7 @@ def test_option_context_scope(self): # Ensure the current context is reset assert self.cf.get_option(option_name) == original_value + + def test_dictwrapper_getattr(self): + options = self.cf.options + assert not hasattr(options, 'bananas') From 8d4f6d642acdcb7227d1e157e0f157bdbd5a841f Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Wed, 21 Feb 2018 14:52:52 +0000 Subject: [PATCH 4/8] Use try/except instead. --- pandas/core/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/config.py b/pandas/core/config.py index ac5d41b1762ff..369e0568346ef 100644 --- a/pandas/core/config.py +++ b/pandas/core/config.py @@ -196,10 +196,10 @@ def __getattr__(self, key): if prefix: prefix += "." prefix += key - d = object.__getattribute__(self, "d") - if key not in d: + try: + v = object.__getattribute__(self, "d")[key] + except KeyError: raise OptionError("No such option") - v = d[key] if isinstance(v, dict): return DictWrapper(v, prefix) else: From 8a00b3b493445a380b25377fa57937dca14a0662 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Wed, 21 Feb 2018 15:05:59 +0000 Subject: [PATCH 5/8] Add a whatsnew. --- doc/source/whatsnew/v0.23.0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index 879b245af49cd..74cd795573012 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -876,3 +876,4 @@ Other ^^^^^ - Improved error message when attempting to use a Python keyword as an identifier in a ``numexpr`` backed query (:issue:`18221`) +- Bug in :func:`pandas.core.DictWrapper.__getattr__` when looking up a non-existent key (:issue:`19789`) From 7dc1bb1f77e52dfb718660c07d37b8a2909f7b36 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Wed, 21 Feb 2018 16:28:31 +0000 Subject: [PATCH 6/8] More informative whatsnew. --- doc/source/whatsnew/v0.23.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index 74cd795573012..3edbf193e51a5 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -876,4 +876,4 @@ Other ^^^^^ - Improved error message when attempting to use a Python keyword as an identifier in a ``numexpr`` backed query (:issue:`18221`) -- Bug in :func:`pandas.core.DictWrapper.__getattr__` when looking up a non-existent key (:issue:`19789`) +- Bug in :func:`pandas.core.DictWrapper.__getattr__` which raised ``KeyError`` instead of (a subclass of) ``AttributeError`` when looking up a non-existent key (:issue:`19789`) From 57ba55b16ef4e3da5098ca22272a5902b404f3a6 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Fri, 23 Feb 2018 10:28:25 +0000 Subject: [PATCH 7/8] Add issue number and check for OptionError explicitly. --- pandas/tests/test_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index d7bfe97b3304d..91ce65dcce9b2 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -431,4 +431,6 @@ def test_option_context_scope(self): def test_dictwrapper_getattr(self): options = self.cf.options + # GH 19789 + pytest.raises(self.cf.OptionError, getattr, options, 'bananas') assert not hasattr(options, 'bananas') From ac530367f3da72a6b7b7c58a94d9bee7166e161e Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 24 Feb 2018 10:07:18 -0500 Subject: [PATCH 8/8] doc --- doc/source/whatsnew/v0.23.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index de13497292b96..1a8fa5a89468a 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -908,4 +908,4 @@ Other ^^^^^ - Improved error message when attempting to use a Python keyword as an identifier in a ``numexpr`` backed query (:issue:`18221`) -- Bug in :func:`pandas.core.DictWrapper.__getattr__` which raised ``KeyError`` instead of (a subclass of) ``AttributeError`` when looking up a non-existent key (:issue:`19789`) +- Bug in accessing a :func:`pandas.get_option`, which raised ``KeyError`` rather than ``OptionError`` when looking up a non-existant option key in some cases (:issue:`19789`)