Skip to content

Commit 6c09821

Browse files
jrebacknateGeorge
authored andcommitted
CLN: reorg type inference & introspection
closes pandas-dev#12503 Author: Jeff Reback <[email protected]> Closes pandas-dev#13147 from jreback/types and squashes the following commits: 244649a [Jeff Reback] CLN: reorg type inference & introspection
1 parent a35521e commit 6c09821

File tree

118 files changed

+4944
-4134
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+4944
-4134
lines changed

ci/lint.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ RET=0
88

99
if [ "$LINT" ]; then
1010
echo "Linting"
11-
for path in 'core' 'indexes' 'types' 'formats' 'io' 'stats' 'compat' 'sparse' 'tools' 'tseries' 'tests' 'computation' 'util'
11+
for path in 'api' 'core' 'indexes' 'types' 'formats' 'io' 'stats' 'compat' 'sparse' 'tools' 'tseries' 'tests' 'computation' 'util'
1212
do
1313
echo "linting -> pandas/$path"
1414
flake8 pandas/$path --filename '*.py'

doc/source/whatsnew/v0.19.0.txt

+21-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ users upgrade to this version.
1010
Highlights include:
1111

1212
- :func:`merge_asof` for asof-style time-series joining, see :ref:`here <whatsnew_0190.enhancements.asof_merge>`
13+
- pandas development api, see :ref:`here <whatsnew_0190.dev_api>`
1314

1415
.. contents:: What's new in v0.18.2
1516
:local:
@@ -20,6 +21,25 @@ Highlights include:
2021
New features
2122
~~~~~~~~~~~~
2223

24+
.. _whatsnew_0190.dev_api:
25+
26+
pandas development API
27+
^^^^^^^^^^^^^^^^^^^^^^
28+
29+
As part of making pandas APi more uniform and accessible in the future, we have created a standard
30+
sub-package of pandas, ``pandas.api`` to hold public API's. We are starting by exposing type
31+
introspection functions in ``pandas.api.types``. More sub-packages and officially sanctioned API's
32+
will be published in future versions of pandas.
33+
34+
The following are now part of this API:
35+
36+
.. ipython:: python
37+
38+
import pprint
39+
from pandas.api import types
40+
funcs = [ f for f in dir(types) if not f.startswith('_') ]
41+
pprint.pprint(funcs)
42+
2343
.. _whatsnew_0190.enhancements.asof_merge:
2444

2545
:func:`merge_asof` for asof-style time-series joining
@@ -227,7 +247,7 @@ Other enhancements
227247
- Consistent with the Python API, ``pd.read_csv()`` will now interpret ``+inf`` as positive infinity (:issue:`13274`)
228248
- The ``DataFrame`` constructor will now respect key ordering if a list of ``OrderedDict`` objects are passed in (:issue:`13304`)
229249
- ``pd.read_html()`` has gained support for the ``decimal`` option (:issue:`12907`)
230-
- A top-level function :func:`union_categorical` has been added for combining categoricals, see :ref:`Unioning Categoricals<categorical.union>` (:issue:`13361`)
250+
- A function :func:`union_categorical` has been added for combining categoricals, see :ref:`Unioning Categoricals<categorical.union>` (:issue:`13361`)
231251
- ``Series`` has gained the properties ``.is_monotonic``, ``.is_monotonic_increasing``, ``.is_monotonic_decreasing``, similar to ``Index`` (:issue:`13336`)
232252

233253
.. _whatsnew_0190.api:

pandas/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
if missing_dependencies:
1818
raise ImportError("Missing required dependencies {0}".format(missing_dependencies))
19-
19+
del hard_dependencies, dependency, missing_dependencies
2020

2121
# numpy compat
2222
from pandas.compat.numpy import *

pandas/api/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
""" public toolkit API """

pandas/api/tests/__init__.py

Whitespace-only changes.

