From 43864098063aaeeaf0c91cc42f65d28bfbef9265 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Wed, 1 Mar 2017 14:04:48 -0500 Subject: [PATCH] API: expose pandas.api.exceptions xref #14800 --- doc/source/whatsnew/v0.20.0.txt | 23 ++++++++ pandas/api/exceptions/__init__.py | 10 ++++ pandas/tests/api/test_api.py | 78 --------------------------- pandas/tests/api/test_exceptions.py | 30 +++++++++++ pandas/tests/api/test_types.py | 83 +++++++++++++++++++++++++++++ setup.py | 1 + 6 files changed, 147 insertions(+), 78 deletions(-) create mode 100644 pandas/api/exceptions/__init__.py create mode 100644 pandas/tests/api/test_exceptions.py create mode 100644 pandas/tests/api/test_types.py diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 54df7514a882d1..555a756f6573f7 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -53,6 +53,29 @@ fixed-width text files, and :func:`read_excel` for parsing Excel files. pd.read_fwf(StringIO(data)).dtypes pd.read_fwf(StringIO(data), dtype={'a':'float64', 'b':'object'}).dtypes + +.. _whatsnew_0200.enhancements.dev_api_exceptions: + +pandas development API +^^^^^^^^^^^^^^^^^^^^^^ + +In 0.19.0, we introduced standard sub-package to present a public API, see :ref:`here `. +We are adding ``pandas.api.exceptions`` so to expose supported exceptions and warnings. (:issue:`14800`) + +The following are now part of this API: + +.. ipython:: python + + import pprint + from pandas.api import exceptions + excs = [ e for e in dir(exceptions) if not e.startswith('_') ] + pprint.pprint(excs) + +.. note:: + + These existing definitions for these are deprecated and will be removed in a future version. + + .. _whatsnew_0200.enhancements.groupby_access: Groupby Enhancements diff --git a/pandas/api/exceptions/__init__.py b/pandas/api/exceptions/__init__.py new file mode 100644 index 00000000000000..5dcd6993d25204 --- /dev/null +++ b/pandas/api/exceptions/__init__.py @@ -0,0 +1,10 @@ +# flake8: noqa + +""" public toolkit API """ + +from pandas.core.common import (PandasError, PerformanceWarning, + AmbiguousIndexError, UnsupportedFunctionCall, + UnsortedIndexError) +from pandas.tslib import OutOfBoundsDatetime +from pandas.io.common import (ParserError, DtypeWarning, + EmptyDataError, ParserWarning) diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index 8ca369f8df83a9..be5fc00d6d97d3 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -1,11 +1,7 @@ # -*- coding: utf-8 -*- -import numpy as np - import pandas as pd -from pandas.core import common as com from pandas import api -from pandas.api import types from pandas.util import testing as tm @@ -140,80 +136,6 @@ def test_api(self): self.check(api, self.allowed) -class TestTypes(Base, tm.TestCase): - - allowed = ['is_any_int_dtype', 'is_bool', 'is_bool_dtype', - 'is_categorical', 'is_categorical_dtype', 'is_complex', - 'is_complex_dtype', 'is_datetime64_any_dtype', - 'is_datetime64_dtype', 'is_datetime64_ns_dtype', - 'is_datetime64tz_dtype', 'is_datetimetz', 'is_dtype_equal', - 'is_extension_type', 'is_float', 'is_float_dtype', - 'is_floating_dtype', 'is_int64_dtype', 'is_integer', - 'is_integer_dtype', 'is_number', 'is_numeric_dtype', - 'is_object_dtype', 'is_scalar', 'is_sparse', - 'is_string_dtype', 'is_signed_integer_dtype', - 'is_timedelta64_dtype', 'is_timedelta64_ns_dtype', - 'is_unsigned_integer_dtype', 'is_period', - 'is_period_dtype', 'is_re', 'is_re_compilable', - 'is_dict_like', 'is_iterator', - 'is_list_like', 'is_hashable', - 'is_named_tuple', 'is_sequence', - 'pandas_dtype'] - - def test_types(self): - - self.check(types, self.allowed) - - def check_deprecation(self, fold, fnew): - with tm.assert_produces_warning(DeprecationWarning): - try: - result = fold('foo') - expected = fnew('foo') - self.assertEqual(result, expected) - except TypeError: - self.assertRaises(TypeError, - lambda: fnew('foo')) - except AttributeError: - self.assertRaises(AttributeError, - lambda: fnew('foo')) - - def test_deprecation_core_common(self): - - # test that we are in fact deprecating - # the pandas.core.common introspectors - for t in self.allowed: - self.check_deprecation(getattr(com, t), getattr(types, t)) - - def test_deprecation_core_common_array_equivalent(self): - - with tm.assert_produces_warning(DeprecationWarning): - com.array_equivalent(np.array([1, 2]), np.array([1, 2])) - - def test_deprecation_core_common_moved(self): - - # these are in pandas.types.common - l = ['is_datetime_arraylike', - 'is_datetime_or_timedelta_dtype', - 'is_datetimelike', - 'is_datetimelike_v_numeric', - 'is_datetimelike_v_object', - 'is_datetimetz', - 'is_int_or_datetime_dtype', - 'is_period_arraylike', - 'is_string_like', - 'is_string_like_dtype'] - - from pandas.types import common as c - for t in l: - self.check_deprecation(getattr(com, t), getattr(c, t)) - - def test_removed_from_core_common(self): - - for t in ['is_null_datelike_scalar', - 'ensure_float']: - self.assertRaises(AttributeError, lambda: getattr(com, t)) - - class TestDatetools(tm.TestCase): def test_deprecation_access_func(self): diff --git a/pandas/tests/api/test_exceptions.py b/pandas/tests/api/test_exceptions.py new file mode 100644 index 00000000000000..7335af9e0e9e1c --- /dev/null +++ b/pandas/tests/api/test_exceptions.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +import pytest +import pandas # noqa +import pandas as pd + + +@pytest.mark.parametrize( + "exc", ['PandasError', 'AmbiguousIndexError', + 'UnsupportedFunctionCall', 'UnsortedIndexError', + 'OutOfBoundsDatetime', + 'ParserError', 'PerformanceWarning', 'DtypeWarning', + 'EmptyDataError', 'ParserWarning']) +def test_exception_importable(exc): + from pandas.api import exceptions + e = getattr(exceptions, exc) + assert e is not None + + # check that we can raise on them + with pytest.raises(e): + raise e() + + +def test_catch_oob(): + from pandas.api import exceptions + + try: + pd.Timestamp('15000101') + except exceptions.OutOfBoundsDatetime: + pass diff --git a/pandas/tests/api/test_types.py b/pandas/tests/api/test_types.py new file mode 100644 index 00000000000000..686de4a196034f --- /dev/null +++ b/pandas/tests/api/test_types.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +import numpy as np + +from pandas.core import common as com +from pandas.api import types +from pandas.util import testing as tm + +from .test_api import Base + + +class TestTypes(Base, tm.TestCase): + + allowed = ['is_any_int_dtype', 'is_bool', 'is_bool_dtype', + 'is_categorical', 'is_categorical_dtype', 'is_complex', + 'is_complex_dtype', 'is_datetime64_any_dtype', + 'is_datetime64_dtype', 'is_datetime64_ns_dtype', + 'is_datetime64tz_dtype', 'is_datetimetz', 'is_dtype_equal', + 'is_extension_type', 'is_float', 'is_float_dtype', + 'is_floating_dtype', 'is_int64_dtype', 'is_integer', + 'is_integer_dtype', 'is_number', 'is_numeric_dtype', + 'is_object_dtype', 'is_scalar', 'is_sparse', + 'is_string_dtype', 'is_signed_integer_dtype', + 'is_timedelta64_dtype', 'is_timedelta64_ns_dtype', + 'is_unsigned_integer_dtype', 'is_period', + 'is_period_dtype', 'is_re', 'is_re_compilable', + 'is_dict_like', 'is_iterator', + 'is_list_like', 'is_hashable', + 'is_named_tuple', 'is_sequence', + 'pandas_dtype'] + + def test_types(self): + + self.check(types, self.allowed) + + def check_deprecation(self, fold, fnew): + with tm.assert_produces_warning(DeprecationWarning): + try: + result = fold('foo') + expected = fnew('foo') + self.assertEqual(result, expected) + except TypeError: + self.assertRaises(TypeError, + lambda: fnew('foo')) + except AttributeError: + self.assertRaises(AttributeError, + lambda: fnew('foo')) + + def test_deprecation_core_common(self): + + # test that we are in fact deprecating + # the pandas.core.common introspectors + for t in self.allowed: + self.check_deprecation(getattr(com, t), getattr(types, t)) + + def test_deprecation_core_common_array_equivalent(self): + + with tm.assert_produces_warning(DeprecationWarning): + com.array_equivalent(np.array([1, 2]), np.array([1, 2])) + + def test_deprecation_core_common_moved(self): + + # these are in pandas.types.common + l = ['is_datetime_arraylike', + 'is_datetime_or_timedelta_dtype', + 'is_datetimelike', + 'is_datetimelike_v_numeric', + 'is_datetimelike_v_object', + 'is_datetimetz', + 'is_int_or_datetime_dtype', + 'is_period_arraylike', + 'is_string_like', + 'is_string_like_dtype'] + + from pandas.types import common as c + for t in l: + self.check_deprecation(getattr(com, t), getattr(c, t)) + + def test_removed_from_core_common(self): + + for t in ['is_null_datelike_scalar', + 'ensure_float']: + self.assertRaises(AttributeError, lambda: getattr(com, t)) diff --git a/setup.py b/setup.py index cbcadce459c678..eca8c7ea003ce5 100755 --- a/setup.py +++ b/setup.py @@ -623,6 +623,7 @@ def pxd(name): packages=['pandas', 'pandas.api', 'pandas.api.types', + 'pandas.api.exceptions', 'pandas.compat', 'pandas.compat.numpy', 'pandas.computation',