pandas-dev / pandas

Flexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more
https://pandas.pydata.org
BSD 3-Clause "New" or "Revised" License
43.43k stars 17.85k forks source link

pandas.options.__getattr__ raises KeyError instead of AttributeError #19789

Closed jayfoad closed 6 years ago

jayfoad commented 6 years ago

Code Sample, a copy-pastable example if possible

import pandas as pd
hasattr(pd.options,'bananas') # should return False but instead raises KeyError: 'bananas'
getattr(pd.options,'bananas') # should raise AttributeError but ...
pd.options.__getattr__('bananas') # should raise AttributeError but ...

Problem description

The docs are clear that custom __getattr__ methods should return a value or raise AttributeError. pandas.options seems to raise KeyError instead. This can be a problem for generic code that iterates through the attributes of any object and expects hasattr() to behave sanely, e.g. https://github.com/Dyalog/pynapl/blob/c6f34d0323aa7370582204c73757f9cea1072794/pynapl/ObjectWrapper.py#L86

Expected Output

False
AttributeError: 'bananas'
AttributeError: 'bananas'

Output of pd.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 3.6.3.final.0 python-bits: 64 OS: Linux OS-release: 4.13.0-35-generic machine: x86_64 processor: x86_64 byteorder: little LC_ALL: None LANG: en_GB.UTF-8 LOCALE: en_GB.UTF-8 pandas: 0.22.0 pytest: None pip: 9.0.1 setuptools: 36.2.7 Cython: None numpy: 1.14.0 scipy: 0.18.1 pyarrow: None xarray: None IPython: 5.1.0 sphinx: None patsy: None dateutil: 2.6.1 pytz: 2018.3 blosc: None bottleneck: None tables: 3.3.0 numexpr: 2.6.2 feather: None matplotlib: 2.0.0 openpyxl: None xlrd: 1.0.0 xlwt: None xlsxwriter: 0.9.6 lxml: None bs4: 4.6.0 html5lib: 0.999999999 sqlalchemy: None pymysql: 0.7.11.None psycopg2: None jinja2: 2.9.6 s3fs: None fastparquet: None pandas_gbq: None pandas_datareader: None
chris-b1 commented 6 years ago

Sure, as pointed out in that issue I think we could raise an OptionError in that case as well - want to do a PR?

https://github.com/pandas-dev/pandas/commit/63fc8af2ad6bee9c90766bcb648d27a0b2748a44