pandas/api/tests/test_api.py

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import pandas as pd
4+
from pandas.core import common as com
5+
from pandas import api
6+
from pandas.api import types
7+
from pandas.util import testing as tm
8+
9+
_multiprocess_can_split_ = True
10+
11+
12+
class Base(object):
13+
14+
def check(self, namespace, expected, ignored=None):
15+
# see which names are in the namespace, minus optional
16+
# ignored ones
17+
# compare vs the expected
18+
19+
result = sorted([f for f in dir(namespace) if not f.startswith('_')])
20+
if ignored is not None:
21+
result = sorted(list(set(result) - set(ignored)))
22+
23+
expected = sorted(expected)
24+
tm.assert_almost_equal(result, expected)
25+
26+
27+
class TestPDApi(Base, tm.TestCase):
28+
29+
# these are optionally imported based on testing
30+
# & need to be ignored
31+
ignored = ['tests', 'rpy', 'sandbox', 'locale']
32+
33+
# top-level sub-packages
34+
lib = ['api', 'compat', 'computation', 'core',
35+
'indexes', 'formats', 'pandas',
36+
'test', 'tools', 'tseries',
37+
'types', 'util', 'options', 'io']
38+
39+
# top-level packages that are c-imports, should rename to _*
40+
# to avoid naming conflicts
41+
lib_to_rename = ['algos', 'hashtable', 'tslib', 'msgpack', 'sparse',
42+
'json', 'lib', 'index', 'parser']
43+
44+
# these are already deprecated; awaiting removal
45+
deprecated_modules = ['ols', 'stats']
46+
47+
# misc
48+
misc = ['IndexSlice', 'NaT']
49+
50+
# top-level classes
51+
classes = ['Categorical', 'CategoricalIndex', 'DataFrame', 'DateOffset',
52+
'DatetimeIndex', 'ExcelFile', 'ExcelWriter', 'Float64Index',
53+
'Grouper', 'HDFStore', 'Index', 'Int64Index', 'MultiIndex',
54+
'Period', 'PeriodIndex', 'RangeIndex',
55+
'Series', 'SparseArray', 'SparseDataFrame',
56+
'SparseSeries', 'TimeGrouper', 'Timedelta',
57+
'TimedeltaIndex', 'Timestamp']
58+
59+
# these are already deprecated; awaiting removal
60+
deprecated_classes = ['SparsePanel', 'TimeSeries', 'WidePanel',
61+
'SparseTimeSeries']
62+
63+
# these should be deperecated in the future
64+
deprecated_classes_in_future = ['Panel', 'Panel4D',
65+
'SparseList', 'Term']
66+
67+
# these should be removed from top-level namespace
68+
remove_classes_from_top_level_namespace = ['Expr']
69+
70+
# external modules exposed in pandas namespace
71+
modules = ['np', 'datetime', 'datetools']
72+
73+
# top-level functions
74+
funcs = ['bdate_range', 'concat', 'crosstab', 'cut',
75+
'date_range', 'eval',
76+
'factorize', 'get_dummies', 'get_store',
77+
'infer_freq', 'isnull', 'lreshape',
78+
'match', 'melt', 'notnull', 'offsets',
79+
'merge', 'merge_ordered', 'merge_asof',
80+
'period_range',
81+
'pivot', 'pivot_table', 'plot_params', 'qcut',
82+
'scatter_matrix',
83+
'show_versions', 'timedelta_range', 'unique',
84+
'value_counts', 'wide_to_long']
85+
86+
# top-level option funcs
87+
funcs_option = ['reset_option', 'describe_option', 'get_option',
88+
'option_context', 'set_option',
89+
'set_eng_float_format']
90+
91+
# top-level read_* funcs
92+
funcs_read = ['read_clipboard', 'read_csv', 'read_excel', 'read_fwf',
93+
'read_gbq', 'read_hdf', 'read_html', 'read_json',
94+
'read_msgpack', 'read_pickle', 'read_sas', 'read_sql',
95+
'read_sql_query', 'read_sql_table', 'read_stata',
96+
'read_table']
97+
98+
# top-level to_* funcs
99+
funcs_to = ['to_datetime', 'to_msgpack',
100+
'to_numeric', 'to_pickle', 'to_timedelta']
101+
102+
# these should be deperecated in the future
103+
deprecated_funcs_in_future = ['pnow', 'groupby', 'info']
104+
105+
# these are already deprecated; awaiting removal
106+
deprecated_funcs = ['ewma', 'ewmcorr', 'ewmcov', 'ewmstd', 'ewmvar',
107+
'ewmvol', 'expanding_apply', 'expanding_corr',
108+
'expanding_count', 'expanding_cov', 'expanding_kurt',
109+
'expanding_max', 'expanding_mean', 'expanding_median',
110+
'expanding_min', 'expanding_quantile',
111+
'expanding_skew', 'expanding_std', 'expanding_sum',
112+
'expanding_var', 'fama_macbeth', 'rolling_apply',
113+
'rolling_corr', 'rolling_count', 'rolling_cov',
114+
'rolling_kurt', 'rolling_max', 'rolling_mean',
115+
'rolling_median', 'rolling_min', 'rolling_quantile',
116+
'rolling_skew', 'rolling_std', 'rolling_sum',
117+
'rolling_var', 'rolling_window', 'ordered_merge']
118+
119+
def test_api(self):
120+
121+
self.check(pd,
122+
self.lib + self.lib_to_rename + self.misc +
123+
self.modules + self.deprecated_modules +
124+
self.classes + self.deprecated_classes +
125+
self.deprecated_classes_in_future +
126+
self.remove_classes_from_top_level_namespace +
127+
self.funcs + self.funcs_option +
128+
self.funcs_read + self.funcs_to +
129+
self.deprecated_funcs +
130+
self.deprecated_funcs_in_future,
131+
self.ignored)
132+
133+
134+
class TestApi(Base, tm.TestCase):
135+
136+
allowed = ['tests', 'types']
137+
138+
def test_api(self):
139+
140+
self.check(api, self.allowed)
141+
142+
143+
class TestTypes(Base, tm.TestCase):
144+
145+
allowed = ['is_any_int_dtype', 'is_bool', 'is_bool_dtype',
146+
'is_categorical', 'is_categorical_dtype', 'is_complex',
147+
'is_complex_dtype', 'is_datetime64_any_dtype',
148+
'is_datetime64_dtype', 'is_datetime64_ns_dtype',
149+
'is_datetime64tz_dtype', 'is_datetimetz', 'is_dtype_equal',
150+
'is_extension_type', 'is_float', 'is_float_dtype',
151+
'is_floating_dtype', 'is_int64_dtype', 'is_integer',
152+
'is_integer_dtype', 'is_number', 'is_numeric_dtype',
153+
'is_object_dtype', 'is_scalar', 'is_sparse',
154+
'is_string_dtype', 'is_timedelta64_dtype',
155+
'is_timedelta64_ns_dtype',
156+
'is_re', 'is_re_compilable',
157+
'is_dict_like', 'is_iterator',
158+
'is_list_like', 'is_hashable',
159+
'is_named_tuple', 'is_sequence',
160+
'pandas_dtype']
161+
162+
def test_types(self):
163+
164+
self.check(types, self.allowed)
165+
166+
def check_deprecation(self, fold, fnew):
167+
with tm.assert_produces_warning(FutureWarning):
168+
try:
169+
result = fold('foo')
170+
expected = fnew('foo')
171+
self.assertEqual(result, expected)
172+
except TypeError:
173+
self.assertRaises(TypeError,
174+
lambda: fnew('foo'))
175+
except AttributeError:
176+
self.assertRaises(AttributeError,
177+
lambda: fnew('foo'))
178+
179+
def test_deprecation_core_common(self):
180+
181+
# test that we are in fact deprecating
182+
# the pandas.core.common introspectors
183+
for t in self.allowed:
184+
self.check_deprecation(getattr(com, t), getattr(types, t))
185+
186+
def test_deprecation_core_common_moved(self):
187+
188+
# these are in pandas.types.common
189+
l = ['is_datetime_arraylike',
190+
'is_datetime_or_timedelta_dtype',
191+
'is_datetimelike',
192+
'is_datetimelike_v_numeric',
193+
'is_datetimelike_v_object',
194+
'is_datetimetz',
195+
'is_int_or_datetime_dtype',
196+
'is_period_arraylike',
197+
'is_string_like',
198+
'is_string_like_dtype']
199+
200+
from pandas.types import common as c
201+
for t in l:
202+
self.check_deprecation(getattr(com, t), getattr(c, t))
203+
204+
def test_removed_from_core_common(self):
205+
206+
for t in ['is_null_datelike_scalar',
207+
'ensure_float']:
208+
self.assertRaises(AttributeError, lambda: getattr(com, t))
209+
210+
if __name__ == '__main__':
211+
import nose
212+
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
213+
exit=False)

pandas/api/types/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
""" public toolkit API """
2+
3+
from pandas.types.api import * # noqa
4+
del np # noqa

pandas/compat/numpy/function.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
from numpy import ndarray
2222
from pandas.util.validators import (validate_args, validate_kwargs,
2323
validate_args_and_kwargs)
24-
from pandas.core.common import is_bool, is_integer, UnsupportedFunctionCall
24+
from pandas.core.common import UnsupportedFunctionCall
25+
from pandas.types.common import is_integer, is_bool
2526
from pandas.compat import OrderedDict
2627

2728

pandas/computation/ops.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
import numpy as np
99

10+
from pandas.types.common import is_list_like, is_scalar
1011
import pandas as pd
1112
from pandas.compat import PY3, string_types, text_type
1213
import pandas.core.common as com
1314
from pandas.formats.printing import pprint_thing, pprint_thing_encoded
14-
import pandas.lib as lib
1515
from pandas.core.base import StringMixin
1616
from pandas.computation.common import _ensure_decoded, _result_type_many
1717
from pandas.computation.scope import _DEFAULT_GLOBALS
@@ -100,7 +100,7 @@ def update(self, value):
100100

101101
@property
102102
def isscalar(self):
103-
return lib.isscalar(self._value)
103+
return is_scalar(self._value)
104104

105105
@property
106106
def type(self):
@@ -229,7 +229,7 @@ def _in(x, y):
229229
try:
230230
return x.isin(y)
231231
except AttributeError:
232-
if com.is_list_like(x):
232+
if is_list_like(x):
233233
try:
234234
return y.isin(x)
235235
except AttributeError:
@@ -244,7 +244,7 @@ def _not_in(x, y):
244244
try:
245245
return ~x.isin(y)
246246
except AttributeError:
247-
if com.is_list_like(x):
247+
if is_list_like(x):
248248
try:
249249
return ~y.isin(x)
250250
except AttributeError:

pandas/computation/pytables.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from datetime import datetime, timedelta
88
import numpy as np
99
import pandas as pd
10+
11+
from pandas.types.common import is_list_like
1012
import pandas.core.common as com
1113
from pandas.compat import u, string_types, DeepChainMap
1214
from pandas.core.base import StringMixin
@@ -127,7 +129,7 @@ def pr(left, right):
127129

128130
def conform(self, rhs):
129131
""" inplace conform rhs """
130-
if not com.is_list_like(rhs):
132+
if not is_list_like(rhs):
131133
rhs = [rhs]
132134
if isinstance(rhs, np.ndarray):
133135
rhs = rhs.ravel()

0 commit comments

Comments
 (0)