From 38fa22b7d4ebeaa4a8672f1da12d50344514b681 Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Fri, 5 May 2017 00:51:05 -0400 Subject: [PATCH 1/7] ENH: Provide dict object for to_dict() #16122 --- asv_bench/benchmarks/algorithms.py | 2 +- asv_bench/benchmarks/attrs_caching.py | 6 +- ci/requirements-3.6_WIN.run | 1 + doc/source/api.rst | 3 +- doc/source/contributing.rst | 12 +- doc/source/merging.rst | 2 +- doc/source/whatsnew/v0.20.0.txt | 101 +- doc/source/whatsnew/v0.20.1.txt | 1 + doc/source/whatsnew/v0.21.0.txt | 113 ++ doc/sphinxext/numpydoc/numpydoc.py | 4 +- pandas/__init__.py | 6 +- pandas/{util => _libs}/hashing.pyx | 0 pandas/{io => _libs}/parsers.pyx | 0 pandas/{core/sparse => _libs}/sparse.pyx | 0 .../sparse => _libs}/sparse_op_helper.pxi.in | 0 pandas/_libs/src/ujson/python/ujson.c | 6 +- pandas/{util => _libs}/testing.pyx | 0 pandas/{core => _libs}/window.pyx | 0 pandas/compat/numpy/function.py | 4 +- pandas/compat/pickle_compat.py | 2 +- pandas/conftest.py | 7 + pandas/core/api.py | 2 +- pandas/core/base.py | 6 +- pandas/core/categorical.py | 8 +- pandas/core/common.py | 39 + pandas/core/computation/eval.py | 2 +- pandas/core/dtypes/common.py | 1211 ++++++++++++++++- pandas/core/frame.py | 48 +- pandas/core/generic.py | 6 +- pandas/core/groupby.py | 6 +- pandas/core/indexes/base.py | 4 +- pandas/core/indexes/category.py | 5 +- pandas/core/indexes/datetimelike.py | 2 +- pandas/core/indexes/datetimes.py | 4 +- pandas/core/indexes/interval.py | 6 +- pandas/core/indexes/multi.py | 8 +- pandas/core/indexes/numeric.py | 2 +- pandas/core/indexes/period.py | 4 +- pandas/core/indexes/range.py | 2 +- pandas/core/indexes/timedeltas.py | 2 +- pandas/core/internals.py | 4 +- pandas/core/ops.py | 2 +- pandas/core/panel.py | 2 +- pandas/core/resample.py | 2 +- pandas/core/reshape/merge.py | 2 +- pandas/core/reshape/reshape.py | 4 +- pandas/core/series.py | 31 +- pandas/core/sparse/array.py | 6 +- pandas/core/sparse/frame.py | 4 +- pandas/core/sparse/list.py | 4 +- pandas/core/sparse/series.py | 6 +- pandas/core/strings.py | 2 +- .../importing.py => core/util/__init__.py} | 0 pandas/{ => core}/util/hashing.py | 18 +- pandas/core/window.py | 6 +- pandas/io/api.py | 2 +- pandas/{util => io}/clipboard/__init__.py | 0 pandas/io/{ => clipboard}/clipboard.py | 4 +- pandas/{util => io}/clipboard/clipboards.py | 0 pandas/{util => io}/clipboard/exceptions.py | 0 pandas/{util => io}/clipboard/windows.py | 0 pandas/io/excel.py | 8 +- pandas/io/formats/console.py | 2 +- pandas/io/formats/format.py | 2 +- pandas/io/formats/style.py | 2 +- pandas/{util => io/formats}/terminal.py | 0 pandas/io/json/json.py | 6 +- pandas/io/parsers.py | 8 +- pandas/io/sas/sas7bdat.py | 2 +- pandas/io/sas/sas_xport.py | 2 +- pandas/io/stata.py | 2 +- pandas/json.py | 2 +- pandas/parser.py | 2 +- pandas/plotting/_core.py | 4 +- pandas/plotting/_misc.py | 2 +- pandas/stats/moments.py | 2 +- pandas/tests/api/test_api.py | 18 +- pandas/tests/api/test_types.py | 2 +- pandas/tests/computation/test_eval.py | 65 +- pandas/tests/dtypes/test_cast.py | 8 +- pandas/tests/dtypes/test_common.py | 462 ++++++- pandas/tests/dtypes/test_concat.py | 3 +- pandas/tests/dtypes/test_generic.py | 3 +- pandas/tests/dtypes/test_inference.py | 8 +- pandas/tests/dtypes/test_io.py | 4 +- pandas/tests/dtypes/test_missing.py | 2 +- pandas/tests/frame/common.py | 2 +- pandas/tests/frame/test_alter_axes.py | 4 +- pandas/tests/frame/test_analytics.py | 2 +- pandas/tests/frame/test_api.py | 2 +- pandas/tests/frame/test_apply.py | 4 +- pandas/tests/frame/test_asof.py | 4 +- .../tests/frame/test_axis_select_reindex.py | 2 +- pandas/tests/frame/test_block_internals.py | 2 +- pandas/tests/frame/test_combine_concat.py | 4 +- pandas/tests/frame/test_constructors.py | 4 +- pandas/tests/frame/test_convert_to.py | 115 +- pandas/tests/frame/test_dtypes.py | 4 +- pandas/tests/frame/test_indexing.py | 10 +- pandas/tests/frame/test_missing.py | 4 +- pandas/tests/frame/test_mutate_columns.py | 2 +- pandas/tests/frame/test_nonunique_indexes.py | 2 +- pandas/tests/frame/test_operators.py | 2 +- pandas/tests/frame/test_period.py | 4 +- pandas/tests/frame/test_quantile.py | 2 +- pandas/tests/frame/test_query_eval.py | 156 +-- pandas/tests/frame/test_rank.py | 2 +- pandas/tests/frame/test_replace.py | 2 +- pandas/tests/frame/test_repr_info.py | 2 +- pandas/tests/frame/test_reshape.py | 2 +- pandas/tests/frame/test_sorting.py | 4 +- pandas/tests/frame/test_subclass.py | 2 +- pandas/tests/frame/test_timeseries.py | 2 +- pandas/tests/frame/test_to_csv.py | 2 +- pandas/tests/frame/test_validate.py | 3 +- pandas/tests/groupby/common.py | 2 +- pandas/tests/groupby/test_aggregate.py | 4 +- pandas/tests/groupby/test_bin_groupby.py | 8 +- pandas/tests/groupby/test_categorical.py | 2 +- pandas/tests/groupby/test_filters.py | 4 +- pandas/tests/groupby/test_groupby.py | 2 +- pandas/tests/groupby/test_nth.py | 3 +- pandas/tests/groupby/test_timegrouper.py | 2 +- pandas/tests/groupby/test_transform.py | 2 +- pandas/tests/indexes/datetimes/test_astype.py | 6 +- .../indexes/datetimes/test_construction.py | 4 +- .../indexes/datetimes/test_date_range.py | 12 +- .../tests/indexes/datetimes/test_datetime.py | 2 +- .../indexes/datetimes/test_datetimelike.py | 4 +- .../tests/indexes/datetimes/test_indexing.py | 2 +- pandas/tests/indexes/datetimes/test_misc.py | 6 +- .../tests/indexes/datetimes/test_missing.py | 2 +- pandas/tests/indexes/datetimes/test_ops.py | 14 +- .../indexes/datetimes/test_partial_slicing.py | 2 +- pandas/tests/indexes/datetimes/test_setops.py | 10 +- pandas/tests/indexes/datetimes/test_tools.py | 18 +- pandas/tests/indexes/period/test_asfreq.py | 4 +- .../tests/indexes/period/test_construction.py | 8 +- pandas/tests/indexes/period/test_indexing.py | 6 +- pandas/tests/indexes/period/test_ops.py | 14 +- .../indexes/period/test_partial_slicing.py | 4 +- pandas/tests/indexes/period/test_period.py | 4 +- pandas/tests/indexes/period/test_setops.py | 4 +- pandas/tests/indexes/period/test_tools.py | 8 +- pandas/tests/indexes/test_base.py | 8 +- pandas/tests/indexes/test_category.py | 4 +- pandas/tests/indexes/test_frozen.py | 8 +- pandas/tests/indexes/test_interval.py | 10 +- pandas/tests/indexes/test_multi.py | 6 +- pandas/tests/indexes/test_numeric.py | 12 +- pandas/tests/indexes/test_range.py | 4 +- .../tests/indexes/timedeltas/test_astype.py | 4 +- .../indexes/timedeltas/test_construction.py | 2 +- .../tests/indexes/timedeltas/test_indexing.py | 2 +- pandas/tests/indexes/timedeltas/test_ops.py | 8 +- .../timedeltas/test_partial_slicing.py | 2 +- .../tests/indexes/timedeltas/test_setops.py | 2 +- .../indexes/timedeltas/test_timedelta.py | 8 +- .../timedeltas/test_timedelta_range.py | 2 +- pandas/tests/indexes/timedeltas/test_tools.py | 2 +- pandas/tests/indexing/common.py | 2 +- pandas/tests/indexing/test_callable.py | 2 +- pandas/tests/indexing/test_categorical.py | 4 +- .../indexing/test_chaining_and_caching.py | 4 +- pandas/tests/indexing/test_coercion.py | 12 +- pandas/tests/indexing/test_datetime.py | 2 +- pandas/tests/indexing/test_floats.py | 2 +- pandas/tests/indexing/test_iloc.py | 2 +- pandas/tests/indexing/test_indexing.py | 8 +- pandas/tests/indexing/test_indexing_slow.py | 2 +- pandas/tests/indexing/test_interval.py | 4 +- pandas/tests/indexing/test_ix.py | 2 +- pandas/tests/indexing/test_loc.py | 2 +- pandas/tests/indexing/test_multiindex.py | 6 +- pandas/tests/indexing/test_panel.py | 2 +- pandas/tests/indexing/test_partial.py | 2 +- pandas/tests/indexing/test_scalar.py | 2 +- pandas/tests/indexing/test_timedelta.py | 2 +- .../tests/io/formats/test_eng_formatting.py | 2 +- pandas/tests/io/formats/test_format.py | 28 +- pandas/tests/io/formats/test_printing.py | 7 +- pandas/tests/io/formats/test_style.py | 9 +- pandas/tests/io/formats/test_to_csv.py | 2 +- pandas/tests/io/formats/test_to_html.py | 2 +- .../tests/io/json/test_json_table_schema.py | 11 +- pandas/tests/io/json/test_normalize.py | 2 +- pandas/tests/io/json/test_pandas.py | 6 +- pandas/tests/io/json/test_ujson.py | 10 +- pandas/tests/io/msgpack/test_limits.py | 4 +- pandas/tests/io/msgpack/test_unpack.py | 3 +- pandas/tests/io/parser/test_network.py | 4 +- pandas/tests/io/parser/test_parsers.py | 8 +- pandas/tests/io/parser/test_read_fwf.py | 2 +- pandas/tests/io/parser/test_textreader.py | 8 +- pandas/tests/io/parser/test_unsupported.py | 4 +- pandas/tests/io/sas/test_sas.py | 3 +- pandas/tests/io/sas/test_sas7bdat.py | 4 +- pandas/tests/io/sas/test_xport.py | 4 +- pandas/tests/io/test_clipboard.py | 14 +- pandas/tests/io/test_common.py | 6 +- pandas/tests/io/test_excel.py | 48 +- pandas/tests/io/test_gbq.py | 7 +- pandas/tests/io/test_html.py | 21 +- pandas/tests/io/test_packers.py | 30 +- pandas/tests/io/test_pytables.py | 16 +- pandas/tests/io/test_s3.py | 4 +- pandas/tests/io/test_sql.py | 63 +- pandas/tests/io/test_stata.py | 4 +- pandas/tests/plotting/common.py | 12 +- pandas/tests/plotting/test_boxplot_method.py | 4 +- pandas/tests/plotting/test_converter.py | 8 +- pandas/tests/plotting/test_datetimelike.py | 9 +- pandas/tests/plotting/test_deprecated.py | 3 +- pandas/tests/plotting/test_frame.py | 7 +- pandas/tests/plotting/test_groupby.py | 3 +- pandas/tests/plotting/test_hist_method.py | 10 +- pandas/tests/plotting/test_misc.py | 8 +- pandas/tests/plotting/test_series.py | 7 +- pandas/tests/reshape/test_concat.py | 6 +- pandas/tests/reshape/test_join.py | 4 +- pandas/tests/reshape/test_merge.py | 8 +- pandas/tests/reshape/test_merge_asof.py | 4 +- pandas/tests/reshape/test_merge_ordered.py | 4 +- pandas/tests/reshape/test_pivot.py | 10 +- pandas/tests/reshape/test_reshape.py | 14 +- pandas/tests/reshape/test_tile.py | 2 +- .../tests/reshape/test_union_categoricals.py | 2 +- pandas/tests/reshape/test_util.py | 2 +- pandas/tests/scalar/test_interval.py | 4 +- pandas/tests/scalar/test_period.py | 10 +- pandas/tests/scalar/test_period_asfreq.py | 2 +- pandas/tests/scalar/test_timedelta.py | 4 +- pandas/tests/scalar/test_timestamp.py | 14 +- pandas/tests/series/common.py | 2 +- pandas/tests/series/test_alter_axes.py | 2 +- pandas/tests/series/test_analytics.py | 41 +- pandas/tests/series/test_api.py | 2 +- pandas/tests/series/test_apply.py | 6 +- pandas/tests/series/test_asof.py | 2 +- pandas/tests/series/test_combine_concat.py | 4 +- pandas/tests/series/test_constructors.py | 2 +- pandas/tests/series/test_datetime_values.py | 2 +- pandas/tests/series/test_indexing.py | 14 +- pandas/tests/series/test_internals.py | 2 +- pandas/tests/series/test_io.py | 26 +- pandas/tests/series/test_missing.py | 4 +- pandas/tests/series/test_operators.py | 2 +- pandas/tests/series/test_period.py | 4 +- pandas/tests/series/test_quantile.py | 2 +- pandas/tests/series/test_rank.py | 2 +- pandas/tests/series/test_replace.py | 2 +- pandas/tests/series/test_repr.py | 2 +- pandas/tests/series/test_sorting.py | 2 +- pandas/tests/series/test_subclass.py | 4 +- pandas/tests/series/test_timeseries.py | 2 +- pandas/tests/sparse/test_arithmetics.py | 2 +- pandas/tests/sparse/test_array.py | 8 +- pandas/tests/sparse/test_combine_concat.py | 6 +- pandas/tests/sparse/test_format.py | 4 +- pandas/tests/sparse/test_frame.py | 12 +- pandas/tests/sparse/test_groupby.py | 4 +- pandas/tests/sparse/test_indexing.py | 12 +- pandas/tests/sparse/test_libsparse.py | 14 +- pandas/tests/sparse/test_list.py | 5 +- pandas/tests/sparse/test_pivot.py | 4 +- pandas/tests/sparse/test_series.py | 18 +- pandas/tests/test_algos.py | 28 +- pandas/tests/test_base.py | 14 +- pandas/tests/test_categorical.py | 10 +- pandas/tests/test_common.py | 27 + pandas/tests/test_compat.py | 3 +- pandas/tests/test_config.py | 32 +- pandas/tests/test_expressions.py | 6 +- pandas/tests/test_internals.py | 8 +- pandas/tests/test_join.py | 2 +- pandas/tests/test_lib.py | 6 +- pandas/tests/test_multilevel.py | 6 +- pandas/tests/test_nanops.py | 20 +- pandas/tests/test_panel.py | 8 +- pandas/tests/test_panel4d.py | 8 +- pandas/tests/test_panelnd.py | 4 +- pandas/tests/test_resample.py | 20 +- pandas/tests/test_sorting.py | 4 +- pandas/tests/test_strings.py | 2 +- pandas/tests/test_take.py | 2 +- pandas/tests/test_window.py | 32 +- pandas/tests/tools/test_numeric.py | 2 +- pandas/tests/tseries/test_frequencies.py | 6 +- pandas/tests/tseries/test_holiday.py | 16 +- pandas/tests/tseries/test_offsets.py | 34 +- pandas/tests/tseries/test_timezones.py | 14 +- pandas/tests/util/__init__.py | 0 .../tests/{reshape => util}/test_hashing.py | 22 +- pandas/tests/{ => util}/test_testing.py | 19 +- pandas/tests/{ => util}/test_util.py | 28 +- pandas/tools/hashing.py | 18 + pandas/tseries/frequencies.py | 2 +- pandas/util/__init__.py | 2 + pandas/util/{decorators.py => _decorators.py} | 0 .../util/{depr_module.py => _depr_module.py} | 0 pandas/util/{doctools.py => _doctools.py} | 0 .../{print_versions.py => _print_versions.py} | 0 pandas/util/{validators.py => _validators.py} | 0 pandas/util/testing.py | 73 +- setup.py | 47 +- 305 files changed, 2980 insertions(+), 1280 deletions(-) create mode 100644 doc/source/whatsnew/v0.21.0.txt rename pandas/{util => _libs}/hashing.pyx (100%) rename pandas/{io => _libs}/parsers.pyx (100%) rename pandas/{core/sparse => _libs}/sparse.pyx (100%) rename pandas/{core/sparse => _libs}/sparse_op_helper.pxi.in (100%) rename pandas/{util => _libs}/testing.pyx (100%) rename pandas/{core => _libs}/window.pyx (100%) rename pandas/{util/importing.py => core/util/__init__.py} (100%) rename pandas/{ => core}/util/hashing.py (94%) rename pandas/{util => io}/clipboard/__init__.py (100%) rename pandas/io/{ => clipboard}/clipboard.py (97%) rename pandas/{util => io}/clipboard/clipboards.py (100%) rename pandas/{util => io}/clipboard/exceptions.py (100%) rename pandas/{util => io}/clipboard/windows.py (100%) rename pandas/{util => io/formats}/terminal.py (100%) create mode 100644 pandas/tests/util/__init__.py rename pandas/tests/{reshape => util}/test_hashing.py (93%) rename pandas/tests/{ => util}/test_testing.py (98%) rename pandas/tests/{ => util}/test_util.py (96%) create mode 100644 pandas/tools/hashing.py rename pandas/util/{decorators.py => _decorators.py} (100%) rename pandas/util/{depr_module.py => _depr_module.py} (100%) rename pandas/util/{doctools.py => _doctools.py} (100%) rename pandas/util/{print_versions.py => _print_versions.py} (100%) rename pandas/util/{validators.py => _validators.py} (100%) diff --git a/asv_bench/benchmarks/algorithms.py b/asv_bench/benchmarks/algorithms.py index d79051ed2d66c..40cfec1bcd4c7 100644 --- a/asv_bench/benchmarks/algorithms.py +++ b/asv_bench/benchmarks/algorithms.py @@ -5,7 +5,7 @@ import pandas as pd from pandas.util import testing as tm -for imp in ['pandas.util.hashing', 'pandas.tools.hashing']: +for imp in ['pandas.util', 'pandas.tools.hashing']: try: hashing = import_module(imp) break diff --git a/asv_bench/benchmarks/attrs_caching.py b/asv_bench/benchmarks/attrs_caching.py index 9210f1f2878d4..b7610037bed4d 100644 --- a/asv_bench/benchmarks/attrs_caching.py +++ b/asv_bench/benchmarks/attrs_caching.py @@ -1,5 +1,9 @@ from .pandas_vb_common import * -from pandas.util.decorators import cache_readonly + +try: + from pandas.util import cache_readonly +except ImportError: + from pandas.util.decorators import cache_readonly class DataFrameAttributes(object): diff --git a/ci/requirements-3.6_WIN.run b/ci/requirements-3.6_WIN.run index 840d2867e9297..899bfbc6b6b23 100644 --- a/ci/requirements-3.6_WIN.run +++ b/ci/requirements-3.6_WIN.run @@ -1,6 +1,7 @@ python-dateutil pytz numpy=1.12* +bottleneck openpyxl xlsxwriter xlrd diff --git a/doc/source/api.rst b/doc/source/api.rst index 491bec3c83f61..c652573bc6677 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -618,7 +618,6 @@ strings and apply several methods to it. These can be accessed like Series.cat Series.dt Index.str - CategoricalIndex.str MultiIndex.str DatetimeIndex.str TimedeltaIndex.str @@ -1404,6 +1403,7 @@ CategoricalIndex .. autosummary:: :toctree: generated/ + :template: autosummary/class_without_autosummary.rst CategoricalIndex @@ -1432,6 +1432,7 @@ IntervalIndex .. autosummary:: :toctree: generated/ + :template: autosummary/class_without_autosummary.rst IntervalIndex diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst index 08e28582e7469..aacfe25b91564 100644 --- a/doc/source/contributing.rst +++ b/doc/source/contributing.rst @@ -617,11 +617,11 @@ the expected correct result:: Transitioning to ``pytest`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*pandas* existing test structure is *mostly* classed based, meaning that you will typically find tests wrapped in a class, inheriting from ``tm.TestCase``. +*pandas* existing test structure is *mostly* classed based, meaning that you will typically find tests wrapped in a class. .. code-block:: python - class TestReallyCoolFeature(tm.TestCase): + class TestReallyCoolFeature(object): .... Going forward, we are moving to a more *functional* style using the `pytest `__ framework, which offers a richer testing @@ -632,14 +632,6 @@ framework that will facilitate testing and developing. Thus, instead of writing def test_really_cool_feature(): .... -Sometimes, it does make sense to bundle test functions together into a single class, either because the test file is testing multiple functions from a single module, and -using test classes allows for better organization. However, instead of inheriting from ``tm.TestCase``, we should just inherit from ``object``: - -.. code-block:: python - - class TestReallyCoolFeature(object): - .... - Using ``pytest`` ~~~~~~~~~~~~~~~~ diff --git a/doc/source/merging.rst b/doc/source/merging.rst index fb020727d077e..170dde87c8363 100644 --- a/doc/source/merging.rst +++ b/doc/source/merging.rst @@ -13,7 +13,7 @@ import matplotlib.pyplot as plt plt.close('all') - import pandas.util.doctools as doctools + import pandas.util._doctools as doctools p = doctools.TablePlotter() diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 230c7c0b90ac0..b34eb0b757968 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -1,7 +1,7 @@ .. _whatsnew_0200: -v0.20.0 (May 12, 2017) ------------------------- +v0.20.0 (May 4, 2017) +--------------------- This is a major release from 0.19.2 and includes a number of API changes, deprecations, new features, enhancements, and performance improvements along with a large number of bug fixes. We recommend that all @@ -17,8 +17,8 @@ Highlights include: - Improved user API when accessing levels in ``.groupby()``, see :ref:`here ` - Improved support for ``UInt64`` dtypes, see :ref:`here ` - A new orient for JSON serialization, ``orient='table'``, that uses the :ref:`Table Schema spec ` -- Experimental support for exporting ``DataFrame.style`` formats to Excel , see :ref:`here ` -- Window Binary Corr/Cov operations now return a MultiIndexed ``DataFrame`` rather than a ``Panel``, as ``Panel`` is now deprecated, see :ref:`here ` +- Experimental support for exporting ``DataFrame.style`` formats to Excel, see :ref:`here ` +- Window binary corr/cov operations now return a MultiIndexed ``DataFrame`` rather than a ``Panel``, as ``Panel`` is now deprecated, see :ref:`here ` - Support for S3 handling now uses ``s3fs``, see :ref:`here ` - Google BigQuery support now uses the ``pandas-gbq`` library, see :ref:`here ` - Switched the test framework to use `pytest `__ (:issue:`13097`) @@ -44,10 +44,10 @@ New features ``agg`` API ^^^^^^^^^^^ -Series & DataFrame have been enhanced to support the aggregation API. This is an already familiar API that -is supported for groupby, window operations, and resampling. This allows one to express aggregation operations -in a single concise way by using :meth:`~DataFrame.agg`, -and :meth:`~DataFrame.transform`. The full documentation is :ref:`here ` (:issue:`1623`). +Series & DataFrame have been enhanced to support the aggregation API. This is a familiar API +from groupby, window operations, and resampling. This allows aggregation operations in a concise +by using :meth:`~DataFrame.agg`, and :meth:`~DataFrame.transform`. The full documentation +is :ref:`here ` (:issue:`1623`). Here is a sample @@ -66,28 +66,28 @@ Using a single function is equivalent to ``.apply``. df.agg('sum') -Multiple functions in lists. +Multiple aggregations with a list of functions. .. ipython:: python df.agg(['sum', 'min']) -Using a dict provides the ability to have selective aggregation per column. -You will get a matrix-like output of all of the aggregators. The output will consist -of all unique functions. Those that are not noted for a particular column will be ``NaN``: +Using a dict provides the ability to apply specific aggregations per column. +You will get a matrix-like output of all of the aggregators. The output has one column +per unique function. Those functions applied to a particular column will be ``NaN``: .. ipython:: python df.agg({'A' : ['sum', 'min'], 'B' : ['min', 'max']}) -The API also supports a ``.transform()`` function to provide for broadcasting results. +The API also supports a ``.transform()`` function for broadcasting results. .. ipython:: python :okwarning: df.transform(['abs', lambda x: x - x.min()]) -When presented with mixed dtypes that cannot aggregate, ``.agg()`` will only take the valid +When presented with mixed dtypes that cannot be aggregated, ``.agg()`` will only take the valid aggregations. This is similiar to how groupby ``.agg()`` works. (:issue:`15015`) .. ipython:: python @@ -107,7 +107,7 @@ aggregations. This is similiar to how groupby ``.agg()`` works. (:issue:`15015`) ``dtype`` keyword for data IO ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The ``dtype`` keyword argument in the :func:`read_csv` function for specifying the types of parsed columns is now supported with the ``'python'`` engine (:issue:`14295`). See the :ref:`io docs ` for more information. +The ``'python'`` engine for :func:`read_csv` now accepts the ``dtype`` keyword argument for specifying the types of specific columns (:issue:`14295`). See the :ref:`io docs ` for more information. .. ipython:: python :suppress: @@ -156,7 +156,7 @@ Commonly called 'unix epoch' or POSIX time. This was the previous default, so th Groupby Enhancements ^^^^^^^^^^^^^^^^^^^^ -Strings passed to ``DataFrame.groupby()`` as the ``by`` parameter may now reference either column names or index level names (:issue:`5677`) +Strings passed to ``DataFrame.groupby()`` as the ``by`` parameter may now reference either column names or index level names. .. ipython:: python @@ -172,6 +172,9 @@ Strings passed to ``DataFrame.groupby()`` as the ``by`` parameter may now refere df.groupby(['second', 'A']).sum() +Previously, only column names could be referenced. (:issue:`5677`) + + .. _whatsnew_0200.enhancements.compressed_urls: Better support for compressed URLs in ``read_csv`` @@ -181,8 +184,8 @@ The compression code was refactored (:issue:`12688`). As a result, reading dataframes from URLs in :func:`read_csv` or :func:`read_table` now supports additional compression methods: ``xz``, ``bz2``, and ``zip`` (:issue:`14570`). Previously, only ``gzip`` compression was supported. By default, compression of -URLs and paths are now both inferred using their file extensions. Additionally, -support for bz2 compression in the python 2 c-engine improved (:issue:`14874`). +URLs and paths are now inferred using their file extensions. Additionally, +support for bz2 compression in the python 2 C-engine improved (:issue:`14874`). .. ipython:: python @@ -203,7 +206,7 @@ Pickle file I/O now supports compression :func:`read_pickle`, :meth:`DataFame.to_pickle` and :meth:`Series.to_pickle` can now read from and write to compressed pickle files. Compression methods can be an explicit parameter or be inferred from the file extension. -See :ref:`the docs here ` +See :ref:`the docs here. ` .. ipython:: python @@ -432,7 +435,7 @@ New behavior: c c.categories -Furthermore, this allows one to bin *other* data with these same bins, with ``NaN`` represents a missing +Furthermore, this allows one to bin *other* data with these same bins, with ``NaN`` representing a missing value similar to other dtypes. .. ipython:: python @@ -465,7 +468,7 @@ Selecting via a scalar value that is contained *in* the intervals. Other Enhancements ^^^^^^^^^^^^^^^^^^ -- ``DataFrame.rolling()`` now accepts the parameter ``closed='right'|'left'|'both'|'neither'`` to choose the rolling window endpoint closedness. See the :ref:`documentation ` (:issue:`13965`) +- ``DataFrame.rolling()`` now accepts the parameter ``closed='right'|'left'|'both'|'neither'`` to choose the rolling window-endpoint closedness. See the :ref:`documentation ` (:issue:`13965`) - Integration with the ``feather-format``, including a new top-level ``pd.read_feather()`` and ``DataFrame.to_feather()`` method, see :ref:`here `. - ``Series.str.replace()`` now accepts a callable, as replacement, which is passed to ``re.sub`` (:issue:`15055`) - ``Series.str.replace()`` now accepts a compiled regular expression as a pattern (:issue:`15446`) @@ -473,11 +476,9 @@ Other Enhancements - ``DataFrame`` has gained a ``nunique()`` method to count the distinct values over an axis (:issue:`14336`). - ``DataFrame`` has gained a ``melt()`` method, equivalent to ``pd.melt()``, for unpivoting from a wide to long format (:issue:`12640`). - ``DataFrame.groupby()`` has gained a ``.nunique()`` method to count the distinct values for all columns within each group (:issue:`14336`, :issue:`15197`). - - ``pd.read_excel()`` now preserves sheet order when using ``sheetname=None`` (:issue:`9930`) - Multiple offset aliases with decimal points are now supported (e.g. ``0.5min`` is parsed as ``30s``) (:issue:`8419`) - ``.isnull()`` and ``.notnull()`` have been added to ``Index`` object to make them more consistent with the ``Series`` API (:issue:`15300`) - - New ``UnsortedIndexError`` (subclass of ``KeyError``) raised when indexing/slicing into an unsorted MultiIndex (:issue:`11897`). This allows differentiation between errors due to lack of sorting or an incorrect key. See :ref:`here ` @@ -497,20 +498,19 @@ Other Enhancements - ``Timedelta.isoformat`` method added for formatting Timedeltas as an `ISO 8601 duration`_. See the :ref:`Timedelta docs ` (:issue:`15136`) - ``.select_dtypes()`` now allows the string ``datetimetz`` to generically select datetimes with tz (:issue:`14910`) - The ``.to_latex()`` method will now accept ``multicolumn`` and ``multirow`` arguments to use the accompanying LaTeX enhancements - - ``pd.merge_asof()`` gained the option ``direction='backward'|'forward'|'nearest'`` (:issue:`14887`) - ``Series/DataFrame.asfreq()`` have gained a ``fill_value`` parameter, to fill missing values (:issue:`3715`). - ``Series/DataFrame.resample.asfreq`` have gained a ``fill_value`` parameter, to fill missing values during resampling (:issue:`3715`). -- ``pandas.util.hashing`` has gained a ``hash_tuples`` routine, and ``hash_pandas_object`` has gained the ability to hash a ``MultiIndex`` (:issue:`15224`) +- :func:`pandas.util.hash_pandas_object` has gained the ability to hash a ``MultiIndex`` (:issue:`15224`) - ``Series/DataFrame.squeeze()`` have gained the ``axis`` parameter. (:issue:`15339`) - ``DataFrame.to_excel()`` has a new ``freeze_panes`` parameter to turn on Freeze Panes when exporting to Excel (:issue:`15160`) -- ``pd.read_html()`` will parse multiple header rows, creating a multiindex header. (:issue:`13434`). +- ``pd.read_html()`` will parse multiple header rows, creating a MutliIndex header. (:issue:`13434`). - HTML table output skips ``colspan`` or ``rowspan`` attribute if equal to 1. (:issue:`15403`) -- ``pd.io.api.Styler`` template now has blocks for easier extension, :ref:`see the example notebook ` (:issue:`15649`) +- :class:`pandas.io.formats.style.Styler`` template now has blocks for easier extension, :ref:`see the example notebook ` (:issue:`15649`) +- :meth:`pandas.io.formats.style.Styler.render` now accepts ``**kwargs`` to allow user-defined variables in the template (:issue:`15649`) - ``pd.io.api.Styler.render`` now accepts ``**kwargs`` to allow user-defined variables in the template (:issue:`15649`) -- Compatability with Jupyter notebook 5.0; MultiIndex column labels are left-aligned and MultiIndex row-labels are top-aligned (:issue:`15379`) - -- ``TimedeltaIndex`` now has a custom datetick formatter specifically designed for nanosecond level precision (:issue:`8711`) +- Compatibility with Jupyter notebook 5.0; MultiIndex column labels are left-aligned and MultiIndex row-labels are top-aligned (:issue:`15379`) +- ``TimedeltaIndex`` now has a custom date-tick formatter specifically designed for nanosecond level precision (:issue:`8711`) - ``pd.api.types.union_categoricals`` gained the ``ignore_ordered`` argument to allow ignoring the ordered attribute of unioned categoricals (:issue:`13410`). See the :ref:`categorical union docs ` for more information. - ``DataFrame.to_latex()`` and ``DataFrame.to_string()`` now allow optional header aliases. (:issue:`15536`) - Re-enable the ``parse_dates`` keyword of ``pd.read_excel()`` to parse string columns as dates (:issue:`14326`) @@ -524,12 +524,10 @@ Other Enhancements - ``pd.read_csv()`` now supports the ``error_bad_lines`` and ``warn_bad_lines`` arguments for the Python parser (:issue:`15925`) - The ``display.show_dimensions`` option can now also be used to specify whether the length of a ``Series`` should be shown in its repr (:issue:`7117`). -- ``parallel_coordinates()`` has gained a ``sort_labels`` keyword arg that sorts class labels and the colours assigned to them (:issue:`15908`) +- ``parallel_coordinates()`` has gained a ``sort_labels`` keyword argument that sorts class labels and the colors assigned to them (:issue:`15908`) - Options added to allow one to turn on/off using ``bottleneck`` and ``numexpr``, see :ref:`here ` (:issue:`16157`) - - ``DataFrame.style.bar()`` now accepts two more options to further customize the bar chart. Bar alignment is set with ``align='left'|'mid'|'zero'``, the default is "left", which is backward compatible; You can now pass a list of ``color=[color_negative, color_positive]``. (:issue:`14757`) - .. _ISO 8601 duration: https://en.wikipedia.org/wiki/ISO_8601#Durations @@ -653,7 +651,7 @@ Accessing datetime fields of Index now return Index The datetime-related attributes (see :ref:`here ` for an overview) of ``DatetimeIndex``, ``PeriodIndex`` and ``TimedeltaIndex`` previously returned numpy arrays. They will now return a new ``Index`` object, except -in the case of a boolean field, where the result will stil be a boolean ndarray. (:issue:`15022`) +in the case of a boolean field, where the result will still be a boolean ndarray. (:issue:`15022`) Previous behaviour: @@ -682,7 +680,7 @@ pd.unique will now be consistent with extension types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In prior versions, using ``Series.unique()`` and :func:`unique` on ``Categorical`` and tz-aware -datatypes would yield different return types. These are now made consistent. (:issue:`15903`) +data-types would yield different return types. These are now made consistent. (:issue:`15903`) - Datetime tz-aware @@ -1044,7 +1042,7 @@ HDFStore where string comparison ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In previous versions most types could be compared to string column in a ``HDFStore`` -usually resulting in an invalid comparsion, returning an empty result frame. These comparisions will now raise a +usually resulting in an invalid comparison, returning an empty result frame. These comparisons will now raise a ``TypeError`` (:issue:`15492`) .. ipython:: python @@ -1085,8 +1083,8 @@ Index.intersection and inner join now preserve the order of the left Index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :meth:`Index.intersection` now preserves the order of the calling ``Index`` (left) -instead of the other ``Index`` (right) (:issue:`15582`). This affects the inner -joins, :meth:`DataFrame.join` and :func:`merge`, and the ``.align`` methods. +instead of the other ``Index`` (right) (:issue:`15582`). This affects inner +joins, :meth:`DataFrame.join` and :func:`merge`, and the ``.align`` method. - ``Index.intersection`` @@ -1141,7 +1139,7 @@ Pivot Table always returns a DataFrame ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The documentation for :meth:`pivot_table` states that a ``DataFrame`` is *always* returned. Here a bug -is fixed that allowed this to return a ``Series`` under a narrow circumstance. (:issue:`4386`) +is fixed that allowed this to return a ``Series`` under certain circumstance. (:issue:`4386`) .. ipython:: python @@ -1199,7 +1197,6 @@ Other API Changes - ``NaT`` will now returns ``NaT`` for ``tz_localize`` and ``tz_convert`` methods (:issue:`15830`) - ``DataFrame`` and ``Panel`` constructors with invalid input will now raise ``ValueError`` rather than ``PandasError``, if called with scalar inputs and not axes (:issue:`15541`) - - ``DataFrame`` and ``Panel`` constructors with invalid input will now raise ``ValueError`` rather than ``pandas.core.common.PandasError``, if called with scalar inputs and not axes; The exception ``PandasError`` is removed as well. (:issue:`15541`) - The exception ``pandas.core.common.AmbiguousIndexError`` is removed as it is not referenced (:issue:`15541`) @@ -1230,19 +1227,19 @@ If indicated, a deprecation warning will be issued if you reference theses modul "pandas.algos", "pandas._libs.algos", "" "pandas.hashtable", "pandas._libs.hashtable", "" "pandas.indexes", "pandas.core.indexes", "" - "pandas.json", "pandas.io.json.libjson", "X" - "pandas.parser", "pandas.io.libparsers", "X" + "pandas.json", "pandas._libs.json", "X" + "pandas.parser", "pandas._libs.parsers", "X" "pandas.formats", "pandas.io.formats", "" "pandas.sparse", "pandas.core.sparse", "" "pandas.tools", "pandas.core.reshape", "" "pandas.types", "pandas.core.dtypes", "" - "pandas.io.sas.saslib", "pandas.io.sas.libsas", "" + "pandas.io.sas.saslib", "pandas.io.sas._sas", "" "pandas._join", "pandas._libs.join", "" - "pandas._hash", "pandas.util.libhashing", "" + "pandas._hash", "pandas._libs.hashing", "" "pandas._period", "pandas._libs.period", "" - "pandas._sparse", "pandas.core.sparse.libsparse", "" - "pandas._testing", "pandas.util.libtesting", "" - "pandas._window", "pandas.core.libwindow", "" + "pandas._sparse", "pandas._libs.sparse", "" + "pandas._testing", "pandas._libs.testing", "" + "pandas._window", "pandas._libs.window", "" Some new subpackages are created with public functionality that is not directly @@ -1254,6 +1251,8 @@ these are now the public subpackages. - The function :func:`~pandas.api.types.union_categoricals` is now importable from ``pandas.api.types``, formerly from ``pandas.types.concat`` (:issue:`15998`) - The type import ``pandas.tslib.NaTType`` is deprecated and can be replaced by using ``type(pandas.NaT)`` (:issue:`16146`) +- The public functions in ``pandas.tools.hashing`` deprecated from that locations, but are now importable from ``pandas.util`` (:issue:`16223`) +- The modules in ``pandas.util``: ``decorators``, ``print_versions``, ``doctools``, `validators``, ``depr_module`` are now private (:issue:`16223`) .. _whatsnew_0200.privacy.errors: @@ -1278,7 +1277,7 @@ The following are now part of this API: 'UnsupportedFunctionCall'] -.. _whatsnew_0200.privay.testing: +.. _whatsnew_0200.privacy.testing: ``pandas.testing`` ^^^^^^^^^^^^^^^^^^ @@ -1292,14 +1291,13 @@ The following testing functions are now part of this API: - :func:`testing.assert_index_equal` -.. _whatsnew_0200.privay.plotting: +.. _whatsnew_0200.privacy.plotting: ``pandas.plotting`` ^^^^^^^^^^^^^^^^^^^ A new public ``pandas.plotting`` module has been added that holds plotting functionality that was previously in either ``pandas.tools.plotting`` or in the top-level namespace. See the :ref:`deprecations sections ` for more details. - .. _whatsnew_0200.privacy.development: Other Development Changes @@ -1323,7 +1321,6 @@ Deprecate ``.ix`` The ``.ix`` indexer is deprecated, in favor of the more strict ``.iloc`` and ``.loc`` indexers. ``.ix`` offers a lot of magic on the inference of what the user wants to do. To wit, ``.ix`` can decide to index *positionally* OR via *labels*, depending on the data type of the index. This has caused quite a bit of user confusion over the years. The full indexing documentation are :ref:`here `. (:issue:`14218`) - The recommended methods of indexing are: - ``.loc`` if you want to *label* index @@ -1719,7 +1716,7 @@ Reshaping - Bug in ``DataFrame.pivot_table()`` where ``dropna=True`` would not drop all-NaN columns when the columns was a ``category`` dtype (:issue:`15193`) - Bug in ``pd.melt()`` where passing a tuple value for ``value_vars`` caused a ``TypeError`` (:issue:`15348`) - Bug in ``pd.pivot_table()`` where no error was raised when values argument was not in the columns (:issue:`14938`) -- Bug in ``pd.concat()`` in which concatting with an empty dataframe with ``join='inner'`` was being improperly handled (:issue:`15328`) +- Bug in ``pd.concat()`` in which concatenating with an empty dataframe with ``join='inner'`` was being improperly handled (:issue:`15328`) - Bug with ``sort=True`` in ``DataFrame.join`` and ``pd.merge`` when joining on indexes (:issue:`15582`) - Bug in ``DataFrame.nsmallest`` and ``DataFrame.nlargest`` where identical values resulted in duplicated rows (:issue:`15297`) diff --git a/doc/source/whatsnew/v0.20.1.txt b/doc/source/whatsnew/v0.20.1.txt index 504f8004bc8a6..b6a41dbb4412f 100644 --- a/doc/source/whatsnew/v0.20.1.txt +++ b/doc/source/whatsnew/v0.20.1.txt @@ -18,6 +18,7 @@ Highlights include: Enhancements ~~~~~~~~~~~~ +- ``Series.to_dict()`` and ``DataFrame.to_dict()`` now support an ``into`` keyword which allows you to specify the ``collections.Mapping`` subclass that you would like returned. The default is ``dict``, which is backwards compatible. (:issue:`16122`) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt new file mode 100644 index 0000000000000..36dffc3d3378b --- /dev/null +++ b/doc/source/whatsnew/v0.21.0.txt @@ -0,0 +1,113 @@ +.. _whatsnew_0210: + +v0.21.0 (???) +------------- + +This is a major release from 0.20.x and includes a number of API changes, deprecations, new features, +enhancements, and performance improvements along with a large number of bug fixes. We recommend that all +users upgrade to this version. + +Highlights include: + +Check the :ref:`API Changes ` and :ref:`deprecations ` before updating. + +.. contents:: What's new in v0.21.0 + :local: + :backlinks: none + +.. _whatsnew_0210.enhancements: + +New features +~~~~~~~~~~~~ + + + +.. _whatsnew_0210.enhancements.other: + +Other Enhancements +^^^^^^^^^^^^^^^^^^ + + + +.. _whatsnew_0210.api_breaking: + +Backwards incompatible API changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +.. _whatsnew_0210.api: + +Other API Changes +^^^^^^^^^^^^^^^^^ + + + +.. _whatsnew_0210.deprecations: + +Deprecations +~~~~~~~~~~~~ + + + +.. _whatsnew_0210.prior_deprecations: + +Removal of prior version deprecations/changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +.. _whatsnew_0210.performance: + +Performance Improvements +~~~~~~~~~~~~~~~~~~~~~~~~ + + + +.. _whatsnew_0210.bug_fixes: + +Bug Fixes +~~~~~~~~~ + +Conversion +^^^^^^^^^^ + + + +Indexing +^^^^^^^^ + + + +I/O +^^^ + + + +Plotting +^^^^^^^^ + + + +Groupby/Resample/Rolling +^^^^^^^^^^^^^^^^^^^^^^^^ + + + +Sparse +^^^^^^ + + + +Reshaping +^^^^^^^^^ + + + +Numeric +^^^^^^^ + + + +Other +^^^^^ diff --git a/doc/sphinxext/numpydoc/numpydoc.py b/doc/sphinxext/numpydoc/numpydoc.py index 0cccf72de3745..710c3cc9842c4 100755 --- a/doc/sphinxext/numpydoc/numpydoc.py +++ b/doc/sphinxext/numpydoc/numpydoc.py @@ -43,7 +43,9 @@ def mangle_docstrings(app, what, name, obj, options, lines, ) # PANDAS HACK (to remove the list of methods/attributes for Categorical) - if what == "class" and name.endswith(".Categorical"): + if what == "class" and (name.endswith(".Categorical") or + name.endswith("CategoricalIndex") or + name.endswith("IntervalIndex")): cfg['class_members_list'] = False if what == 'module': diff --git a/pandas/__init__.py b/pandas/__init__.py index 20c7e0d9d5993..48ac9d173559d 100644 --- a/pandas/__init__.py +++ b/pandas/__init__.py @@ -50,17 +50,17 @@ import pandas.tools.plotting plot_params = pandas.plotting._style._Options(deprecated=True) # do not import deprecate to top namespace -scatter_matrix = pandas.util.decorators.deprecate( +scatter_matrix = pandas.util._decorators.deprecate( 'pandas.scatter_matrix', pandas.plotting.scatter_matrix, 'pandas.plotting.scatter_matrix') -from pandas.util.print_versions import show_versions +from pandas.util._print_versions import show_versions from pandas.io.api import * from pandas.util._tester import test import pandas.testing # extension module deprecations -from pandas.util.depr_module import _DeprecatedModule +from pandas.util._depr_module import _DeprecatedModule json = _DeprecatedModule(deprmod='pandas.json', moved={'dumps': 'pandas.io.json.dumps', diff --git a/pandas/util/hashing.pyx b/pandas/_libs/hashing.pyx similarity index 100% rename from pandas/util/hashing.pyx rename to pandas/_libs/hashing.pyx diff --git a/pandas/io/parsers.pyx b/pandas/_libs/parsers.pyx similarity index 100% rename from pandas/io/parsers.pyx rename to pandas/_libs/parsers.pyx diff --git a/pandas/core/sparse/sparse.pyx b/pandas/_libs/sparse.pyx similarity index 100% rename from pandas/core/sparse/sparse.pyx rename to pandas/_libs/sparse.pyx diff --git a/pandas/core/sparse/sparse_op_helper.pxi.in b/pandas/_libs/sparse_op_helper.pxi.in similarity index 100% rename from pandas/core/sparse/sparse_op_helper.pxi.in rename to pandas/_libs/sparse_op_helper.pxi.in diff --git a/pandas/_libs/src/ujson/python/ujson.c b/pandas/_libs/src/ujson/python/ujson.c index ec6720f16bc77..a0c2146c30eed 100644 --- a/pandas/_libs/src/ujson/python/ujson.c +++ b/pandas/_libs/src/ujson/python/ujson.c @@ -90,14 +90,14 @@ static struct PyModuleDef moduledef = { NULL /* m_free */ }; -#define PYMODINITFUNC PyMODINIT_FUNC PyInit_libjson(void) +#define PYMODINITFUNC PyMODINIT_FUNC PyInit_json(void) #define PYMODULE_CREATE() PyModule_Create(&moduledef) #define MODINITERROR return NULL #else -#define PYMODINITFUNC PyMODINIT_FUNC initlibjson(void) -#define PYMODULE_CREATE() Py_InitModule("libjson", ujsonMethods) +#define PYMODINITFUNC PyMODINIT_FUNC initjson(void) +#define PYMODULE_CREATE() Py_InitModule("json", ujsonMethods) #define MODINITERROR return #endif diff --git a/pandas/util/testing.pyx b/pandas/_libs/testing.pyx similarity index 100% rename from pandas/util/testing.pyx rename to pandas/_libs/testing.pyx diff --git a/pandas/core/window.pyx b/pandas/_libs/window.pyx similarity index 100% rename from pandas/core/window.pyx rename to pandas/_libs/window.pyx diff --git a/pandas/compat/numpy/function.py b/pandas/compat/numpy/function.py index d707ac66c4eab..a324bf94171ce 100644 --- a/pandas/compat/numpy/function.py +++ b/pandas/compat/numpy/function.py @@ -19,8 +19,8 @@ """ from numpy import ndarray -from pandas.util.validators import (validate_args, validate_kwargs, - validate_args_and_kwargs) +from pandas.util._validators import (validate_args, validate_kwargs, + validate_args_and_kwargs) from pandas.errors import UnsupportedFunctionCall from pandas.core.dtypes.common import is_integer, is_bool from pandas.compat import OrderedDict diff --git a/pandas/compat/pickle_compat.py b/pandas/compat/pickle_compat.py index 6df365a1cd898..b875bbb0d63c0 100644 --- a/pandas/compat/pickle_compat.py +++ b/pandas/compat/pickle_compat.py @@ -71,7 +71,7 @@ def load_reduce(self): # 12588, extensions moving ('pandas._sparse', 'BlockIndex'): - ('pandas.core.sparse.libsparse', 'BlockIndex'), + ('pandas._libs.sparse', 'BlockIndex'), ('pandas.tslib', 'Timestamp'): ('pandas._libs.tslib', 'Timestamp'), ('pandas.tslib', '__nat_unpickle'): diff --git a/pandas/conftest.py b/pandas/conftest.py index caced6a0c568e..1149fae3fc0b0 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -25,6 +25,13 @@ def pytest_runtest_setup(item): pytest.skip("skipping due to --skip-network") +# Configurations for all tests and all test modules + +@pytest.fixture(autouse=True) +def configure_tests(): + pandas.set_option('chained_assignment', 'raise') + + # For running doctests: make np and pd names available @pytest.fixture(autouse=True) diff --git a/pandas/core/api.py b/pandas/core/api.py index 3e84720c32a1c..265fb4004d997 100644 --- a/pandas/core/api.py +++ b/pandas/core/api.py @@ -35,7 +35,7 @@ from pandas.core.resample import TimeGrouper # see gh-14094. -from pandas.util.depr_module import _DeprecatedModule +from pandas.util._depr_module import _DeprecatedModule _removals = ['day', 'bday', 'businessDay', 'cday', 'customBusinessDay', 'customBusinessMonthEnd', 'customBusinessMonthBegin', diff --git a/pandas/core/base.py b/pandas/core/base.py index fd0846b0ad33c..a3ef24c80f883 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -9,14 +9,14 @@ from pandas.core.dtypes.missing import isnull from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries, ABCIndexClass from pandas.core.dtypes.common import is_object_dtype, is_list_like, is_scalar -from pandas.util.validators import validate_bool_kwarg +from pandas.util._validators import validate_bool_kwarg from pandas.core import common as com import pandas.core.nanops as nanops import pandas._libs.lib as lib from pandas.compat.numpy import function as nv -from pandas.util.decorators import (Appender, cache_readonly, - deprecate_kwarg, Substitution) +from pandas.util._decorators import (Appender, cache_readonly, + deprecate_kwarg, Substitution) from pandas.core.common import AbstractMethodError _shared_docs = dict() diff --git a/pandas/core/categorical.py b/pandas/core/categorical.py index a3667e9322959..7eb86232cbb07 100644 --- a/pandas/core/categorical.py +++ b/pandas/core/categorical.py @@ -34,11 +34,11 @@ import pandas.core.common as com from pandas.core.missing import interpolate_2d from pandas.compat.numpy import function as nv -from pandas.util.decorators import (Appender, cache_readonly, - deprecate_kwarg, Substitution) +from pandas.util._decorators import (Appender, cache_readonly, + deprecate_kwarg, Substitution) -from pandas.util.terminal import get_terminal_size -from pandas.util.validators import validate_bool_kwarg +from pandas.io.formats.terminal import get_terminal_size +from pandas.util._validators import validate_bool_kwarg from pandas.core.config import get_option diff --git a/pandas/core/common.py b/pandas/core/common.py index 39a5da0aa6912..08cff034782b0 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -6,6 +6,8 @@ import warnings from datetime import datetime, timedelta from functools import partial +import inspect +import collections import numpy as np from pandas._libs import lib, tslib @@ -479,6 +481,43 @@ def _dict_compat(d): for key, value in iteritems(d)) +def _standardize_mapping(into): + """ + Helper function to standardize the supplied mapping so it can + be passed to the ``Series.to_dict()`` and ``DataFrame.to_dict()`` + + Parameters + ---------- + into : instance or subclass of collections.Mapping + The argument supplied to ``to_dict``. Must be a class, an + initialized collections.defaultdict, or an empty instance + of a collections.Mapping subclass. + + Returns + ------- + mapping : a collections.Mapping subclass or other constructor + a callable object that can accept an iterator to create + the desired Mapping. + + """ + if not inspect.isclass(into): + if len(into) > 0: + raise ValueError( + "to_dict() only accepts empty mappings.") + elif type(into) == collections.defaultdict: + return partial( + collections.defaultdict, into.default_factory) + else: + return _standardize_mapping(type(into)) + elif not issubclass(into, collections.Mapping): + raise TypeError('unsupported type: {}'.format(into)) + elif into == collections.defaultdict: + raise TypeError( + 'to_dict() only accepts initialized defaultdicts') + else: + return into + + def sentinel_factory(): class Sentinel(object): pass diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index 15e13025a7c53..22e376306280a 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -11,7 +11,7 @@ from pandas.core.computation.scope import _ensure_scope from pandas.compat import string_types from pandas.core.computation.engines import _engines -from pandas.util.validators import validate_bool_kwarg +from pandas.util._validators import validate_bool_kwarg def _check_engine(engine): diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index ba822071a3b72..bfec1ec3ebe8c 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -37,7 +37,7 @@ def _ensure_float(arr): Parameters ---------- - arr : ndarray, Series + arr : array-like The array whose data type we want to enforce as float. Returns @@ -82,46 +82,245 @@ def _ensure_categorical(arr): def is_object_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the object dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is of the object dtype. + + Examples + -------- + >>> is_object_dtype(object) + True + >>> is_object_dtype(int) + False + >>> is_object_dtype(np.array([], dtype=object)) + True + >>> is_object_dtype(np.array([], dtype=int)) + False + >>> is_object_dtype([1, 2, 3]) + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) return issubclass(tipo, np.object_) -def is_sparse(array): - """ return if we are a sparse array """ - return isinstance(array, (ABCSparseArray, ABCSparseSeries)) +def is_sparse(arr): + """ + Check whether an array-like is a pandas sparse array. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a pandas sparse array. + + Examples + -------- + >>> is_sparse(np.array([1, 2, 3])) + False + >>> is_sparse(pd.SparseArray([1, 2, 3])) + True + >>> is_sparse(pd.SparseSeries([1, 2, 3])) + True + + This function checks only for pandas sparse array instances, so + sparse arrays from other libraries will return False. + + >>> from scipy.sparse import bsr_matrix + >>> is_sparse(bsr_matrix([1, 2, 3])) + False + """ + + return isinstance(arr, (ABCSparseArray, ABCSparseSeries)) + + +def is_scipy_sparse(arr): + """ + Check whether an array-like is a scipy.sparse.spmatrix instance. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a + scipy.sparse.spmatrix instance. + + Notes + ----- + If scipy is not installed, this function will always return False. + Examples + -------- + >>> from scipy.sparse import bsr_matrix + >>> is_scipy_sparse(bsr_matrix([1, 2, 3])) + True + >>> is_scipy_sparse(pd.SparseArray([1, 2, 3])) + False + >>> is_scipy_sparse(pd.SparseSeries([1, 2, 3])) + False + """ -def is_scipy_sparse(array): - """ return if we are a scipy.sparse.spmatrix """ global _is_scipy_sparse + if _is_scipy_sparse is None: try: from scipy.sparse import issparse as _is_scipy_sparse except ImportError: _is_scipy_sparse = lambda _: False - return _is_scipy_sparse(array) + return _is_scipy_sparse(arr) -def is_categorical(array): - """ return if we are a categorical possibility """ - return isinstance(array, ABCCategorical) or is_categorical_dtype(array) +def is_categorical(arr): + """ + Check whether an array-like is a Categorical instance. -def is_datetimetz(array): - """ return if we are a datetime with tz array """ - return ((isinstance(array, ABCDatetimeIndex) and - getattr(array, 'tz', None) is not None) or - is_datetime64tz_dtype(array)) + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is of a Categorical instance. + + Examples + -------- + >>> is_categorical([1, 2, 3]) + False + + Categoricals, Series Categoricals, and CategoricalIndex will return True. + + >>> cat = pd.Categorical([1, 2, 3]) + >>> is_categorical(cat) + True + >>> is_categorical(pd.Series(cat)) + True + >>> is_categorical(pd.CategoricalIndex([1, 2, 3])) + True + """ + + return isinstance(arr, ABCCategorical) or is_categorical_dtype(arr) + + +def is_datetimetz(arr): + """ + Check whether an array-like is a datetime array-like with a timezone + component in its dtype. + + Parameters + ---------- + arr : array-like + The array-like to check. + Returns + ------- + boolean : Whether or not the array-like is a datetime array-like with + a timezone component in its dtype. + + Examples + -------- + >>> is_datetimetz([1, 2, 3]) + False + + Although the following examples are both DatetimeIndex objects, + the first one returns False because it has no timezone component + unlike the second one, which returns True. + + >>> is_datetimetz(pd.DatetimeIndex([1, 2, 3])) + False + >>> is_datetimetz(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + True + + The object need not be a DatetimeIndex object. It just needs to have + a dtype which has a timezone component. + + >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern") + >>> s = pd.Series([], dtype=dtype) + >>> is_datetimetz(s) + True + """ + + # TODO: do we need this function? + # It seems like a repeat of is_datetime64tz_dtype. + + return ((isinstance(arr, ABCDatetimeIndex) and + getattr(arr, 'tz', None) is not None) or + is_datetime64tz_dtype(arr)) + + +def is_period(arr): + """ + Check whether an array-like is a periodical index. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a periodical index. + + Examples + -------- + >>> is_period([1, 2, 3]) + False + >>> is_period(pd.Index([1, 2, 3])) + False + >>> is_period(pd.PeriodIndex(["2017-01-01"], freq="D")) + True + """ -def is_period(array): - """ return if we are a period array """ - return isinstance(array, ABCPeriodIndex) or is_period_arraylike(array) + # TODO: do we need this function? + # It seems like a repeat of is_period_arraylike. + return isinstance(arr, ABCPeriodIndex) or is_period_arraylike(arr) def is_datetime64_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the datetime64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is of + the datetime64 dtype. + + Examples + -------- + >>> is_datetime64_dtype(object) + False + >>> is_datetime64_dtype(np.datetime64) + True + >>> is_datetime64_dtype(np.array([], dtype=int)) + False + >>> is_datetime64_dtype(np.array([], dtype=np.datetime64)) + True + >>> is_datetime64_dtype([1, 2, 3]) + False + """ + if arr_or_dtype is None: return False try: @@ -132,12 +331,69 @@ def is_datetime64_dtype(arr_or_dtype): def is_datetime64tz_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of a DatetimeTZDtype dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is of + a DatetimeTZDtype dtype. + + Examples + -------- + >>> is_datetime64tz_dtype(object) + False + >>> is_datetime64tz_dtype([1, 2, 3]) + False + >>> is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3])) # tz-naive + False + >>> is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + True + + >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern") + >>> s = pd.Series([], dtype=dtype) + >>> is_datetime64tz_dtype(dtype) + True + >>> is_datetime64tz_dtype(s) + True + """ + if arr_or_dtype is None: return False return DatetimeTZDtype.is_dtype(arr_or_dtype) def is_timedelta64_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the timedelta64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is + of the timedelta64 dtype. + + Examples + -------- + >>> is_timedelta64_dtype(object) + False + >>> is_timedelta64_dtype(np.timedelta64) + True + >>> is_timedelta64_dtype([1, 2, 3]) + False + >>> is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) + True + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -145,18 +401,102 @@ def is_timedelta64_dtype(arr_or_dtype): def is_period_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the Period dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is of the Period dtype. + + Examples + -------- + >>> is_period_dtype(object) + False + >>> is_period_dtype(PeriodDtype(freq="D")) + True + >>> is_period_dtype([1, 2, 3]) + False + >>> is_period_dtype(pd.Period("2017-01-01")) + False + >>> is_period_dtype(pd.PeriodIndex([], freq="A")) + True + """ + + # TODO: Consider making Period an instance of PeriodDtype if arr_or_dtype is None: return False return PeriodDtype.is_dtype(arr_or_dtype) def is_interval_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the Interval dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is + of the Interval dtype. + + Examples + -------- + >>> is_interval_dtype(object) + False + >>> is_interval_dtype(IntervalDtype()) + True + >>> is_interval_dtype([1, 2, 3]) + False + >>> + >>> interval = pd.Interval(1, 2, closed="right") + >>> is_interval_dtype(interval) + False + >>> is_interval_dtype(pd.IntervalIndex([interval])) + True + """ + + # TODO: Consider making Interval an instance of IntervalDtype if arr_or_dtype is None: return False return IntervalDtype.is_dtype(arr_or_dtype) def is_categorical_dtype(arr_or_dtype): + """ + Check whether an array-like or dtype is of the Categorical dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array-like or dtype to check. + + Returns + ------- + boolean : Whether or not the array-like or dtype is + of the Categorical dtype. + + Examples + -------- + >>> is_categorical_dtype(object) + False + >>> is_categorical_dtype(CategoricalDtype()) + True + >>> is_categorical_dtype([1, 2, 3]) + False + >>> is_categorical_dtype(pd.Categorical([1, 2, 3])) + True + >>> is_categorical_dtype(pd.CategoricalIndex([1, 2, 3])) + True + """ + if arr_or_dtype is None: return False return CategoricalDtype.is_dtype(arr_or_dtype) @@ -168,7 +508,7 @@ def is_string_dtype(arr_or_dtype): Parameters ---------- - arr_or_dtype : ndarray, dtype, type + arr_or_dtype : array-like The array or dtype to check. Returns @@ -186,7 +526,7 @@ def is_string_dtype(arr_or_dtype): >>> >>> is_string_dtype(np.array(['a', 'b'])) True - >>> is_string_dtype(np.array([1, 2])) + >>> is_string_dtype(pd.Series([1, 2])) False """ @@ -202,7 +542,29 @@ def is_string_dtype(arr_or_dtype): def is_period_arraylike(arr): - """ return if we are period arraylike / PeriodIndex """ + """ + Check whether an array-like is a periodical array-like or PeriodIndex. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a periodical + array-like or PeriodIndex instance. + + Examples + -------- + >>> is_period_arraylike([1, 2, 3]) + False + >>> is_period_arraylike(pd.Index([1, 2, 3])) + False + >>> is_period_arraylike(pd.PeriodIndex(["2017-01-01"], freq="D")) + True + """ + if isinstance(arr, ABCPeriodIndex): return True elif isinstance(arr, (np.ndarray, ABCSeries)): @@ -211,7 +573,29 @@ def is_period_arraylike(arr): def is_datetime_arraylike(arr): - """ return if we are datetime arraylike / DatetimeIndex """ + """ + Check whether an array-like is a datetime array-like or DatetimeIndex. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a datetime + array-like or DatetimeIndex. + + Examples + -------- + >>> is_datetime_arraylike([1, 2, 3]) + False + >>> is_datetime_arraylike(pd.Index([1, 2, 3])) + False + >>> is_datetime_arraylike(pd.DatetimeIndex([1, 2, 3])) + True + """ + if isinstance(arr, ABCDatetimeIndex): return True elif isinstance(arr, (np.ndarray, ABCSeries)): @@ -220,6 +604,44 @@ def is_datetime_arraylike(arr): def is_datetimelike(arr): + """ + Check whether an array-like is a datetime-like array-like. + + Acceptable datetime-like objects are (but not limited to) datetime + indices, periodic indices, and timedelta indices. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is a datetime-like array-like. + + Examples + -------- + >>> is_datetimelike([1, 2, 3]) + False + >>> is_datetimelike(pd.Index([1, 2, 3])) + False + >>> is_datetimelike(pd.DatetimeIndex([1, 2, 3])) + True + >>> is_datetimelike(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + True + >>> is_datetimelike(pd.PeriodIndex([], freq="A")) + True + >>> is_datetimelike(np.array([], dtype=np.datetime64)) + True + >>> is_datetimelike(pd.Series([], dtype="timedelta64[ns]")) + True + >>> + >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern") + >>> s = pd.Series([], dtype=dtype) + >>> is_datetimelike(s) + True + """ + return (is_datetime64_dtype(arr) or is_datetime64tz_dtype(arr) or is_timedelta64_dtype(arr) or isinstance(arr, ABCPeriodIndex) or @@ -227,7 +649,32 @@ def is_datetimelike(arr): def is_dtype_equal(source, target): - """ return a boolean if the dtypes are equal """ + """ + Check if two dtypes are equal. + + Parameters + ---------- + source : The first dtype to compare + target : The second dtype to compare + + Returns + ---------- + boolean : Whether or not the two dtypes are equal. + + Examples + -------- + >>> is_dtype_equal(int, float) + False + >>> is_dtype_equal("int", int) + True + >>> is_dtype_equal(object, "category") + False + >>> is_dtype_equal(CategoricalDtype(), "category") + True + >>> is_dtype_equal(DatetimeTZDtype(), "datetime64") + False + """ + try: source = _get_dtype(source) target = _get_dtype(target) @@ -240,6 +687,47 @@ def is_dtype_equal(source, target): def is_any_int_dtype(arr_or_dtype): + """ + DEPRECATED: This function will be removed in a future version. + + Check whether the provided array or dtype is of an integer dtype. + + In this function, timedelta64 instances are also considered "any-integer" + type objects and will return True. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of an integer dtype. + + Examples + -------- + >>> is_any_int_dtype(str) + False + >>> is_any_int_dtype(int) + True + >>> is_any_int_dtype(float) + False + >>> is_any_int_dtype(np.uint64) + True + >>> is_any_int_dtype(np.datetime64) + False + >>> is_any_int_dtype(np.timedelta64) + True + >>> is_any_int_dtype(np.array(['a', 'b'])) + False + >>> is_any_int_dtype(pd.Series([1, 2])) + True + >>> is_any_int_dtype(np.array([], dtype=np.timedelta64)) + True + >>> is_any_int_dtype(pd.Index([1, 2.])) # float + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -247,6 +735,45 @@ def is_any_int_dtype(arr_or_dtype): def is_integer_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of an integer dtype. + + Unlike in `in_any_int_dtype`, timedelta64 instances will return False. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of an integer dtype + and not an instance of timedelta64. + + Examples + -------- + >>> is_integer_dtype(str) + False + >>> is_integer_dtype(int) + True + >>> is_integer_dtype(float) + False + >>> is_integer_dtype(np.uint64) + True + >>> is_integer_dtype(np.datetime64) + False + >>> is_integer_dtype(np.timedelta64) + False + >>> is_integer_dtype(np.array(['a', 'b'])) + False + >>> is_integer_dtype(pd.Series([1, 2])) + True + >>> is_integer_dtype(np.array([], dtype=np.timedelta64)) + False + >>> is_integer_dtype(pd.Index([1, 2.])) # float + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -255,6 +782,47 @@ def is_integer_dtype(arr_or_dtype): def is_signed_integer_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of a signed integer dtype. + + Unlike in `in_any_int_dtype`, timedelta64 instances will return False. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a signed integer dtype + and not an instance of timedelta64. + + Examples + -------- + >>> is_signed_integer_dtype(str) + False + >>> is_signed_integer_dtype(int) + True + >>> is_signed_integer_dtype(float) + False + >>> is_signed_integer_dtype(np.uint64) # unsigned + False + >>> is_signed_integer_dtype(np.datetime64) + False + >>> is_signed_integer_dtype(np.timedelta64) + False + >>> is_signed_integer_dtype(np.array(['a', 'b'])) + False + >>> is_signed_integer_dtype(pd.Series([1, 2])) + True + >>> is_signed_integer_dtype(np.array([], dtype=np.timedelta64)) + False + >>> is_signed_integer_dtype(pd.Index([1, 2.])) # float + False + >>> is_signed_integer_dtype(np.array([1, 2], dtype=np.uint32)) # unsigned + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -263,6 +831,39 @@ def is_signed_integer_dtype(arr_or_dtype): def is_unsigned_integer_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of an unsigned integer dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of an + unsigned integer dtype. + + Examples + -------- + >>> is_unsigned_integer_dtype(str) + False + >>> is_unsigned_integer_dtype(int) # signed + False + >>> is_unsigned_integer_dtype(float) + False + >>> is_unsigned_integer_dtype(np.uint64) + True + >>> is_unsigned_integer_dtype(np.array(['a', 'b'])) + False + >>> is_unsigned_integer_dtype(pd.Series([1, 2])) # signed + False + >>> is_unsigned_integer_dtype(pd.Index([1, 2.])) # float + False + >>> is_unsigned_integer_dtype(np.array([1, 2], dtype=np.uint32)) + True + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -271,6 +872,46 @@ def is_unsigned_integer_dtype(arr_or_dtype): def is_int64_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of the int64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of the int64 dtype. + + Notes + ----- + Depending on system architecture, the return value of `is_int64_dtype( + int)` will be True if the OS uses 64-bit integers and False if the OS + uses 32-bit integers. + + Examples + -------- + >>> is_int64_dtype(str) + False + >>> is_int64_dtype(np.int32) + False + >>> is_int64_dtype(np.int64) + True + >>> is_int64_dtype(float) + False + >>> is_int64_dtype(np.uint64) # unsigned + False + >>> is_int64_dtype(np.array(['a', 'b'])) + False + >>> is_int64_dtype(np.array([1, 2], dtype=np.int64)) + True + >>> is_int64_dtype(pd.Index([1, 2.])) # float + False + >>> is_int64_dtype(np.array([1, 2], dtype=np.uint32)) # unsigned + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -278,6 +919,46 @@ def is_int64_dtype(arr_or_dtype): def is_int_or_datetime_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of an + integer, timedelta64, or datetime64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of an + integer, timedelta64, or datetime64 dtype. + + Examples + -------- + >>> is_int_or_datetime_dtype(str) + False + >>> is_int_or_datetime_dtype(int) + True + >>> is_int_or_datetime_dtype(float) + False + >>> is_int_or_datetime_dtype(np.uint64) + True + >>> is_int_or_datetime_dtype(np.datetime64) + True + >>> is_int_or_datetime_dtype(np.timedelta64) + True + >>> is_int_or_datetime_dtype(np.array(['a', 'b'])) + False + >>> is_int_or_datetime_dtype(pd.Series([1, 2])) + True + >>> is_int_or_datetime_dtype(np.array([], dtype=np.timedelta64)) + True + >>> is_int_or_datetime_dtype(np.array([], dtype=np.datetime64)) + True + >>> is_int_or_datetime_dtype(pd.Index([1, 2.])) # float + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -285,7 +966,40 @@ def is_int_or_datetime_dtype(arr_or_dtype): issubclass(tipo, (np.datetime64, np.timedelta64))) -def is_datetime64_any_dtype(arr_or_dtype): +def is_datetime64_any_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of the datetime64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of the datetime64 dtype. + + Examples + -------- + >>> is_datetime64_any_dtype(str) + False + >>> is_datetime64_any_dtype(int) + False + >>> is_datetime64_any_dtype(np.datetime64) # can be tz-naive + True + >>> is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) + True + >>> is_datetime64_any_dtype(np.array(['a', 'b'])) + False + >>> is_datetime64_any_dtype(np.array([1, 2])) + False + >>> is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) + True + >>> is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], + dtype=np.datetime64)) + True + """ + if arr_or_dtype is None: return False return (is_datetime64_dtype(arr_or_dtype) or @@ -293,6 +1007,42 @@ def is_datetime64_any_dtype(arr_or_dtype): def is_datetime64_ns_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of the datetime64[ns] dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of the datetime64[ns] dtype. + + Examples + -------- + >>> is_datetime64_ns_dtype(str) + False + >>> is_datetime64_ns_dtype(int) + False + >>> is_datetime64_ns_dtype(np.datetime64) # no unit + False + >>> is_datetime64_ns_dtype(DatetimeTZDtype("ns", "US/Eastern")) + True + >>> is_datetime64_ns_dtype(np.array(['a', 'b'])) + False + >>> is_datetime64_ns_dtype(np.array([1, 2])) + False + >>> is_datetime64_ns_dtype(np.array([], dtype=np.datetime64)) # no unit + False + >>> is_datetime64_ns_dtype(np.array([], + dtype="datetime64[ps]")) # wrong unit + False + >>> is_datetime64_ns_dtype(pd.DatetimeIndex([1, 2, 3], + dtype=np.datetime64)) # has 'ns' unit + True + """ + if arr_or_dtype is None: return False try: @@ -314,21 +1064,20 @@ def is_timedelta64_ns_dtype(arr_or_dtype): Parameters ---------- - arr_or_dtype : ndarray, dtype, type + arr_or_dtype : array-like The array or dtype to check. Returns ------- - boolean : Whether or not the array or dtype - is of the timedelta64[ns] dtype. + boolean : Whether or not the array or dtype is of the + timedelta64[ns] dtype. Examples -------- - >>> is_timedelta64_ns_dtype(np.dtype('m8[ns]') + >>> is_timedelta64_ns_dtype(np.dtype('m8[ns]')) True - >>> is_timedelta64_ns_dtype(np.dtype('m8[ps]') # Wrong frequency + >>> is_timedelta64_ns_dtype(np.dtype('m8[ps]')) # Wrong frequency False - >>> >>> is_timedelta64_ns_dtype(np.array([1, 2], dtype='m8[ns]')) True >>> is_timedelta64_ns_dtype(np.array([1, 2], dtype=np.timedelta64)) @@ -345,6 +1094,40 @@ def is_timedelta64_ns_dtype(arr_or_dtype): def is_datetime_or_timedelta_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of + a timedelta64 or datetime64 dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a + timedelta64, or datetime64 dtype. + + Examples + -------- + >>> is_datetime_or_timedelta_dtype(str) + False + >>> is_datetime_or_timedelta_dtype(int) + False + >>> is_datetime_or_timedelta_dtype(np.datetime64) + True + >>> is_datetime_or_timedelta_dtype(np.timedelta64) + True + >>> is_datetime_or_timedelta_dtype(np.array(['a', 'b'])) + False + >>> is_datetime_or_timedelta_dtype(pd.Series([1, 2])) + False + >>> is_datetime_or_timedelta_dtype(np.array([], dtype=np.timedelta64)) + True + >>> is_datetime_or_timedelta_dtype(np.array([], dtype=np.datetime64)) + True + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -378,11 +1161,45 @@ def _is_unorderable_exception(e): def is_numeric_v_string_like(a, b): """ - numpy doesn't like to compare numeric arrays vs scalar string-likes + Check if we are comparing a string-like object to a numeric ndarray. + + NumPy doesn't like to compare such objects, especially numeric arrays + and scalar string-likes. + + Parameters + ---------- + a : array-like, scalar + The first object to check. + b : array-like, scalar + The second object to check. - return a boolean result if this is the case for a,b or b,a + Returns + ------- + boolean : Whether we return a comparing a string-like + object to a numeric array. + Examples + -------- + >>> is_numeric_v_string_like(1, 1) + False + >>> is_numeric_v_string_like("foo", "foo") + False + >>> is_numeric_v_string_like(1, "foo") # non-array numeric + False + >>> is_numeric_v_string_like(np.array([1]), "foo") + True + >>> is_numeric_v_string_like("foo", np.array([1])) # symmetric check + True + >>> is_numeric_v_string_like(np.array([1, 2]), np.array(["foo"])) + True + >>> is_numeric_v_string_like(np.array(["foo"]), np.array([1, 2])) + True + >>> is_numeric_v_string_like(np.array([1]), np.array([2])) + False + >>> is_numeric_v_string_like(np.array(["foo"]), np.array(["foo"])) + False """ + is_a_array = isinstance(a, np.ndarray) is_b_array = isinstance(b, np.ndarray) @@ -401,13 +1218,56 @@ def is_numeric_v_string_like(a, b): def is_datetimelike_v_numeric(a, b): - # return if we have an i8 convertible and numeric comparison + """ + Check if we are comparing a datetime-like object to a numeric object. + + By "numeric," we mean an object that is either of an int or float dtype. + + Parameters + ---------- + a : array-like, scalar + The first object to check. + b : array-like, scalar + The second object to check. + + Returns + ------- + boolean : Whether we return a comparing a datetime-like + to a numeric object. + + Examples + -------- + >>> dt = np.datetime64(pd.datetime(2017, 1, 1)) + >>> + >>> is_datetimelike_v_numeric(1, 1) + False + >>> is_datetimelike_v_numeric(dt, dt) + False + >>> is_datetimelike_v_numeric(1, dt) + True + >>> is_datetimelike_v_numeric(dt, 1) # symmetric check + True + >>> is_datetimelike_v_numeric(np.array([dt]), 1) + True + >>> is_datetimelike_v_numeric(np.array([1]), dt) + True + >>> is_datetimelike_v_numeric(np.array([dt]), np.array([1])) + True + >>> is_datetimelike_v_numeric(np.array([1]), np.array([2])) + False + >>> is_datetimelike_v_numeric(np.array([dt]), np.array([dt])) + False + """ + if not hasattr(a, 'dtype'): a = np.asarray(a) if not hasattr(b, 'dtype'): b = np.asarray(b) def is_numeric(x): + """ + Check if an object has a numeric dtype (i.e. integer or float). + """ return is_integer_dtype(x) or is_float_dtype(x) is_datetimelike = needs_i8_conversion @@ -416,24 +1276,92 @@ def is_numeric(x): def is_datetimelike_v_object(a, b): - # return if we have an i8 convertible and object comparsion + """ + Check if we are comparing a datetime-like object to an object instance. + + Parameters + ---------- + a : array-like, scalar + The first object to check. + b : array-like, scalar + The second object to check. + + Returns + ------- + boolean : Whether we return a comparing a datetime-like + to an object instance. + + Examples + -------- + >>> obj = object() + >>> dt = np.datetime64(pd.datetime(2017, 1, 1)) + >>> + >>> is_datetimelike_v_object(obj, obj) + False + >>> is_datetimelike_v_object(dt, dt) + False + >>> is_datetimelike_v_object(obj, dt) + True + >>> is_datetimelike_v_object(dt, obj) # symmetric check + True + >>> is_datetimelike_v_object(np.array([dt]), obj) + True + >>> is_datetimelike_v_object(np.array([obj]), dt) + True + >>> is_datetimelike_v_object(np.array([dt]), np.array([obj])) + True + >>> is_datetimelike_v_object(np.array([obj]), np.array([obj])) + False + >>> is_datetimelike_v_object(np.array([dt]), np.array([1])) + False + >>> is_datetimelike_v_object(np.array([dt]), np.array([dt])) + False + """ + if not hasattr(a, 'dtype'): a = np.asarray(a) if not hasattr(b, 'dtype'): b = np.asarray(b) - def f(x): - return is_object_dtype(x) - - def is_object(x): - return is_integer_dtype(x) or is_float_dtype(x) - is_datetimelike = needs_i8_conversion - return ((is_datetimelike(a) and is_object(b)) or - (is_datetimelike(b) and is_object(a))) + return ((is_datetimelike(a) and is_object_dtype(b)) or + (is_datetimelike(b) and is_object_dtype(a))) def needs_i8_conversion(arr_or_dtype): + """ + Check whether the array or dtype should be converted to int64. + + An array-like or dtype "needs" such a conversion if the array-like + or dtype is of a datetime-like dtype + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype should be converted to int64. + + Examples + -------- + >>> needs_i8_conversion(str) + False + >>> needs_i8_conversion(np.int64) + False + >>> needs_i8_conversion(np.datetime64) + True + >>> needs_i8_conversion(np.array(['a', 'b'])) + False + >>> needs_i8_conversion(pd.Series([1, 2])) + False + >>> needs_i8_conversion(pd.Series([], dtype="timedelta64[ns]")) + True + >>> needs_i8_conversion(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + True + """ + if arr_or_dtype is None: return False return (is_datetime_or_timedelta_dtype(arr_or_dtype) or @@ -442,6 +1370,42 @@ def needs_i8_conversion(arr_or_dtype): def is_numeric_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of a numeric dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a numeric dtype. + + Examples + -------- + >>> is_numeric_dtype(str) + False + >>> is_numeric_dtype(int) + True + >>> is_numeric_dtype(float) + True + >>> is_numeric_dtype(np.uint64) + True + >>> is_numeric_dtype(np.datetime64) + False + >>> is_numeric_dtype(np.timedelta64) + False + >>> is_numeric_dtype(np.array(['a', 'b'])) + False + >>> is_numeric_dtype(pd.Series([1, 2])) + True + >>> is_numeric_dtype(pd.Index([1, 2.])) + True + >>> is_numeric_dtype(np.array([], dtype=np.timedelta64)) + False + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -458,7 +1422,7 @@ def is_string_like_dtype(arr_or_dtype): Parameters ---------- - arr_or_dtype : ndarray, dtype, type + arr_or_dtype : array-like The array or dtype to check. Returns @@ -471,10 +1435,9 @@ def is_string_like_dtype(arr_or_dtype): True >>> is_string_like_dtype(object) False - >>> >>> is_string_like_dtype(np.array(['a', 'b'])) True - >>> is_string_like_dtype(np.array([1, 2])) + >>> is_string_like_dtype(pd.Series([1, 2])) False """ @@ -488,6 +1451,34 @@ def is_string_like_dtype(arr_or_dtype): def is_float_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of a float dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a float dtype. + + Examples + -------- + >>> is_float_dtype(str) + False + >>> is_float_dtype(int) + False + >>> is_float_dtype(float) + True + >>> is_float_dtype(np.array(['a', 'b'])) + False + >>> is_float_dtype(pd.Series([1, 2])) + False + >>> is_float_dtype(pd.Index([1, 2.])) + True + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -495,6 +1486,16 @@ def is_float_dtype(arr_or_dtype): def is_floating_dtype(arr_or_dtype): + """ + DEPRECATED: This function will be removed in a future version. + + Check whether the provided array or dtype is an instance of + numpy's float dtype. + + Unlike, `is_float_dtype`, this check is a lot stricter, as it requires + `isinstance` of `np.floating` and not `issubclass`. + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -502,6 +1503,36 @@ def is_floating_dtype(arr_or_dtype): def is_bool_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of a boolean dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a boolean dtype. + + Examples + -------- + >>> is_bool_dtype(str) + False + >>> is_bool_dtype(int) + False + >>> is_bool_dtype(bool) + True + >>> is_bool_dtype(np.bool) + True + >>> is_bool_dtype(np.array(['a', 'b'])) + False + >>> is_bool_dtype(pd.Series([1, 2])) + False + >>> is_bool_dtype(np.array([True, False])) + True + """ + if arr_or_dtype is None: return False try: @@ -512,21 +1543,94 @@ def is_bool_dtype(arr_or_dtype): return issubclass(tipo, np.bool_) -def is_extension_type(value): +def is_extension_type(arr): """ - if we are a klass that is preserved by the internals - these are internal klasses that we represent (and don't use a np.array) + Check whether an array-like is of a pandas extension class instance. + + Extension classes include categoricals, pandas sparse objects (i.e. + classes represented within the pandas library and not ones external + to it like scipy sparse matrices), and datetime-like arrays. + + Parameters + ---------- + arr : array-like + The array-like to check. + + Returns + ------- + boolean : Whether or not the array-like is of a pandas + extension class instance. + + Examples + -------- + >>> is_extension_type([1, 2, 3]) + False + >>> is_extension_type(np.array([1, 2, 3])) + False + >>> + >>> cat = pd.Categorical([1, 2, 3]) + >>> + >>> is_extension_type(cat) + True + >>> is_extension_type(pd.Series(cat)) + True + >>> is_extension_type(pd.SparseArray([1, 2, 3])) + True + >>> is_extension_type(pd.SparseSeries([1, 2, 3])) + True + >>> + >>> from scipy.sparse import bsr_matrix + >>> is_extension_type(bsr_matrix([1, 2, 3])) + False + >>> is_extension_type(pd.DatetimeIndex([1, 2, 3])) + False + >>> is_extension_type(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + True + >>> + >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern") + >>> s = pd.Series([], dtype=dtype) + >>> is_extension_type(s) + True """ - if is_categorical(value): + + if is_categorical(arr): return True - elif is_sparse(value): + elif is_sparse(arr): return True - elif is_datetimetz(value): + elif is_datetimetz(arr): return True return False def is_complex_dtype(arr_or_dtype): + """ + Check whether the provided array or dtype is of a complex dtype. + + Parameters + ---------- + arr_or_dtype : array-like + The array or dtype to check. + + Returns + ------- + boolean : Whether or not the array or dtype is of a compex dtype. + + Examples + -------- + >>> is_complex_dtype(str) + False + >>> is_complex_dtype(int) + False + >>> is_complex_dtype(np.complex) + True + >>> is_complex_dtype(np.array(['a', 'b'])) + False + >>> is_complex_dtype(pd.Series([1, 2])) + False + >>> is_complex_dtype(np.array([1 + 1j, 5])) + True + """ + if arr_or_dtype is None: return False tipo = _get_dtype_type(arr_or_dtype) @@ -570,7 +1674,7 @@ def _get_dtype(arr_or_dtype): Parameters ---------- - arr_or_dtype : ndarray, Series, dtype, type + arr_or_dtype : array-like The array-like or dtype object whose dtype we want to extract. Returns @@ -619,7 +1723,7 @@ def _get_dtype_type(arr_or_dtype): Parameters ---------- - arr_or_dtype : ndarray, Series, dtype, type + arr_or_dtype : array-like The array-like or dtype object whose type we want to extract. Returns @@ -754,6 +1858,7 @@ def pandas_dtype(dtype): ------- np.dtype or a pandas dtype """ + if isinstance(dtype, DatetimeTZDtype): return dtype elif isinstance(dtype, PeriodDtype): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 67966374fcf9a..f1a87c303d18b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -63,7 +63,8 @@ _default_index, _values_from_object, _maybe_box_datetimelike, - _dict_compat) + _dict_compat, + _standardize_mapping) from pandas.core.generic import NDFrame, _shared_docs from pandas.core.index import Index, MultiIndex, _ensure_index from pandas.core.indexing import (maybe_droplevels, convert_to_index_sliceable, @@ -80,8 +81,8 @@ OrderedDict, raise_with_traceback) from pandas import compat from pandas.compat.numpy import function as nv -from pandas.util.decorators import Appender, Substitution -from pandas.util.validators import validate_bool_kwarg +from pandas.util._decorators import Appender, Substitution +from pandas.util._validators import validate_bool_kwarg from pandas.core.indexes.period import PeriodIndex from pandas.core.indexes.datetimes import DatetimeIndex @@ -860,7 +861,7 @@ def from_dict(cls, data, orient='columns', dtype=None): return cls(data, index=index, columns=columns, dtype=dtype) - def to_dict(self, orient='dict'): + def to_dict(self, orient='dict', into=dict): """Convert DataFrame to dictionary. Parameters @@ -882,32 +883,45 @@ def to_dict(self, orient='dict'): Abbreviations are allowed. `s` indicates `series` and `sp` indicates `split`. + into : class, default dict + The collections.Mapping subclass used for all Mappings + in the return value. Can be the actual class or an empty + instance of the mapping type you want. If you want a + collections.defaultdict, you must pass an initialized + instance. + .. versionadded:: 0.20.1 + Returns ------- - result : dict like {column -> {index -> value}} + result : collections.Mapping like {column -> {index -> value}} + If ``into`` is collections.defaultdict, the return + value's default_factory will be None. """ if not self.columns.is_unique: warnings.warn("DataFrame columns are not unique, some " "columns will be omitted.", UserWarning) + # GH16122 + into_c = _standardize_mapping(into) if orient.lower().startswith('d'): - return dict((k, v.to_dict()) for k, v in compat.iteritems(self)) + return into_c( + (k, v.to_dict(into)) for k, v in compat.iteritems(self)) elif orient.lower().startswith('l'): - return dict((k, v.tolist()) for k, v in compat.iteritems(self)) + return into_c((k, v.tolist()) for k, v in compat.iteritems(self)) elif orient.lower().startswith('sp'): - return {'index': self.index.tolist(), - 'columns': self.columns.tolist(), - 'data': lib.map_infer(self.values.ravel(), - _maybe_box_datetimelike) - .reshape(self.values.shape).tolist()} + return into_c((('index', self.index.tolist()), + ('columns', self.columns.tolist()), + ('data', lib.map_infer(self.values.ravel(), + _maybe_box_datetimelike) + .reshape(self.values.shape).tolist()))) elif orient.lower().startswith('s'): - return dict((k, _maybe_box_datetimelike(v)) - for k, v in compat.iteritems(self)) + return into_c((k, _maybe_box_datetimelike(v)) + for k, v in compat.iteritems(self)) elif orient.lower().startswith('r'): - return [dict((k, _maybe_box_datetimelike(v)) - for k, v in zip(self.columns, row)) + return [into_c((k, _maybe_box_datetimelike(v)) + for k, v in zip(self.columns, row)) for row in self.values] elif orient.lower().startswith('i'): - return dict((k, v.to_dict()) for k, v in self.iterrows()) + return into_c((k, v.to_dict(into)) for k, v in self.iterrows()) else: raise ValueError("orient '%s' not understood" % orient) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 2bc64795b5f20..27a489293db8f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -51,8 +51,8 @@ from pandas.compat import (map, zip, lzip, lrange, string_types, isidentifier, set_function_name) import pandas.core.nanops as nanops -from pandas.util.decorators import Appender, Substitution, deprecate_kwarg -from pandas.util.validators import validate_bool_kwarg +from pandas.util._decorators import Appender, Substitution, deprecate_kwarg +from pandas.util._validators import validate_bool_kwarg from pandas.core import config # goal is to be able to define the docs close to function, while still being @@ -1382,7 +1382,7 @@ def to_clipboard(self, excel=None, sep=None, **kwargs): - Windows: none - OS X: none """ - from pandas.io import clipboard + from pandas.io.clipboard import clipboard clipboard.to_clipboard(self, excel=excel, sep=sep, **kwargs) def to_xarray(self): diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py index 479d2f7d26eb6..91b55c414b507 100644 --- a/pandas/core/groupby.py +++ b/pandas/core/groupby.py @@ -54,10 +54,10 @@ from pandas.core.sorting import (get_group_index_sorter, get_group_index, compress_group_index, get_flattened_iterator, decons_obs_group_ids, get_indexer_dict) -from pandas.util.decorators import (cache_readonly, Substitution, - Appender, make_signature) +from pandas.util._decorators import (cache_readonly, Substitution, + Appender, make_signature) from pandas.io.formats.printing import pprint_thing -from pandas.util.validators import validate_kwargs +from pandas.util._validators import validate_kwargs import pandas.core.algorithms as algorithms import pandas.core.common as com diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 4345c74664bf5..82f3bf3b15462 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -41,8 +41,8 @@ from pandas.core.base import PandasObject, IndexOpsMixin import pandas.core.base as base -from pandas.util.decorators import (Appender, Substitution, cache_readonly, - deprecate, deprecate_kwarg) +from pandas.util._decorators import (Appender, Substitution, cache_readonly, + deprecate, deprecate_kwarg) from pandas.core.indexes.frozen import FrozenList import pandas.core.common as com import pandas.core.dtypes.concat as _concat diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 760db4ba20675..d9e0c218bfafc 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -16,7 +16,7 @@ from pandas.core.algorithms import take_1d -from pandas.util.decorators import Appender, cache_readonly +from pandas.util._decorators import Appender, cache_readonly from pandas.core.config import get_option from pandas.core.indexes.base import Index, _index_shared_docs import pandas.core.base as base @@ -47,6 +47,9 @@ class CategoricalIndex(Index, base.PandasDelegate): name : object Name to be stored in the index + See Also + -------- + Categorical, Index """ _typ = 'categoricalindex' diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 387209ceb038f..cd8559bcca03c 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -28,7 +28,7 @@ from pandas._libs.period import Period from pandas.core.indexes.base import Index, _index_shared_docs -from pandas.util.decorators import Appender, cache_readonly +from pandas.util._decorators import Appender, cache_readonly import pandas.core.dtypes.concat as _concat import pandas.tseries.frequencies as frequencies diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index b0264759f2f8d..ec678b1577d81 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -41,8 +41,8 @@ from pandas.core.tools.datetimes import ( parse_time_string, normalize_date, to_time) from pandas.core.tools.timedeltas import to_timedelta -from pandas.util.decorators import (Appender, cache_readonly, - deprecate_kwarg, Substitution) +from pandas.util._decorators import (Appender, cache_readonly, + deprecate_kwarg, Substitution) import pandas.core.common as com import pandas.tseries.offsets as offsets import pandas.core.tools.datetimes as tools diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index ccd0d8bee4abc..8363cead01e56 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -28,7 +28,7 @@ from pandas.core.indexes.multi import MultiIndex from pandas.compat.numpy import function as nv from pandas.core import common as com -from pandas.util.decorators import cache_readonly, Appender +from pandas.util._decorators import cache_readonly, Appender from pandas.core.config import get_option import pandas.core.indexes.base as ibase @@ -110,6 +110,10 @@ class IntervalIndex(IntervalMixin, Index): Name to be stored in the index. copy : boolean, default False Copy the meta-data + + See Also + -------- + Index """ _typ = 'intervalindex' _comparables = ['name'] diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index c760d2943b823..7ef037d8f3536 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -26,8 +26,8 @@ is_null_slice) import pandas.core.base as base -from pandas.util.decorators import (Appender, cache_readonly, - deprecate, deprecate_kwarg) +from pandas.util._decorators import (Appender, cache_readonly, + deprecate, deprecate_kwarg) import pandas.core.common as com import pandas.core.missing as missing import pandas.core.algorithms as algos @@ -718,7 +718,7 @@ def _inferred_type_levels(self): @cache_readonly def _hashed_values(self): """ return a uint64 ndarray of my hashed values """ - from pandas.util.hashing import hash_tuples + from pandas.core.util.hashing import hash_tuples return hash_tuples(self) def _hashed_indexing_key(self, key): @@ -740,7 +740,7 @@ def _hashed_indexing_key(self, key): we need to stringify if we have mixed levels """ - from pandas.util.hashing import hash_tuples + from pandas.core.util.hashing import hash_tuples if not isinstance(key, tuple): return hash_tuples(key) diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 21ba2a386d96a..bdae0ac7ac5e9 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -11,7 +11,7 @@ from pandas.core import algorithms from pandas.core.indexes.base import ( Index, InvalidIndexError, _index_shared_docs) -from pandas.util.decorators import Appender, cache_readonly +from pandas.util._decorators import Appender, cache_readonly import pandas.core.indexes.base as ibase diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 378661a49e20d..15fd9b7dc2b6a 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -40,8 +40,8 @@ from pandas.core.indexes.base import _index_shared_docs, _ensure_index from pandas import compat -from pandas.util.decorators import (Appender, Substitution, cache_readonly, - deprecate_kwarg) +from pandas.util._decorators import (Appender, Substitution, cache_readonly, + deprecate_kwarg) from pandas.compat import zip, u import pandas.core.indexes.base as ibase diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index acd040693af2e..b7a8e0b54a128 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -13,7 +13,7 @@ from pandas.compat import lrange, range from pandas.compat.numpy import function as nv from pandas.core.indexes.base import Index, _index_shared_docs -from pandas.util.decorators import Appender, cache_readonly +from pandas.util._decorators import Appender, cache_readonly import pandas.core.indexes.base as ibase from pandas.core.indexes.numeric import Int64Index diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 1081787b2c0b0..ab94a5bffb4f9 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -27,7 +27,7 @@ from pandas.core.indexes.base import _index_shared_docs import pandas.core.common as com import pandas.core.dtypes.concat as _concat -from pandas.util.decorators import Appender, Substitution, deprecate_kwarg +from pandas.util._decorators import Appender, Substitution, deprecate_kwarg from pandas.core.indexes.datetimelike import TimelikeOps, DatetimeIndexOpsMixin from pandas.core.tools.timedeltas import ( to_timedelta, _coerce_scalar_to_timedelta_type) diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 840206977cf30..15851a17274ca 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -64,8 +64,8 @@ from pandas._libs.lib import BlockPlacement import pandas.core.computation.expressions as expressions -from pandas.util.decorators import cache_readonly -from pandas.util.validators import validate_bool_kwarg +from pandas.util._decorators import cache_readonly +from pandas.util._validators import validate_bool_kwarg from pandas import compat, _np_version_under1p9 from pandas.compat import range, map, zip, u diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 41a17a0957cbf..e7cfbdb0fc9c6 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -15,7 +15,7 @@ tslib as libts, algos as libalgos, iNaT) from pandas import compat -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender import pandas.core.computation.expressions as expressions from pandas.compat import bind_method diff --git a/pandas/core/panel.py b/pandas/core/panel.py index 39d2ebdeec3ac..d1f5b4587059c 100644 --- a/pandas/core/panel.py +++ b/pandas/core/panel.py @@ -34,7 +34,7 @@ from pandas.core.ops import _op_descriptions from pandas.core.series import Series from pandas.core.reshape.util import cartesian_product -from pandas.util.decorators import (deprecate, Appender) +from pandas.util._decorators import (deprecate, Appender) _shared_doc_kwargs = dict( axes='items, major_axis, minor_axis', diff --git a/pandas/core/resample.py b/pandas/core/resample.py index cbb2f6a93c2fd..631b91c3aad11 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -25,7 +25,7 @@ from pandas._libs.lib import Timestamp from pandas._libs.period import IncompatibleFrequency -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from pandas.core.generic import _shared_docs _shared_docs_kwargs = dict() diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index 1ca3786ecc174..c55f4b5bf935f 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -34,7 +34,7 @@ from pandas.core.dtypes.missing import na_value_for_dtype from pandas.core.internals import (items_overlap_with_suffix, concatenate_block_managers) -from pandas.util.decorators import Appender, Substitution +from pandas.util._decorators import Appender, Substitution from pandas.core.sorting import is_int64_overflow_possible import pandas.core.algorithms as algos diff --git a/pandas/core/reshape/reshape.py b/pandas/core/reshape/reshape.py index a3cf80d758b7b..779002b300cc7 100644 --- a/pandas/core/reshape/reshape.py +++ b/pandas/core/reshape/reshape.py @@ -20,7 +20,7 @@ from pandas.core.sparse.api import SparseDataFrame, SparseSeries from pandas.core.sparse.array import SparseArray -from pandas.core.sparse.libsparse import IntIndex +from pandas._libs.sparse import IntIndex from pandas.core.categorical import Categorical, _factorize_from_iterable from pandas.core.sorting import (get_group_index, get_compressed_ids, @@ -30,7 +30,7 @@ from pandas._libs import algos as _algos, reshape as _reshape from pandas.core.frame import _shared_docs -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from pandas.core.index import MultiIndex, _get_na_value diff --git a/pandas/core/series.py b/pandas/core/series.py index e5f1d91eedfec..709e4ff08ec90 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -9,6 +9,7 @@ import types import warnings from textwrap import dedent +import collections from numpy import nan, ndarray import numpy as np @@ -46,7 +47,8 @@ _maybe_match_name, SettingWithCopyError, _maybe_box_datetimelike, - _dict_compat) + _dict_compat, + _standardize_mapping) from pandas.core.index import (Index, MultiIndex, InvalidIndexError, Float64Index, _ensure_index) from pandas.core.indexing import check_bool_indexer, maybe_convert_indices @@ -60,7 +62,7 @@ from pandas.core.indexes.timedeltas import TimedeltaIndex from pandas.core.indexes.period import PeriodIndex from pandas import compat -from pandas.util.terminal import get_terminal_size +from pandas.io.formats.terminal import get_terminal_size from pandas.compat import zip, u, OrderedDict, StringIO from pandas.compat.numpy import function as nv @@ -70,8 +72,8 @@ import pandas.core.common as com import pandas.core.nanops as nanops import pandas.io.formats.format as fmt -from pandas.util.decorators import Appender, deprecate_kwarg, Substitution -from pandas.util.validators import validate_bool_kwarg +from pandas.util._decorators import Appender, deprecate_kwarg, Substitution +from pandas.util._validators import validate_bool_kwarg from pandas._libs import index as libindex, tslib as libts, lib, iNaT from pandas.core.config import get_option @@ -1074,15 +1076,28 @@ def tolist(self): """ Convert Series to a nested list """ return list(self.asobject) - def to_dict(self): + def to_dict(self, into=dict): """ - Convert Series to {label -> value} dict + Convert Series to {label -> value} dict or dict-like object + Parameters + ---------- + into : class, default dict + The collections.Mapping subclass to use as the return + object. Can be the actual class or an empty + instance of the mapping type you want. If you want a + collections.defaultdict, you must pass an initialized + .. versionadded:: 0.20.1 Returns ------- - value_dict : dict + value_dict : collections.Mapping + If ``into`` is collections.defaultdict, the return + value's default_factory will be None. """ - return dict(compat.iteritems(self)) + # GH16122 + into_c = _standardize_mapping(into) + return into_c(compat.iteritems(self)) + def to_frame(self, name=None): """ diff --git a/pandas/core/sparse/array.py b/pandas/core/sparse/array.py index ef3600266c037..8ac9d3916573e 100644 --- a/pandas/core/sparse/array.py +++ b/pandas/core/sparse/array.py @@ -29,13 +29,13 @@ astype_nansafe, find_common_type) from pandas.core.dtypes.missing import isnull, notnull, na_value_for_dtype -from pandas.core.sparse import libsparse as splib -from pandas.core.sparse.libsparse import SparseIndex, BlockIndex, IntIndex +import pandas._libs.sparse as splib +from pandas._libs.sparse import SparseIndex, BlockIndex, IntIndex from pandas._libs import index as libindex import pandas.core.algorithms as algos import pandas.core.ops as ops import pandas.io.formats.printing as printing -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from pandas.core.indexes.base import _index_shared_docs diff --git a/pandas/core/sparse/frame.py b/pandas/core/sparse/frame.py index 05c97fac4b53a..3c8f6e8c6257d 100644 --- a/pandas/core/sparse/frame.py +++ b/pandas/core/sparse/frame.py @@ -25,8 +25,8 @@ create_block_manager_from_arrays) import pandas.core.generic as generic from pandas.core.sparse.series import SparseSeries, SparseArray -from pandas.core.sparse.libsparse import BlockIndex, get_blocks -from pandas.util.decorators import Appender +from pandas._libs.sparse import BlockIndex, get_blocks +from pandas.util._decorators import Appender import pandas.core.ops as ops diff --git a/pandas/core/sparse/list.py b/pandas/core/sparse/list.py index e69ad6d0ab7ad..e2a8c6a29cc23 100644 --- a/pandas/core/sparse/list.py +++ b/pandas/core/sparse/list.py @@ -5,8 +5,8 @@ from pandas.core.dtypes.common import is_scalar from pandas.core.sparse.array import SparseArray -from pandas.util.validators import validate_bool_kwarg -from pandas.core.sparse import libsparse as splib +from pandas.util._validators import validate_bool_kwarg +import pandas._libs.sparse as splib class SparseList(PandasObject): diff --git a/pandas/core/sparse/series.py b/pandas/core/sparse/series.py index a77bce8f06783..9dd061e26ba06 100644 --- a/pandas/core/sparse/series.py +++ b/pandas/core/sparse/series.py @@ -21,13 +21,13 @@ import pandas.core.common as com import pandas.core.ops as ops import pandas._libs.index as _index -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from pandas.core.sparse.array import ( make_sparse, _sparse_array_op, SparseArray, _make_index) -from pandas.core.sparse.libsparse import BlockIndex, IntIndex -import pandas.core.sparse.libsparse as splib +from pandas._libs.sparse import BlockIndex, IntIndex +import pandas._libs.sparse as splib from pandas.core.sparse.scipy_sparse import ( _sparse_series_to_coo, diff --git a/pandas/core/strings.py b/pandas/core/strings.py index 5082ac7f80fbf..c57d7a9362490 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -17,7 +17,7 @@ from pandas.core.algorithms import take_1d import pandas.compat as compat from pandas.core.base import AccessorProperty, NoNewAttributesMixin -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender import re import pandas._libs.lib as lib import warnings diff --git a/pandas/util/importing.py b/pandas/core/util/__init__.py similarity index 100% rename from pandas/util/importing.py rename to pandas/core/util/__init__.py diff --git a/pandas/util/hashing.py b/pandas/core/util/hashing.py similarity index 94% rename from pandas/util/hashing.py rename to pandas/core/util/hashing.py index 3046c62a03f48..6a5343e8a8e25 100644 --- a/pandas/util/hashing.py +++ b/pandas/core/util/hashing.py @@ -4,10 +4,10 @@ import itertools import numpy as np -from pandas import Series, factorize, Categorical, Index, MultiIndex -from pandas.util import libhashing as _hash +from pandas._libs import hashing from pandas._libs.lib import is_bool_array from pandas.core.dtypes.generic import ( + ABCMultiIndex, ABCIndexClass, ABCSeries, ABCDataFrame) @@ -73,10 +73,11 @@ def hash_pandas_object(obj, index=True, encoding='utf8', hash_key=None, Series of uint64, same length as the object """ + from pandas import Series if hash_key is None: hash_key = _default_hash_key - if isinstance(obj, MultiIndex): + if isinstance(obj, ABCMultiIndex): return Series(hash_tuples(obj, encoding, hash_key), dtype='uint64', copy=False) @@ -143,7 +144,9 @@ def hash_tuples(vals, encoding='utf8', hash_key=None): elif not is_list_like(vals): raise TypeError("must be convertible to a list-of-tuples") - if not isinstance(vals, MultiIndex): + from pandas import Categorical, MultiIndex + + if not isinstance(vals, ABCMultiIndex): vals = MultiIndex.from_tuples(vals) # create a list-of-Categoricals @@ -257,17 +260,18 @@ def hash_array(vals, encoding='utf8', hash_key=None, categorize=True): # then hash and rename categories. We allow skipping the categorization # when the values are known/likely to be unique. if categorize: + from pandas import factorize, Categorical, Index codes, categories = factorize(vals, sort=False) cat = Categorical(codes, Index(categories), ordered=False, fastpath=True) return _hash_categorical(cat, encoding, hash_key) try: - vals = _hash.hash_object_array(vals, hash_key, encoding) + vals = hashing.hash_object_array(vals, hash_key, encoding) except TypeError: # we have mixed types - vals = _hash.hash_object_array(vals.astype(str).astype(object), - hash_key, encoding) + vals = hashing.hash_object_array(vals.astype(str).astype(object), + hash_key, encoding) # Then, redistribute these 64-bit ints within the space of 64-bit ints vals ^= vals >> 30 diff --git a/pandas/core/window.py b/pandas/core/window.py index 6d8f12e982f12..df8e0c05009f4 100644 --- a/pandas/core/window.py +++ b/pandas/core/window.py @@ -33,12 +33,12 @@ from pandas.core.base import (PandasObject, SelectionMixin, GroupByMixin) import pandas.core.common as com -import pandas.core.libwindow as _window +import pandas._libs.window as _window from pandas.tseries.offsets import DateOffset from pandas import compat from pandas.compat.numpy import function as nv -from pandas.util.decorators import (Substitution, Appender, - cache_readonly) +from pandas.util._decorators import (Substitution, Appender, + cache_readonly) from pandas.core.generic import _shared_docs from textwrap import dedent diff --git a/pandas/io/api.py b/pandas/io/api.py index e312e7bc2f300..7f0d3c3631f63 100644 --- a/pandas/io/api.py +++ b/pandas/io/api.py @@ -5,7 +5,7 @@ # flake8: noqa from pandas.io.parsers import read_csv, read_table, read_fwf -from pandas.io.clipboard import read_clipboard +from pandas.io.clipboard.clipboard import read_clipboard from pandas.io.excel import ExcelFile, ExcelWriter, read_excel from pandas.io.pytables import HDFStore, get_store, read_hdf from pandas.io.json import read_json diff --git a/pandas/util/clipboard/__init__.py b/pandas/io/clipboard/__init__.py similarity index 100% rename from pandas/util/clipboard/__init__.py rename to pandas/io/clipboard/__init__.py diff --git a/pandas/io/clipboard.py b/pandas/io/clipboard/clipboard.py similarity index 97% rename from pandas/io/clipboard.py rename to pandas/io/clipboard/clipboard.py index 3c7ac528d83fd..6252a02b0d63d 100644 --- a/pandas/io/clipboard.py +++ b/pandas/io/clipboard/clipboard.py @@ -26,7 +26,7 @@ def read_clipboard(sep='\s+', **kwargs): # pragma: no cover raise NotImplementedError( 'reading from clipboard only supports utf-8 encoding') - from pandas.util.clipboard import clipboard_get + from pandas.io.clipboard import clipboard_get from pandas.io.parsers import read_table text = clipboard_get() @@ -92,7 +92,7 @@ def to_clipboard(obj, excel=None, sep=None, **kwargs): # pragma: no cover if encoding is not None and encoding.lower().replace('-', '') != 'utf8': raise ValueError('clipboard only supports utf-8 encoding') - from pandas.util.clipboard import clipboard_set + from pandas.io.clipboard import clipboard_set if excel is None: excel = True diff --git a/pandas/util/clipboard/clipboards.py b/pandas/io/clipboard/clipboards.py similarity index 100% rename from pandas/util/clipboard/clipboards.py rename to pandas/io/clipboard/clipboards.py diff --git a/pandas/util/clipboard/exceptions.py b/pandas/io/clipboard/exceptions.py similarity index 100% rename from pandas/util/clipboard/exceptions.py rename to pandas/io/clipboard/exceptions.py diff --git a/pandas/util/clipboard/windows.py b/pandas/io/clipboard/windows.py similarity index 100% rename from pandas/util/clipboard/windows.py rename to pandas/io/clipboard/windows.py diff --git a/pandas/io/excel.py b/pandas/io/excel.py index fbb10ebdfc56d..9b0f49ccc45b1 100644 --- a/pandas/io/excel.py +++ b/pandas/io/excel.py @@ -20,7 +20,7 @@ from pandas.io.common import (_is_url, _urlopen, _validate_header_arg, get_filepath_or_buffer, _NA_VALUES) from pandas.core.indexes.period import Period -from pandas.io.json import libjson +import pandas._libs.json as json from pandas.compat import (map, zip, reduce, range, lrange, u, add_metaclass, string_types, OrderedDict) from pandas.core import config @@ -29,7 +29,7 @@ import pandas.compat.openpyxl_compat as openpyxl_compat from warnings import warn from distutils.version import LooseVersion -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from textwrap import fill __all__ = ["read_excel", "ExcelWriter", "ExcelFile"] @@ -1447,7 +1447,7 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0, elif isinstance(cell.val, date): num_format_str = self.date_format - stylekey = libjson.dumps(cell.style) + stylekey = json.dumps(cell.style) if num_format_str: stylekey += num_format_str @@ -1575,7 +1575,7 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0, elif isinstance(cell.val, date): num_format_str = self.date_format - stylekey = libjson.dumps(cell.style) + stylekey = json.dumps(cell.style) if num_format_str: stylekey += num_format_str diff --git a/pandas/io/formats/console.py b/pandas/io/formats/console.py index 0e46b0073a53d..ab75e3fa253ce 100644 --- a/pandas/io/formats/console.py +++ b/pandas/io/formats/console.py @@ -4,7 +4,7 @@ import sys import locale -from pandas.util.terminal import get_terminal_size +from pandas.io.formats.terminal import get_terminal_size # ----------------------------------------------------------------------------- # Global formatting options diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 43b0b5fbeee90..65098bb2aa404 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -30,7 +30,7 @@ from pandas import compat from pandas.compat import (StringIO, lzip, range, map, zip, u, OrderedDict, unichr) -from pandas.util.terminal import get_terminal_size +from pandas.io.formats.terminal import get_terminal_size from pandas.core.config import get_option, set_option from pandas.io.common import _get_handle, UnicodeWriter, _expand_user from pandas.io.formats.printing import adjoin, justify, pprint_thing diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 71c61998be092..eac82ddde2318 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -29,7 +29,7 @@ from pandas.core.generic import _shared_docs import pandas.core.common as com from pandas.core.indexing import _maybe_numeric_slice, _non_reducing_slice -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender try: import matplotlib.pyplot as plt from matplotlib import colors diff --git a/pandas/util/terminal.py b/pandas/io/formats/terminal.py similarity index 100% rename from pandas/util/terminal.py rename to pandas/io/formats/terminal.py diff --git a/pandas/io/json/json.py b/pandas/io/json/json.py index 28ea8298cee9e..b2fe074732cbb 100644 --- a/pandas/io/json/json.py +++ b/pandas/io/json/json.py @@ -2,7 +2,7 @@ import os import numpy as np -from pandas.io.json import libjson +import pandas._libs.json as json from pandas._libs.tslib import iNaT from pandas.compat import StringIO, long, u from pandas import compat, isnull @@ -14,8 +14,8 @@ from .table_schema import build_table_schema from pandas.core.dtypes.common import is_period_dtype -loads = libjson.loads -dumps = libjson.dumps +loads = json.loads +dumps = json.dumps TABLE_SCHEMA_VERSION = '0.20.0' diff --git a/pandas/io/parsers.py b/pandas/io/parsers.py index 95b1394c88ac2..ce8643504932f 100755 --- a/pandas/io/parsers.py +++ b/pandas/io/parsers.py @@ -37,10 +37,10 @@ _NA_VALUES, _infer_compression) from pandas.core.tools import datetimes as tools -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender import pandas._libs.lib as lib -import pandas.io.libparsers as libparsers +import pandas._libs.parsers as parsers # BOM character (byte order mark) @@ -1460,7 +1460,7 @@ def _convert_to_ndarrays(self, dct, na_values, na_fvalues, verbose=False, if issubclass(cvals.dtype.type, np.integer) and self.compact_ints: cvals = lib.downcast_int64( - cvals, libparsers.na_values, + cvals, parsers.na_values, self.use_unsigned) result[c] = cvals @@ -1579,7 +1579,7 @@ def __init__(self, src, **kwds): # #2442 kwds['allow_leading_cols'] = self.index_col is not False - self._reader = libparsers.TextReader(src, **kwds) + self._reader = parsers.TextReader(src, **kwds) # XXX self.usecols, self.usecols_dtype = _validate_usecols_arg( diff --git a/pandas/io/sas/sas7bdat.py b/pandas/io/sas/sas7bdat.py index d33cee2c5a1bc..20b0cf85e95b7 100644 --- a/pandas/io/sas/sas7bdat.py +++ b/pandas/io/sas/sas7bdat.py @@ -20,7 +20,7 @@ import numpy as np import struct import pandas.io.sas.sas_constants as const -from pandas.io.sas.libsas import Parser +from pandas.io.sas._sas import Parser class _subheader_pointer(object): diff --git a/pandas/io/sas/sas_xport.py b/pandas/io/sas/sas_xport.py index 76fc55154bc49..a43a5988a2ade 100644 --- a/pandas/io/sas/sas_xport.py +++ b/pandas/io/sas/sas_xport.py @@ -14,7 +14,7 @@ from pandas import compat import struct import numpy as np -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender import warnings _correct_line1 = ("HEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!" diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 691582629251a..55cac83804cd9 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -27,7 +27,7 @@ from pandas import compat, to_timedelta, to_datetime, isnull, DatetimeIndex from pandas.compat import lrange, lmap, lzip, text_type, string_types, range, \ zip, BytesIO -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender import pandas as pd from pandas.io.common import get_filepath_or_buffer, BaseIterator diff --git a/pandas/json.py b/pandas/json.py index 5b1e395fa4b74..0b87aa22394b9 100644 --- a/pandas/json.py +++ b/pandas/json.py @@ -4,4 +4,4 @@ warnings.warn("The pandas.json module is deprecated and will be " "removed in a future version. Please import from " "the pandas.io.json instead", FutureWarning, stacklevel=2) -from pandas.io.json.libjson import dumps, loads +from pandas._libs.json import dumps, loads diff --git a/pandas/parser.py b/pandas/parser.py index af203c3df8cc9..c0c3bf3179a2d 100644 --- a/pandas/parser.py +++ b/pandas/parser.py @@ -4,5 +4,5 @@ warnings.warn("The pandas.parser module is deprecated and will be " "removed in a future version. Please import from " "the pandas.io.parser instead", FutureWarning, stacklevel=2) -from pandas.io.libparsers import na_values +from pandas._libs.parsers import na_values from pandas.io.common import CParserError diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index c3476d1443fc3..e88979b14c8af 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -9,7 +9,7 @@ import numpy as np -from pandas.util.decorators import cache_readonly +from pandas.util._decorators import cache_readonly from pandas.core.base import PandasObject from pandas.core.dtypes.common import ( is_list_like, @@ -25,7 +25,7 @@ from pandas.compat import range, lrange, map, zip, string_types import pandas.compat as compat from pandas.io.formats.printing import pprint_thing -from pandas.util.decorators import Appender +from pandas.util._decorators import Appender from pandas.plotting._compat import (_mpl_ge_1_3_1, _mpl_ge_1_5_0) diff --git a/pandas/plotting/_misc.py b/pandas/plotting/_misc.py index 93eceba9a3f02..20ada033c0f58 100644 --- a/pandas/plotting/_misc.py +++ b/pandas/plotting/_misc.py @@ -4,7 +4,7 @@ import numpy as np -from pandas.util.decorators import deprecate_kwarg +from pandas.util._decorators import deprecate_kwarg from pandas.core.dtypes.missing import notnull from pandas.compat import range, lrange, lmap, zip from pandas.io.formats.printing import pprint_thing diff --git a/pandas/stats/moments.py b/pandas/stats/moments.py index f98ffa26e0c2b..f6c3a08c6721a 100644 --- a/pandas/stats/moments.py +++ b/pandas/stats/moments.py @@ -8,7 +8,7 @@ import numpy as np from pandas.core.dtypes.common import is_scalar from pandas.core.api import DataFrame, Series -from pandas.util.decorators import Substitution, Appender +from pandas.util._decorators import Substitution, Appender __all__ = ['rolling_count', 'rolling_max', 'rolling_min', 'rolling_sum', 'rolling_mean', 'rolling_std', 'rolling_cov', diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index 4678db4a52c5a..b1652cf6eb6db 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -23,7 +23,7 @@ def check(self, namespace, expected, ignored=None): tm.assert_almost_equal(result, expected) -class TestPDApi(Base, tm.TestCase): +class TestPDApi(Base): # these are optionally imported based on testing # & need to be ignored @@ -117,7 +117,7 @@ def test_api(self): self.ignored) -class TestApi(Base, tm.TestCase): +class TestApi(Base): allowed = ['types'] @@ -137,7 +137,7 @@ def test_testing(self): self.check(testing, self.funcs) -class TestDatetoolsDeprecation(tm.TestCase): +class TestDatetoolsDeprecation(object): def test_deprecation_access_func(self): with tm.assert_produces_warning(FutureWarning, @@ -150,7 +150,7 @@ def test_deprecation_access_obj(self): pd.datetools.monthEnd -class TestTopLevelDeprecations(tm.TestCase): +class TestTopLevelDeprecations(object): # top-level API deprecations # GH 13790 @@ -191,35 +191,35 @@ def test_get_store(self): s.close() -class TestJson(tm.TestCase): +class TestJson(object): def test_deprecation_access_func(self): with catch_warnings(record=True): pd.json.dumps([]) -class TestParser(tm.TestCase): +class TestParser(object): def test_deprecation_access_func(self): with catch_warnings(record=True): pd.parser.na_values -class TestLib(tm.TestCase): +class TestLib(object): def test_deprecation_access_func(self): with catch_warnings(record=True): pd.lib.infer_dtype('foo') -class TestTSLib(tm.TestCase): +class TestTSLib(object): def test_deprecation_access_func(self): with catch_warnings(record=True): pd.tslib.Timestamp('20160101') -class TestTypes(tm.TestCase): +class TestTypes(object): def test_deprecation_access_func(self): with tm.assert_produces_warning( diff --git a/pandas/tests/api/test_types.py b/pandas/tests/api/test_types.py index 834857b87960c..1cbcf3f9109a4 100644 --- a/pandas/tests/api/test_types.py +++ b/pandas/tests/api/test_types.py @@ -13,7 +13,7 @@ from .test_api import Base -class TestTypes(Base, tm.TestCase): +class TestTypes(Base): allowed = ['is_bool', 'is_bool_dtype', 'is_categorical', 'is_categorical_dtype', 'is_complex', diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py index f8f84985142a8..89ab4531877a4 100644 --- a/pandas/tests/computation/test_eval.py +++ b/pandas/tests/computation/test_eval.py @@ -95,11 +95,10 @@ def _is_py3_complex_incompat(result, expected): _good_arith_ops = com.difference(_arith_ops_syms, _special_case_arith_ops_syms) -class TestEvalNumexprPandas(tm.TestCase): +class TestEvalNumexprPandas(object): @classmethod - def setUpClass(cls): - super(TestEvalNumexprPandas, cls).setUpClass() + def setup_class(cls): tm.skip_if_no_ne() import numexpr as ne cls.ne = ne @@ -107,8 +106,7 @@ def setUpClass(cls): cls.parser = 'pandas' @classmethod - def tearDownClass(cls): - super(TestEvalNumexprPandas, cls).tearDownClass() + def teardown_class(cls): del cls.engine, cls.parser if hasattr(cls, 'ne'): del cls.ne @@ -137,12 +135,12 @@ def setup_ops(self): self.arith_ops = _good_arith_ops self.unary_ops = '-', '~', 'not ' - def setUp(self): + def setup_method(self, method): self.setup_ops() self.setup_data() self.current_engines = filter(lambda x: x != self.engine, _engines) - def tearDown(self): + def teardown_method(self, method): del self.lhses, self.rhses, self.scalar_rhses, self.scalar_lhses del self.pandas_rhses, self.pandas_lhses, self.current_engines @@ -723,8 +721,8 @@ def test_float_truncation(self): class TestEvalNumexprPython(TestEvalNumexprPandas): @classmethod - def setUpClass(cls): - super(TestEvalNumexprPython, cls).setUpClass() + def setup_class(cls): + super(TestEvalNumexprPython, cls).setup_class() tm.skip_if_no_ne() import numexpr as ne cls.ne = ne @@ -750,8 +748,8 @@ def check_chained_cmp_op(self, lhs, cmp1, mid, cmp2, rhs): class TestEvalPythonPython(TestEvalNumexprPython): @classmethod - def setUpClass(cls): - super(TestEvalPythonPython, cls).setUpClass() + def setup_class(cls): + super(TestEvalPythonPython, cls).setup_class() cls.engine = 'python' cls.parser = 'python' @@ -780,8 +778,8 @@ def check_alignment(self, result, nlhs, ghs, op): class TestEvalPythonPandas(TestEvalPythonPython): @classmethod - def setUpClass(cls): - super(TestEvalPythonPandas, cls).setUpClass() + def setup_class(cls): + super(TestEvalPythonPandas, cls).setup_class() cls.engine = 'python' cls.parser = 'pandas' @@ -1067,19 +1065,17 @@ def test_performance_warning_for_poor_alignment(self, engine, parser): # ------------------------------------ # Slightly more complex ops -class TestOperationsNumExprPandas(tm.TestCase): +class TestOperationsNumExprPandas(object): @classmethod - def setUpClass(cls): - super(TestOperationsNumExprPandas, cls).setUpClass() + def setup_class(cls): tm.skip_if_no_ne() cls.engine = 'numexpr' cls.parser = 'pandas' cls.arith_ops = expr._arith_ops_syms + expr._cmp_ops_syms @classmethod - def tearDownClass(cls): - super(TestOperationsNumExprPandas, cls).tearDownClass() + def teardown_class(cls): del cls.engine, cls.parser def eval(self, *args, **kwargs): @@ -1492,8 +1488,8 @@ def test_simple_in_ops(self): class TestOperationsNumExprPython(TestOperationsNumExprPandas): @classmethod - def setUpClass(cls): - super(TestOperationsNumExprPython, cls).setUpClass() + def setup_class(cls): + super(TestOperationsNumExprPython, cls).setup_class() cls.engine = 'numexpr' cls.parser = 'python' tm.skip_if_no_ne(cls.engine) @@ -1566,8 +1562,8 @@ def test_simple_bool_ops(self): class TestOperationsPythonPython(TestOperationsNumExprPython): @classmethod - def setUpClass(cls): - super(TestOperationsPythonPython, cls).setUpClass() + def setup_class(cls): + super(TestOperationsPythonPython, cls).setup_class() cls.engine = cls.parser = 'python' cls.arith_ops = expr._arith_ops_syms + expr._cmp_ops_syms cls.arith_ops = filter(lambda x: x not in ('in', 'not in'), @@ -1577,18 +1573,17 @@ def setUpClass(cls): class TestOperationsPythonPandas(TestOperationsNumExprPandas): @classmethod - def setUpClass(cls): - super(TestOperationsPythonPandas, cls).setUpClass() + def setup_class(cls): + super(TestOperationsPythonPandas, cls).setup_class() cls.engine = 'python' cls.parser = 'pandas' cls.arith_ops = expr._arith_ops_syms + expr._cmp_ops_syms -class TestMathPythonPython(tm.TestCase): +class TestMathPythonPython(object): @classmethod - def setUpClass(cls): - super(TestMathPythonPython, cls).setUpClass() + def setup_class(cls): tm.skip_if_no_ne() cls.engine = 'python' cls.parser = 'pandas' @@ -1596,7 +1591,7 @@ def setUpClass(cls): cls.binary_fns = _binary_math_ops @classmethod - def tearDownClass(cls): + def teardown_class(cls): del cls.engine, cls.parser def eval(self, *args, **kwargs): @@ -1694,8 +1689,8 @@ def test_keyword_arg(self): class TestMathPythonPandas(TestMathPythonPython): @classmethod - def setUpClass(cls): - super(TestMathPythonPandas, cls).setUpClass() + def setup_class(cls): + super(TestMathPythonPandas, cls).setup_class() cls.engine = 'python' cls.parser = 'pandas' @@ -1703,8 +1698,8 @@ def setUpClass(cls): class TestMathNumExprPandas(TestMathPythonPython): @classmethod - def setUpClass(cls): - super(TestMathNumExprPandas, cls).setUpClass() + def setup_class(cls): + super(TestMathNumExprPandas, cls).setup_class() cls.engine = 'numexpr' cls.parser = 'pandas' @@ -1712,8 +1707,8 @@ def setUpClass(cls): class TestMathNumExprPython(TestMathPythonPython): @classmethod - def setUpClass(cls): - super(TestMathNumExprPython, cls).setUpClass() + def setup_class(cls): + super(TestMathNumExprPython, cls).setup_class() cls.engine = 'numexpr' cls.parser = 'python' @@ -1873,7 +1868,7 @@ def test_negate_lt_eq_le(engine, parser): tm.assert_frame_equal(result, expected) -class TestValidate(tm.TestCase): +class TestValidate(object): def test_validate_bool_args(self): invalid_values = [1, "True", [1, 2, 3], 5.0] diff --git a/pandas/tests/dtypes/test_cast.py b/pandas/tests/dtypes/test_cast.py index cbf049b95b6ef..e92724a5d9cd4 100644 --- a/pandas/tests/dtypes/test_cast.py +++ b/pandas/tests/dtypes/test_cast.py @@ -26,7 +26,7 @@ from pandas.util import testing as tm -class TestMaybeDowncast(tm.TestCase): +class TestMaybeDowncast(object): def test_downcast_conv(self): # test downcasting @@ -156,7 +156,7 @@ def test_infer_dtype_from_array(self, arr, expected): assert dtype == expected -class TestMaybe(tm.TestCase): +class TestMaybe(object): def test_maybe_convert_string_to_array(self): result = maybe_convert_string_to_object('x') @@ -214,7 +214,7 @@ def test_maybe_convert_scalar(self): assert result == Timedelta('1 day 1 min').value -class TestConvert(tm.TestCase): +class TestConvert(object): def test_maybe_convert_objects_copy(self): values = np.array([1, 2]) @@ -233,7 +233,7 @@ def test_maybe_convert_objects_copy(self): assert values is not out -class TestCommonTypes(tm.TestCase): +class TestCommonTypes(object): def test_numpy_dtypes(self): # (source_types, destination_type) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 0472f0599cd9b..4633dde5ed537 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -4,15 +4,14 @@ import numpy as np import pandas as pd -from pandas.core.dtypes.dtypes import ( - DatetimeTZDtype, PeriodDtype, CategoricalDtype) -from pandas.core.dtypes.common import ( - pandas_dtype, is_dtype_equal) +from pandas.core.dtypes.dtypes import (DatetimeTZDtype, PeriodDtype, + CategoricalDtype, IntervalDtype) +import pandas.core.dtypes.common as com import pandas.util.testing as tm -class TestPandasDtype(tm.TestCase): +class TestPandasDtype(object): # Passing invalid dtype, both as a string or object, must raise TypeError # Per issue GH15520 @@ -21,49 +20,49 @@ def test_invalid_dtype_error(self): invalid_list = [pd.Timestamp, 'pd.Timestamp', list] for dtype in invalid_list: with tm.assert_raises_regex(TypeError, msg): - pandas_dtype(dtype) + com.pandas_dtype(dtype) valid_list = [object, 'float64', np.object_, np.dtype('object'), 'O', np.float64, float, np.dtype('float64')] for dtype in valid_list: - pandas_dtype(dtype) + com.pandas_dtype(dtype) def test_numpy_dtype(self): for dtype in ['M8[ns]', 'm8[ns]', 'object', 'float64', 'int64']: - assert pandas_dtype(dtype) == np.dtype(dtype) + assert com.pandas_dtype(dtype) == np.dtype(dtype) def test_numpy_string_dtype(self): # do not parse freq-like string as period dtype - assert pandas_dtype('U') == np.dtype('U') - assert pandas_dtype('S') == np.dtype('S') + assert com.pandas_dtype('U') == np.dtype('U') + assert com.pandas_dtype('S') == np.dtype('S') def test_datetimetz_dtype(self): for dtype in ['datetime64[ns, US/Eastern]', 'datetime64[ns, Asia/Tokyo]', 'datetime64[ns, UTC]']: - assert pandas_dtype(dtype) is DatetimeTZDtype(dtype) - assert pandas_dtype(dtype) == DatetimeTZDtype(dtype) - assert pandas_dtype(dtype) == dtype + assert com.pandas_dtype(dtype) is DatetimeTZDtype(dtype) + assert com.pandas_dtype(dtype) == DatetimeTZDtype(dtype) + assert com.pandas_dtype(dtype) == dtype def test_categorical_dtype(self): - assert pandas_dtype('category') == CategoricalDtype() + assert com.pandas_dtype('category') == CategoricalDtype() def test_period_dtype(self): for dtype in ['period[D]', 'period[3M]', 'period[U]', 'Period[D]', 'Period[3M]', 'Period[U]']: - assert pandas_dtype(dtype) is PeriodDtype(dtype) - assert pandas_dtype(dtype) == PeriodDtype(dtype) - assert pandas_dtype(dtype) == dtype + assert com.pandas_dtype(dtype) is PeriodDtype(dtype) + assert com.pandas_dtype(dtype) == PeriodDtype(dtype) + assert com.pandas_dtype(dtype) == dtype -dtypes = dict(datetime_tz=pandas_dtype('datetime64[ns, US/Eastern]'), - datetime=pandas_dtype('datetime64[ns]'), - timedelta=pandas_dtype('timedelta64[ns]'), +dtypes = dict(datetime_tz=com.pandas_dtype('datetime64[ns, US/Eastern]'), + datetime=com.pandas_dtype('datetime64[ns]'), + timedelta=com.pandas_dtype('timedelta64[ns]'), period=PeriodDtype('D'), integer=np.dtype(np.int64), float=np.dtype(np.float64), object=np.dtype(np.object), - category=pandas_dtype('category')) + category=com.pandas_dtype('category')) @pytest.mark.parametrize('name1,dtype1', @@ -75,31 +74,30 @@ def test_period_dtype(self): def test_dtype_equal(name1, dtype1, name2, dtype2): # match equal to self, but not equal to other - assert is_dtype_equal(dtype1, dtype1) + assert com.is_dtype_equal(dtype1, dtype1) if name1 != name2: - assert not is_dtype_equal(dtype1, dtype2) + assert not com.is_dtype_equal(dtype1, dtype2) def test_dtype_equal_strict(): # we are strict on kind equality for dtype in [np.int8, np.int16, np.int32]: - assert not is_dtype_equal(np.int64, dtype) + assert not com.is_dtype_equal(np.int64, dtype) for dtype in [np.float32]: - assert not is_dtype_equal(np.float64, dtype) + assert not com.is_dtype_equal(np.float64, dtype) # strict w.r.t. PeriodDtype - assert not is_dtype_equal(PeriodDtype('D'), - PeriodDtype('2D')) + assert not com.is_dtype_equal(PeriodDtype('D'), PeriodDtype('2D')) # strict w.r.t. datetime64 - assert not is_dtype_equal( - pandas_dtype('datetime64[ns, US/Eastern]'), - pandas_dtype('datetime64[ns, CET]')) + assert not com.is_dtype_equal( + com.pandas_dtype('datetime64[ns, US/Eastern]'), + com.pandas_dtype('datetime64[ns, CET]')) # see gh-15941: no exception should be raised - assert not is_dtype_equal(None, None) + assert not com.is_dtype_equal(None, None) def get_is_dtype_funcs(): @@ -108,7 +106,6 @@ def get_is_dtype_funcs(): begin with 'is_' and end with 'dtype' """ - import pandas.core.dtypes.common as com fnames = [f for f in dir(com) if (f.startswith('is_') and f.endswith('dtype'))] @@ -124,3 +121,404 @@ def test_get_dtype_error_catch(func): # No exception should be raised. assert not func(None) + + +def test_is_object(): + assert com.is_object_dtype(object) + assert com.is_object_dtype(np.array([], dtype=object)) + + assert not com.is_object_dtype(int) + assert not com.is_object_dtype(np.array([], dtype=int)) + assert not com.is_object_dtype([1, 2, 3]) + + +def test_is_sparse(): + assert com.is_sparse(pd.SparseArray([1, 2, 3])) + assert com.is_sparse(pd.SparseSeries([1, 2, 3])) + + assert not com.is_sparse(np.array([1, 2, 3])) + + # This test will only skip if the previous assertions + # pass AND scipy is not installed. + sparse = pytest.importorskip("scipy.sparse") + assert not com.is_sparse(sparse.bsr_matrix([1, 2, 3])) + + +def test_is_scipy_sparse(): + tm._skip_if_no_scipy() + + from scipy.sparse import bsr_matrix + assert com.is_scipy_sparse(bsr_matrix([1, 2, 3])) + + assert not com.is_scipy_sparse(pd.SparseArray([1, 2, 3])) + assert not com.is_scipy_sparse(pd.SparseSeries([1, 2, 3])) + + +def test_is_categorical(): + cat = pd.Categorical([1, 2, 3]) + assert com.is_categorical(cat) + assert com.is_categorical(pd.Series(cat)) + assert com.is_categorical(pd.CategoricalIndex([1, 2, 3])) + + assert not com.is_categorical([1, 2, 3]) + + +def test_is_datetimetz(): + assert not com.is_datetimetz([1, 2, 3]) + assert not com.is_datetimetz(pd.DatetimeIndex([1, 2, 3])) + + assert com.is_datetimetz(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + + dtype = DatetimeTZDtype("ns", tz="US/Eastern") + s = pd.Series([], dtype=dtype) + assert com.is_datetimetz(s) + + +def test_is_period(): + assert not com.is_period([1, 2, 3]) + assert not com.is_period(pd.Index([1, 2, 3])) + assert com.is_period(pd.PeriodIndex(["2017-01-01"], freq="D")) + + +def test_is_datetime64_dtype(): + assert not com.is_datetime64_dtype(object) + assert not com.is_datetime64_dtype([1, 2, 3]) + assert not com.is_datetime64_dtype(np.array([], dtype=int)) + + assert com.is_datetime64_dtype(np.datetime64) + assert com.is_datetime64_dtype(np.array([], dtype=np.datetime64)) + + +def test_is_datetime64tz_dtype(): + assert not com.is_datetime64tz_dtype(object) + assert not com.is_datetime64tz_dtype([1, 2, 3]) + assert not com.is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3])) + assert com.is_datetime64tz_dtype(pd.DatetimeIndex( + [1, 2, 3], tz="US/Eastern")) + + +def test_is_timedelta64_dtype(): + assert not com.is_timedelta64_dtype(object) + assert not com.is_timedelta64_dtype([1, 2, 3]) + + assert com.is_timedelta64_dtype(np.timedelta64) + assert com.is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) + + +def test_is_period_dtype(): + assert not com.is_period_dtype(object) + assert not com.is_period_dtype([1, 2, 3]) + assert not com.is_period_dtype(pd.Period("2017-01-01")) + + assert com.is_period_dtype(PeriodDtype(freq="D")) + assert com.is_period_dtype(pd.PeriodIndex([], freq="A")) + + +def test_is_interval_dtype(): + assert not com.is_interval_dtype(object) + assert not com.is_interval_dtype([1, 2, 3]) + + assert com.is_interval_dtype(IntervalDtype()) + + interval = pd.Interval(1, 2, closed="right") + assert not com.is_interval_dtype(interval) + assert com.is_interval_dtype(pd.IntervalIndex([interval])) + + +def test_is_categorical_dtype(): + assert not com.is_categorical_dtype(object) + assert not com.is_categorical_dtype([1, 2, 3]) + + assert com.is_categorical_dtype(CategoricalDtype()) + assert com.is_categorical_dtype(pd.Categorical([1, 2, 3])) + assert com.is_categorical_dtype(pd.CategoricalIndex([1, 2, 3])) + + +def test_is_string_dtype(): + assert not com.is_string_dtype(int) + assert not com.is_string_dtype(pd.Series([1, 2])) + + assert com.is_string_dtype(str) + assert com.is_string_dtype(object) + assert com.is_string_dtype(np.array(['a', 'b'])) + + +def test_is_period_arraylike(): + assert not com.is_period_arraylike([1, 2, 3]) + assert not com.is_period_arraylike(pd.Index([1, 2, 3])) + assert com.is_period_arraylike(pd.PeriodIndex(["2017-01-01"], freq="D")) + + +def test_is_datetime_arraylike(): + assert not com.is_datetime_arraylike([1, 2, 3]) + assert not com.is_datetime_arraylike(pd.Index([1, 2, 3])) + assert com.is_datetime_arraylike(pd.DatetimeIndex([1, 2, 3])) + + +def test_is_datetimelike(): + assert not com.is_datetimelike([1, 2, 3]) + assert not com.is_datetimelike(pd.Index([1, 2, 3])) + + assert com.is_datetimelike(pd.DatetimeIndex([1, 2, 3])) + assert com.is_datetimelike(pd.PeriodIndex([], freq="A")) + assert com.is_datetimelike(np.array([], dtype=np.datetime64)) + assert com.is_datetimelike(pd.Series([], dtype="timedelta64[ns]")) + assert com.is_datetimelike(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + + dtype = DatetimeTZDtype("ns", tz="US/Eastern") + s = pd.Series([], dtype=dtype) + assert com.is_datetimelike(s) + + +def test_is_integer_dtype(): + assert not com.is_integer_dtype(str) + assert not com.is_integer_dtype(float) + assert not com.is_integer_dtype(np.datetime64) + assert not com.is_integer_dtype(np.timedelta64) + assert not com.is_integer_dtype(pd.Index([1, 2.])) + assert not com.is_integer_dtype(np.array(['a', 'b'])) + assert not com.is_integer_dtype(np.array([], dtype=np.timedelta64)) + + assert com.is_integer_dtype(int) + assert com.is_integer_dtype(np.uint64) + assert com.is_integer_dtype(pd.Series([1, 2])) + + +def test_is_signed_integer_dtype(): + assert not com.is_signed_integer_dtype(str) + assert not com.is_signed_integer_dtype(float) + assert not com.is_signed_integer_dtype(np.uint64) + assert not com.is_signed_integer_dtype(np.datetime64) + assert not com.is_signed_integer_dtype(np.timedelta64) + assert not com.is_signed_integer_dtype(pd.Index([1, 2.])) + assert not com.is_signed_integer_dtype(np.array(['a', 'b'])) + assert not com.is_signed_integer_dtype(np.array([1, 2], dtype=np.uint32)) + assert not com.is_signed_integer_dtype(np.array([], dtype=np.timedelta64)) + + assert com.is_signed_integer_dtype(int) + assert com.is_signed_integer_dtype(pd.Series([1, 2])) + + +def test_is_unsigned_integer_dtype(): + assert not com.is_unsigned_integer_dtype(str) + assert not com.is_unsigned_integer_dtype(int) + assert not com.is_unsigned_integer_dtype(float) + assert not com.is_unsigned_integer_dtype(pd.Series([1, 2])) + assert not com.is_unsigned_integer_dtype(pd.Index([1, 2.])) + assert not com.is_unsigned_integer_dtype(np.array(['a', 'b'])) + + assert com.is_unsigned_integer_dtype(np.uint64) + assert com.is_unsigned_integer_dtype(np.array([1, 2], dtype=np.uint32)) + + +def test_is_int64_dtype(): + assert not com.is_int64_dtype(str) + assert not com.is_int64_dtype(float) + assert not com.is_int64_dtype(np.int32) + assert not com.is_int64_dtype(np.uint64) + assert not com.is_int64_dtype(pd.Index([1, 2.])) + assert not com.is_int64_dtype(np.array(['a', 'b'])) + assert not com.is_int64_dtype(np.array([1, 2], dtype=np.uint32)) + + assert com.is_int64_dtype(np.int64) + assert com.is_int64_dtype(np.array([1, 2], dtype=np.int64)) + + +def test_is_int_or_datetime_dtype(): + assert not com.is_int_or_datetime_dtype(str) + assert not com.is_int_or_datetime_dtype(float) + assert not com.is_int_or_datetime_dtype(pd.Index([1, 2.])) + assert not com.is_int_or_datetime_dtype(np.array(['a', 'b'])) + + assert com.is_int_or_datetime_dtype(int) + assert com.is_int_or_datetime_dtype(np.uint64) + assert com.is_int_or_datetime_dtype(np.datetime64) + assert com.is_int_or_datetime_dtype(np.timedelta64) + assert com.is_int_or_datetime_dtype(pd.Series([1, 2])) + assert com.is_int_or_datetime_dtype(np.array([], dtype=np.datetime64)) + assert com.is_int_or_datetime_dtype(np.array([], dtype=np.timedelta64)) + + +def test_is_datetime64_any_dtype(): + assert not com.is_datetime64_any_dtype(int) + assert not com.is_datetime64_any_dtype(str) + assert not com.is_datetime64_any_dtype(np.array([1, 2])) + assert not com.is_datetime64_any_dtype(np.array(['a', 'b'])) + + assert com.is_datetime64_any_dtype(np.datetime64) + assert com.is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) + assert com.is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) + assert com.is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], + dtype=np.datetime64)) + + +def test_is_datetime64_ns_dtype(): + assert not com.is_datetime64_ns_dtype(int) + assert not com.is_datetime64_ns_dtype(str) + assert not com.is_datetime64_ns_dtype(np.datetime64) + assert not com.is_datetime64_ns_dtype(np.array([1, 2])) + assert not com.is_datetime64_ns_dtype(np.array(['a', 'b'])) + assert not com.is_datetime64_ns_dtype(np.array([], dtype=np.datetime64)) + + # This datetime array has the wrong unit (ps instead of ns) + assert not com.is_datetime64_ns_dtype(np.array([], dtype="datetime64[ps]")) + + assert com.is_datetime64_ns_dtype(DatetimeTZDtype("ns", "US/Eastern")) + assert com.is_datetime64_ns_dtype(pd.DatetimeIndex([1, 2, 3], + dtype=np.datetime64)) + + +def test_is_timedelta64_ns_dtype(): + assert not com.is_timedelta64_ns_dtype(np.dtype('m8[ps]')) + assert not com.is_timedelta64_ns_dtype( + np.array([1, 2], dtype=np.timedelta64)) + + assert com.is_timedelta64_ns_dtype(np.dtype('m8[ns]')) + assert com.is_timedelta64_ns_dtype(np.array([1, 2], dtype='m8[ns]')) + + +def test_is_datetime_or_timedelta_dtype(): + assert not com.is_datetime_or_timedelta_dtype(int) + assert not com.is_datetime_or_timedelta_dtype(str) + assert not com.is_datetime_or_timedelta_dtype(pd.Series([1, 2])) + assert not com.is_datetime_or_timedelta_dtype(np.array(['a', 'b'])) + + assert com.is_datetime_or_timedelta_dtype(np.datetime64) + assert com.is_datetime_or_timedelta_dtype(np.timedelta64) + assert com.is_datetime_or_timedelta_dtype( + np.array([], dtype=np.timedelta64)) + assert com.is_datetime_or_timedelta_dtype( + np.array([], dtype=np.datetime64)) + + +def test_is_numeric_v_string_like(): + assert not com.is_numeric_v_string_like(1, 1) + assert not com.is_numeric_v_string_like(1, "foo") + assert not com.is_numeric_v_string_like("foo", "foo") + assert not com.is_numeric_v_string_like(np.array([1]), np.array([2])) + assert not com.is_numeric_v_string_like( + np.array(["foo"]), np.array(["foo"])) + + assert com.is_numeric_v_string_like(np.array([1]), "foo") + assert com.is_numeric_v_string_like("foo", np.array([1])) + assert com.is_numeric_v_string_like(np.array([1, 2]), np.array(["foo"])) + assert com.is_numeric_v_string_like(np.array(["foo"]), np.array([1, 2])) + + +def test_is_datetimelike_v_numeric(): + dt = np.datetime64(pd.datetime(2017, 1, 1)) + + assert not com.is_datetimelike_v_numeric(1, 1) + assert not com.is_datetimelike_v_numeric(dt, dt) + assert not com.is_datetimelike_v_numeric(np.array([1]), np.array([2])) + assert not com.is_datetimelike_v_numeric(np.array([dt]), np.array([dt])) + + assert com.is_datetimelike_v_numeric(1, dt) + assert com.is_datetimelike_v_numeric(1, dt) + assert com.is_datetimelike_v_numeric(np.array([dt]), 1) + assert com.is_datetimelike_v_numeric(np.array([1]), dt) + assert com.is_datetimelike_v_numeric(np.array([dt]), np.array([1])) + + +def test_is_datetimelike_v_object(): + obj = object() + dt = np.datetime64(pd.datetime(2017, 1, 1)) + + assert not com.is_datetimelike_v_object(dt, dt) + assert not com.is_datetimelike_v_object(obj, obj) + assert not com.is_datetimelike_v_object(np.array([dt]), np.array([1])) + assert not com.is_datetimelike_v_object(np.array([dt]), np.array([dt])) + assert not com.is_datetimelike_v_object(np.array([obj]), np.array([obj])) + + assert com.is_datetimelike_v_object(dt, obj) + assert com.is_datetimelike_v_object(obj, dt) + assert com.is_datetimelike_v_object(np.array([dt]), obj) + assert com.is_datetimelike_v_object(np.array([obj]), dt) + assert com.is_datetimelike_v_object(np.array([dt]), np.array([obj])) + + +def test_needs_i8_conversion(): + assert not com.needs_i8_conversion(str) + assert not com.needs_i8_conversion(np.int64) + assert not com.needs_i8_conversion(pd.Series([1, 2])) + assert not com.needs_i8_conversion(np.array(['a', 'b'])) + + assert com.needs_i8_conversion(np.datetime64) + assert com.needs_i8_conversion(pd.Series([], dtype="timedelta64[ns]")) + assert com.needs_i8_conversion(pd.DatetimeIndex( + [1, 2, 3], tz="US/Eastern")) + + +def test_is_numeric_dtype(): + assert not com.is_numeric_dtype(str) + assert not com.is_numeric_dtype(np.datetime64) + assert not com.is_numeric_dtype(np.timedelta64) + assert not com.is_numeric_dtype(np.array(['a', 'b'])) + assert not com.is_numeric_dtype(np.array([], dtype=np.timedelta64)) + + assert com.is_numeric_dtype(int) + assert com.is_numeric_dtype(float) + assert com.is_numeric_dtype(np.uint64) + assert com.is_numeric_dtype(pd.Series([1, 2])) + assert com.is_numeric_dtype(pd.Index([1, 2.])) + + +def test_is_string_like_dtype(): + assert not com.is_string_like_dtype(object) + assert not com.is_string_like_dtype(pd.Series([1, 2])) + + assert com.is_string_like_dtype(str) + assert com.is_string_like_dtype(np.array(['a', 'b'])) + + +def test_is_float_dtype(): + assert not com.is_float_dtype(str) + assert not com.is_float_dtype(int) + assert not com.is_float_dtype(pd.Series([1, 2])) + assert not com.is_float_dtype(np.array(['a', 'b'])) + + assert com.is_float_dtype(float) + assert com.is_float_dtype(pd.Index([1, 2.])) + + +def test_is_bool_dtype(): + assert not com.is_bool_dtype(int) + assert not com.is_bool_dtype(str) + assert not com.is_bool_dtype(pd.Series([1, 2])) + assert not com.is_bool_dtype(np.array(['a', 'b'])) + + assert com.is_bool_dtype(bool) + assert com.is_bool_dtype(np.bool) + assert com.is_bool_dtype(np.array([True, False])) + + +def test_is_extension_type(): + assert not com.is_extension_type([1, 2, 3]) + assert not com.is_extension_type(np.array([1, 2, 3])) + assert not com.is_extension_type(pd.DatetimeIndex([1, 2, 3])) + + cat = pd.Categorical([1, 2, 3]) + assert com.is_extension_type(cat) + assert com.is_extension_type(pd.Series(cat)) + assert com.is_extension_type(pd.SparseArray([1, 2, 3])) + assert com.is_extension_type(pd.SparseSeries([1, 2, 3])) + assert com.is_extension_type(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern")) + + dtype = DatetimeTZDtype("ns", tz="US/Eastern") + s = pd.Series([], dtype=dtype) + assert com.is_extension_type(s) + + # This test will only skip if the previous assertions + # pass AND scipy is not installed. + sparse = pytest.importorskip("scipy.sparse") + assert not com.is_extension_type(sparse.bsr_matrix([1, 2, 3])) + + +def test_is_complex_dtype(): + assert not com.is_complex_dtype(int) + assert not com.is_complex_dtype(str) + assert not com.is_complex_dtype(pd.Series([1, 2])) + assert not com.is_complex_dtype(np.array(['a', 'b'])) + + assert com.is_complex_dtype(np.complex) + assert com.is_complex_dtype(np.array([1 + 1j, 5])) diff --git a/pandas/tests/dtypes/test_concat.py b/pandas/tests/dtypes/test_concat.py index c0be0dc38d27f..ca579e2dc9390 100644 --- a/pandas/tests/dtypes/test_concat.py +++ b/pandas/tests/dtypes/test_concat.py @@ -2,10 +2,9 @@ import pandas as pd import pandas.core.dtypes.concat as _concat -import pandas.util.testing as tm -class TestConcatCompat(tm.TestCase): +class TestConcatCompat(object): def check_concat(self, to_concat, exp): for klass in [pd.Index, pd.Series]: diff --git a/pandas/tests/dtypes/test_generic.py b/pandas/tests/dtypes/test_generic.py index e9af53aaa1e1a..653d7d3082c08 100644 --- a/pandas/tests/dtypes/test_generic.py +++ b/pandas/tests/dtypes/test_generic.py @@ -3,11 +3,10 @@ from warnings import catch_warnings import numpy as np import pandas as pd -import pandas.util.testing as tm from pandas.core.dtypes import generic as gt -class TestABCClasses(tm.TestCase): +class TestABCClasses(object): tuples = [[1, 2, 2], ['red', 'blue', 'red']] multi_index = pd.MultiIndex.from_arrays(tuples, names=('number', 'color')) datetime_index = pd.to_datetime(['2000/1/1', '2010/1/1']) diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index ec02a5a200308..3790ebe0d3e7c 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -226,7 +226,7 @@ def test_is_recompilable(): assert not inference.is_re_compilable(f) -class TestInference(tm.TestCase): +class TestInference(object): def test_infer_dtype_bytes(self): compare = 'string' if PY2 else 'bytes' @@ -405,7 +405,7 @@ def test_mixed_dtypes_remain_object_array(self): tm.assert_numpy_array_equal(result, array) -class TestTypeInference(tm.TestCase): +class TestTypeInference(object): def test_length_zero(self): result = lib.infer_dtype(np.array([], dtype='i4')) @@ -774,7 +774,7 @@ def test_categorical(self): assert result == 'categorical' -class TestNumberScalar(tm.TestCase): +class TestNumberScalar(object): def test_is_number(self): @@ -917,7 +917,7 @@ def test_is_timedelta(self): assert not is_timedelta64_ns_dtype(tdi.astype('timedelta64[h]')) -class Testisscalar(tm.TestCase): +class Testisscalar(object): def test_isscalar_builtin_scalars(self): assert is_scalar(None) diff --git a/pandas/tests/dtypes/test_io.py b/pandas/tests/dtypes/test_io.py index 443c0c5410e61..ae92e9ecca681 100644 --- a/pandas/tests/dtypes/test_io.py +++ b/pandas/tests/dtypes/test_io.py @@ -7,7 +7,7 @@ from pandas.compat import long, u -class TestParseSQL(tm.TestCase): +class TestParseSQL(object): def test_convert_sql_column_floats(self): arr = np.array([1.5, None, 3, 4.2], dtype=object) @@ -73,7 +73,7 @@ def test_convert_sql_column_decimals(self): tm.assert_numpy_array_equal(result, expected) def test_convert_downcast_int64(self): - from pandas.io.libparsers import na_values + from pandas._libs.parsers import na_values arr = np.array([1, 2, 7, 8, 10], dtype=np.int64) expected = np.array([1, 2, 7, 8, 10], dtype=np.int8) diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py index 78396a8d89d91..90993890b7553 100644 --- a/pandas/tests/dtypes/test_missing.py +++ b/pandas/tests/dtypes/test_missing.py @@ -45,7 +45,7 @@ def test_notnull(): assert (isinstance(isnull(s), Series)) -class TestIsNull(tm.TestCase): +class TestIsNull(object): def test_0d_array(self): assert isnull(np.array(np.nan)) diff --git a/pandas/tests/frame/common.py b/pandas/tests/frame/common.py index b9cd764c8704c..b475d25eb5dac 100644 --- a/pandas/tests/frame/common.py +++ b/pandas/tests/frame/common.py @@ -1,7 +1,7 @@ import numpy as np from pandas import compat -from pandas.util.decorators import cache_readonly +from pandas.util._decorators import cache_readonly import pandas.util.testing as tm import pandas as pd diff --git a/pandas/tests/frame/test_alter_axes.py b/pandas/tests/frame/test_alter_axes.py index 34ab0b72f9b9a..e6313dfc602a8 100644 --- a/pandas/tests/frame/test_alter_axes.py +++ b/pandas/tests/frame/test_alter_axes.py @@ -25,7 +25,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameAlterAxes(tm.TestCase, TestData): +class TestDataFrameAlterAxes(TestData): def test_set_index(self): idx = Index(np.arange(len(self.mixed_frame))) @@ -806,7 +806,7 @@ def test_set_index_preserve_categorical_dtype(self): tm.assert_frame_equal(result, df) -class TestIntervalIndex(tm.TestCase): +class TestIntervalIndex(object): def test_setitem(self): diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 89ee096b4434e..be89b27912d1c 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -24,7 +24,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameAnalytics(tm.TestCase, TestData): +class TestDataFrameAnalytics(TestData): # ---------------------------------------------------------------------= # Correlation and covariance diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index 208c7b5ace50e..f63918c97c614 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -69,7 +69,7 @@ def test_add_prefix_suffix(self): tm.assert_index_equal(with_suffix.columns, expected) -class TestDataFrameMisc(tm.TestCase, SharedWithSparse, TestData): +class TestDataFrameMisc(SharedWithSparse, TestData): klass = DataFrame diff --git a/pandas/tests/frame/test_apply.py b/pandas/tests/frame/test_apply.py index 5febe8c62abe8..aa7c7a7120c1b 100644 --- a/pandas/tests/frame/test_apply.py +++ b/pandas/tests/frame/test_apply.py @@ -19,7 +19,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameApply(tm.TestCase, TestData): +class TestDataFrameApply(TestData): def test_apply(self): with np.errstate(all='ignore'): @@ -482,7 +482,7 @@ def zip_frames(*frames): return pd.concat(zipped, axis=1) -class TestDataFrameAggregate(tm.TestCase, TestData): +class TestDataFrameAggregate(TestData): _multiprocess_can_split_ = True diff --git a/pandas/tests/frame/test_asof.py b/pandas/tests/frame/test_asof.py index ba3e239756f51..d4e3d541937dc 100644 --- a/pandas/tests/frame/test_asof.py +++ b/pandas/tests/frame/test_asof.py @@ -9,8 +9,8 @@ from .common import TestData -class TestFrameAsof(TestData, tm.TestCase): - def setUp(self): +class TestFrameAsof(TestData): + def setup_method(self, method): self.N = N = 50 self.rng = date_range('1/1/1990', periods=N, freq='53s') self.df = DataFrame({'A': np.arange(N), 'B': np.arange(N)}, diff --git a/pandas/tests/frame/test_axis_select_reindex.py b/pandas/tests/frame/test_axis_select_reindex.py index a563b678a3786..a6326083c1bee 100644 --- a/pandas/tests/frame/test_axis_select_reindex.py +++ b/pandas/tests/frame/test_axis_select_reindex.py @@ -22,7 +22,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameSelectReindex(tm.TestCase, TestData): +class TestDataFrameSelectReindex(TestData): # These are specific reindex-based tests; other indexing tests should go in # test_indexing diff --git a/pandas/tests/frame/test_block_internals.py b/pandas/tests/frame/test_block_internals.py index 44dc6df756f3d..c1a5b437be5d0 100644 --- a/pandas/tests/frame/test_block_internals.py +++ b/pandas/tests/frame/test_block_internals.py @@ -28,7 +28,7 @@ # structure -class TestDataFrameBlockInternals(tm.TestCase, TestData): +class TestDataFrameBlockInternals(TestData): def test_cast_internals(self): casted = DataFrame(self.frame._data, dtype=int) diff --git a/pandas/tests/frame/test_combine_concat.py b/pandas/tests/frame/test_combine_concat.py index 44f17faabe20d..688cacdee263e 100644 --- a/pandas/tests/frame/test_combine_concat.py +++ b/pandas/tests/frame/test_combine_concat.py @@ -18,7 +18,7 @@ from pandas.util.testing import assert_frame_equal, assert_series_equal -class TestDataFrameConcatCommon(tm.TestCase, TestData): +class TestDataFrameConcatCommon(TestData): def test_concat_multiple_frames_dtypes(self): @@ -441,7 +441,7 @@ def test_concat_numerical_names(self): tm.assert_frame_equal(result, expected) -class TestDataFrameCombineFirst(tm.TestCase, TestData): +class TestDataFrameCombineFirst(TestData): def test_combine_first_mixed(self): a = Series(['a', 'b'], index=lrange(2)) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 5b00ddc51da46..8459900ea1059 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -32,7 +32,7 @@ 'int32', 'int64'] -class TestDataFrameConstructors(tm.TestCase, TestData): +class TestDataFrameConstructors(TestData): def test_constructor(self): df = DataFrame() @@ -1903,7 +1903,7 @@ def test_to_frame_with_falsey_names(self): tm.assert_series_equal(result, expected) -class TestDataFrameConstructorWithDatetimeTZ(tm.TestCase, TestData): +class TestDataFrameConstructorWithDatetimeTZ(TestData): def test_from_dict(self): diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index 353b4b873332e..8f4fa1d383100 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import pytest +import collections import numpy as np from pandas import compat @@ -11,51 +12,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameConvertTo(tm.TestCase, TestData): - - def test_to_dict(self): - test_data = { - 'A': {'1': 1, '2': 2}, - 'B': {'1': '1', '2': '2', '3': '3'}, - } - recons_data = DataFrame(test_data).to_dict() - - for k, v in compat.iteritems(test_data): - for k2, v2 in compat.iteritems(v): - assert v2 == recons_data[k][k2] - - recons_data = DataFrame(test_data).to_dict("l") - - for k, v in compat.iteritems(test_data): - for k2, v2 in compat.iteritems(v): - assert v2 == recons_data[k][int(k2) - 1] - - recons_data = DataFrame(test_data).to_dict("s") - - for k, v in compat.iteritems(test_data): - for k2, v2 in compat.iteritems(v): - assert v2 == recons_data[k][k2] - - recons_data = DataFrame(test_data).to_dict("sp") - expected_split = {'columns': ['A', 'B'], 'index': ['1', '2', '3'], - 'data': [[1.0, '1'], [2.0, '2'], [np.nan, '3']]} - tm.assert_dict_equal(recons_data, expected_split) - - recons_data = DataFrame(test_data).to_dict("r") - expected_records = [{'A': 1.0, 'B': '1'}, - {'A': 2.0, 'B': '2'}, - {'A': np.nan, 'B': '3'}] - assert isinstance(recons_data, list) - assert len(recons_data) == 3 - for l, r in zip(recons_data, expected_records): - tm.assert_dict_equal(l, r) - - # GH10844 - recons_data = DataFrame(test_data).to_dict("i") - - for k, v in compat.iteritems(test_data): - for k2, v2 in compat.iteritems(v): - assert v2 == recons_data[k2][k] +class TestDataFrameConvertTo(TestData): def test_to_dict_timestamp(self): @@ -190,17 +147,65 @@ def test_to_records_with_unicode_column_names(self): ) tm.assert_almost_equal(result, expected) + @pytest.mark.parametrize('mapping', [ + dict, + collections.defaultdict(list), + collections.OrderedDict]) + def test_to_dict(self, mapping): + test_data = { + 'A': {'1': 1, '2': 2}, + 'B': {'1': '1', '2': '2', '3': '3'}, + } + # GH16122 + recons_data = DataFrame(test_data).to_dict(into=mapping) + + for k, v in compat.iteritems(test_data): + for k2, v2 in compat.iteritems(v): + assert (v2 == recons_data[k][k2]) + + recons_data = DataFrame(test_data).to_dict("l", mapping) + + for k, v in compat.iteritems(test_data): + for k2, v2 in compat.iteritems(v): + assert (v2 == recons_data[k][int(k2) - 1]) + + recons_data = DataFrame(test_data).to_dict("s", mapping) + + for k, v in compat.iteritems(test_data): + for k2, v2 in compat.iteritems(v): + assert (v2 == recons_data[k][k2]) + + recons_data = DataFrame(test_data).to_dict("sp", mapping) + expected_split = {'columns': ['A', 'B'], 'index': ['1', '2', '3'], + 'data': [[1.0, '1'], [2.0, '2'], [np.nan, '3']]} + tm.assert_dict_equal(recons_data, expected_split) + + recons_data = DataFrame(test_data).to_dict("r", mapping) + expected_records = [{'A': 1.0, 'B': '1'}, + {'A': 2.0, 'B': '2'}, + {'A': np.nan, 'B': '3'}] + assert isinstance(recons_data, list) + assert (len(recons_data) == 3) + for l, r in zip(recons_data, expected_records): + tm.assert_dict_equal(l, r) + + # GH10844 + recons_data = DataFrame(test_data).to_dict("i") + + for k, v in compat.iteritems(test_data): + for k2, v2 in compat.iteritems(v): + assert (v2 == recons_data[k2][k]) -@pytest.mark.parametrize('tz', ['UTC', 'GMT', 'US/Eastern']) -def test_to_records_datetimeindex_with_tz(tz): - # GH13937 - dr = date_range('2016-01-01', periods=10, - freq='S', tz=tz) + @pytest.mark.parametrize('tz', ['UTC', 'GMT', 'US/Eastern']) + def test_to_records_datetimeindex_with_tz(self, tz): + # GH13937 + dr = date_range('2016-01-01', periods=10, + freq='S', tz=tz) - df = DataFrame({'datetime': dr}, index=dr) + df = DataFrame({'datetime': dr}, index=dr) - expected = df.to_records() - result = df.tz_convert("UTC").to_records() + expected = df.to_records() + result = df.tz_convert("UTC").to_records() - # both converted to UTC, so they are equal - tm.assert_numpy_array_equal(result, expected) + # both converted to UTC, so they are equal + tm.assert_numpy_array_equal(result, expected) diff --git a/pandas/tests/frame/test_dtypes.py b/pandas/tests/frame/test_dtypes.py index 2d39db16dbd8d..b99a6fabfa42b 100644 --- a/pandas/tests/frame/test_dtypes.py +++ b/pandas/tests/frame/test_dtypes.py @@ -19,7 +19,7 @@ import pandas as pd -class TestDataFrameDataTypes(tm.TestCase, TestData): +class TestDataFrameDataTypes(TestData): def test_concat_empty_dataframe_dtypes(self): df = DataFrame(columns=list("abc")) @@ -542,7 +542,7 @@ def test_arg_for_errors_in_astype(self): df.astype(np.int8, errors='ignore') -class TestDataFrameDatetimeWithTZ(tm.TestCase, TestData): +class TestDataFrameDatetimeWithTZ(TestData): def test_interleave(self): diff --git a/pandas/tests/frame/test_indexing.py b/pandas/tests/frame/test_indexing.py index 75d4263cbe68f..f0503b60eeefa 100644 --- a/pandas/tests/frame/test_indexing.py +++ b/pandas/tests/frame/test_indexing.py @@ -36,7 +36,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameIndexing(tm.TestCase, TestData): +class TestDataFrameIndexing(TestData): def test_getitem(self): # Slicing @@ -2912,9 +2912,9 @@ def test_type_error_multiindex(self): assert_series_equal(result, expected) -class TestDataFrameIndexingDatetimeWithTZ(tm.TestCase, TestData): +class TestDataFrameIndexingDatetimeWithTZ(TestData): - def setUp(self): + def setup_method(self, method): self.idx = Index(date_range('20130101', periods=3, tz='US/Eastern'), name='foo') self.dr = date_range('20130110', periods=3) @@ -2970,9 +2970,9 @@ def test_transpose(self): assert_frame_equal(result, expected) -class TestDataFrameIndexingUInt64(tm.TestCase, TestData): +class TestDataFrameIndexingUInt64(TestData): - def setUp(self): + def setup_method(self, method): self.ir = Index(np.arange(3), dtype=np.uint64) self.idx = Index([2**63, 2**63 + 5, 2**63 + 10], name='foo') diff --git a/pandas/tests/frame/test_missing.py b/pandas/tests/frame/test_missing.py index ffba141ddc15d..77f0357685cab 100644 --- a/pandas/tests/frame/test_missing.py +++ b/pandas/tests/frame/test_missing.py @@ -34,7 +34,7 @@ def _skip_if_no_pchip(): pytest.skip('scipy.interpolate.pchip missing') -class TestDataFrameMissingData(tm.TestCase, TestData): +class TestDataFrameMissingData(TestData): def test_dropEmptyRows(self): N = len(self.frame.index) @@ -519,7 +519,7 @@ def test_fill_value_when_combine_const(self): assert_frame_equal(res, exp) -class TestDataFrameInterpolate(tm.TestCase, TestData): +class TestDataFrameInterpolate(TestData): def test_interp_basic(self): df = DataFrame({'A': [1, 2, np.nan, 4], diff --git a/pandas/tests/frame/test_mutate_columns.py b/pandas/tests/frame/test_mutate_columns.py index ac76970aaa901..4462260a290d9 100644 --- a/pandas/tests/frame/test_mutate_columns.py +++ b/pandas/tests/frame/test_mutate_columns.py @@ -17,7 +17,7 @@ # Column add, remove, delete. -class TestDataFrameMutateColumns(tm.TestCase, TestData): +class TestDataFrameMutateColumns(TestData): def test_assign(self): df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}) diff --git a/pandas/tests/frame/test_nonunique_indexes.py b/pandas/tests/frame/test_nonunique_indexes.py index 4bc0176b570e3..4f77ba0ae1f5a 100644 --- a/pandas/tests/frame/test_nonunique_indexes.py +++ b/pandas/tests/frame/test_nonunique_indexes.py @@ -16,7 +16,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameNonuniqueIndexes(tm.TestCase, TestData): +class TestDataFrameNonuniqueIndexes(TestData): def test_column_dups_operations(self): diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 9083b7952909e..8ec6c6e6263d8 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -28,7 +28,7 @@ _check_mixed_int) -class TestDataFrameOperators(tm.TestCase, TestData): +class TestDataFrameOperators(TestData): def test_operators(self): garbage = random.random(4) diff --git a/pandas/tests/frame/test_period.py b/pandas/tests/frame/test_period.py index 826ece2ed2c9b..482210966fe6b 100644 --- a/pandas/tests/frame/test_period.py +++ b/pandas/tests/frame/test_period.py @@ -12,9 +12,9 @@ def _permute(obj): return obj.take(np.random.permutation(len(obj))) -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_as_frame_columns(self): diff --git a/pandas/tests/frame/test_quantile.py b/pandas/tests/frame/test_quantile.py index 33f72cde1b9a3..2482e493dbefd 100644 --- a/pandas/tests/frame/test_quantile.py +++ b/pandas/tests/frame/test_quantile.py @@ -17,7 +17,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameQuantile(tm.TestCase, TestData): +class TestDataFrameQuantile(TestData): def test_quantile(self): from numpy import percentile diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index 80db2c50c3eb6..f0f1a2df27e93 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -4,7 +4,6 @@ import operator import pytest -from itertools import product from pandas.compat import (zip, range, lrange, StringIO) from pandas import DataFrame, Series, Index, MultiIndex, date_range @@ -27,6 +26,16 @@ ENGINES = 'python', 'numexpr' +@pytest.fixture(params=PARSERS, ids=lambda x: x) +def parser(request): + return request.param + + +@pytest.fixture(params=ENGINES, ids=lambda x: x) +def engine(request): + return request.param + + def skip_if_no_pandas_parser(parser): if parser != 'pandas': pytest.skip("cannot evaluate with parser {0!r}".format(parser)) @@ -39,9 +48,9 @@ def skip_if_no_ne(engine='numexpr'): "installed") -class TestCompat(tm.TestCase): +class TestCompat(object): - def setUp(self): + def setup_method(self, method): self.df = DataFrame({'A': [1, 2, 3]}) self.expected1 = self.df[self.df.A > 0] self.expected2 = self.df.A + 1 @@ -87,7 +96,7 @@ def test_query_numexpr(self): lambda: df.eval('A+1', engine='numexpr')) -class TestDataFrameEval(tm.TestCase, TestData): +class TestDataFrameEval(TestData): def test_ops(self): @@ -163,10 +172,11 @@ def test_eval_resolvers_as_list(self): dict1['a'] + dict2['b']) -class TestDataFrameQueryWithMultiIndex(tm.TestCase): +class TestDataFrameQueryWithMultiIndex(object): - def check_query_with_named_multiindex(self, parser, engine): + def test_query_with_named_multiindex(self, parser, engine): tm.skip_if_no_ne(engine) + skip_if_no_pandas_parser(parser) a = np.random.choice(['red', 'green'], size=10) b = np.random.choice(['eggs', 'ham'], size=10) index = MultiIndex.from_arrays([a, b], names=['color', 'food']) @@ -214,12 +224,9 @@ def check_query_with_named_multiindex(self, parser, engine): assert_frame_equal(res1, exp) assert_frame_equal(res2, exp) - def test_query_with_named_multiindex(self): - for parser, engine in product(['pandas'], ENGINES): - yield self.check_query_with_named_multiindex, parser, engine - - def check_query_with_unnamed_multiindex(self, parser, engine): + def test_query_with_unnamed_multiindex(self, parser, engine): tm.skip_if_no_ne(engine) + skip_if_no_pandas_parser(parser) a = np.random.choice(['red', 'green'], size=10) b = np.random.choice(['eggs', 'ham'], size=10) index = MultiIndex.from_arrays([a, b]) @@ -308,12 +315,9 @@ def check_query_with_unnamed_multiindex(self, parser, engine): assert_frame_equal(res1, exp) assert_frame_equal(res2, exp) - def test_query_with_unnamed_multiindex(self): - for parser, engine in product(['pandas'], ENGINES): - yield self.check_query_with_unnamed_multiindex, parser, engine - - def check_query_with_partially_named_multiindex(self, parser, engine): + def test_query_with_partially_named_multiindex(self, parser, engine): tm.skip_if_no_ne(engine) + skip_if_no_pandas_parser(parser) a = np.random.choice(['red', 'green'], size=10) b = np.arange(10) index = MultiIndex.from_arrays([a, b]) @@ -341,17 +345,7 @@ def check_query_with_partially_named_multiindex(self, parser, engine): exp = df[ind != "red"] assert_frame_equal(res, exp) - def test_query_with_partially_named_multiindex(self): - for parser, engine in product(['pandas'], ENGINES): - yield (self.check_query_with_partially_named_multiindex, - parser, engine) - def test_query_multiindex_get_index_resolvers(self): - for parser, engine in product(['pandas'], ENGINES): - yield (self.check_query_multiindex_get_index_resolvers, parser, - engine) - - def check_query_multiindex_get_index_resolvers(self, parser, engine): df = mkdf(10, 3, r_idx_nlevels=2, r_idx_names=['spam', 'eggs']) resolvers = df._get_index_resolvers() @@ -375,22 +369,14 @@ def to_series(mi, level): else: raise AssertionError("object must be a Series or Index") - def test_raise_on_panel_with_multiindex(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_raise_on_panel_with_multiindex, parser, engine - - def check_raise_on_panel_with_multiindex(self, parser, engine): + def test_raise_on_panel_with_multiindex(self, parser, engine): tm.skip_if_no_ne() p = tm.makePanel(7) p.items = tm.makeCustomIndex(len(p.items), nlevels=2) with pytest.raises(NotImplementedError): pd.eval('p + 1', parser=parser, engine=engine) - def test_raise_on_panel4d_with_multiindex(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_raise_on_panel4d_with_multiindex, parser, engine - - def check_raise_on_panel4d_with_multiindex(self, parser, engine): + def test_raise_on_panel4d_with_multiindex(self, parser, engine): tm.skip_if_no_ne() p4d = tm.makePanel4D(7) p4d.items = tm.makeCustomIndex(len(p4d.items), nlevels=2) @@ -398,18 +384,16 @@ def check_raise_on_panel4d_with_multiindex(self, parser, engine): pd.eval('p4d + 1', parser=parser, engine=engine) -class TestDataFrameQueryNumExprPandas(tm.TestCase): +class TestDataFrameQueryNumExprPandas(object): @classmethod - def setUpClass(cls): - super(TestDataFrameQueryNumExprPandas, cls).setUpClass() + def setup_class(cls): cls.engine = 'numexpr' cls.parser = 'pandas' tm.skip_if_no_ne(cls.engine) @classmethod - def tearDownClass(cls): - super(TestDataFrameQueryNumExprPandas, cls).tearDownClass() + def teardown_class(cls): del cls.engine, cls.parser def test_date_query_with_attribute_access(self): @@ -733,8 +717,8 @@ def test_inf(self): class TestDataFrameQueryNumExprPython(TestDataFrameQueryNumExprPandas): @classmethod - def setUpClass(cls): - super(TestDataFrameQueryNumExprPython, cls).setUpClass() + def setup_class(cls): + super(TestDataFrameQueryNumExprPython, cls).setup_class() cls.engine = 'numexpr' cls.parser = 'python' tm.skip_if_no_ne(cls.engine) @@ -834,8 +818,8 @@ def test_nested_scope(self): class TestDataFrameQueryPythonPandas(TestDataFrameQueryNumExprPandas): @classmethod - def setUpClass(cls): - super(TestDataFrameQueryPythonPandas, cls).setUpClass() + def setup_class(cls): + super(TestDataFrameQueryPythonPandas, cls).setup_class() cls.engine = 'python' cls.parser = 'pandas' cls.frame = TestData().frame @@ -855,8 +839,8 @@ def test_query_builtin(self): class TestDataFrameQueryPythonPython(TestDataFrameQueryNumExprPython): @classmethod - def setUpClass(cls): - super(TestDataFrameQueryPythonPython, cls).setUpClass() + def setup_class(cls): + super(TestDataFrameQueryPythonPython, cls).setup_class() cls.engine = cls.parser = 'python' cls.frame = TestData().frame @@ -872,9 +856,9 @@ def test_query_builtin(self): assert_frame_equal(expected, result) -class TestDataFrameQueryStrings(tm.TestCase): +class TestDataFrameQueryStrings(object): - def check_str_query_method(self, parser, engine): + def test_str_query_method(self, parser, engine): tm.skip_if_no_ne(engine) df = DataFrame(randn(10, 1), columns=['b']) df['strings'] = Series(list('aabbccddee')) @@ -911,15 +895,7 @@ def check_str_query_method(self, parser, engine): assert_frame_equal(res, expect) assert_frame_equal(res, df[~df.strings.isin(['a'])]) - def test_str_query_method(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_str_query_method, parser, engine - - def test_str_list_query_method(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_str_list_query_method, parser, engine - - def check_str_list_query_method(self, parser, engine): + def test_str_list_query_method(self, parser, engine): tm.skip_if_no_ne(engine) df = DataFrame(randn(10, 1), columns=['b']) df['strings'] = Series(list('aabbccddee')) @@ -958,7 +934,7 @@ def check_str_list_query_method(self, parser, engine): parser=parser) assert_frame_equal(res, expect) - def check_query_with_string_columns(self, parser, engine): + def test_query_with_string_columns(self, parser, engine): tm.skip_if_no_ne(engine) df = DataFrame({'a': list('aaaabbbbcccc'), 'b': list('aabbccddeeff'), @@ -979,11 +955,7 @@ def check_query_with_string_columns(self, parser, engine): with pytest.raises(NotImplementedError): df.query('a in b and c < d', parser=parser, engine=engine) - def test_query_with_string_columns(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_query_with_string_columns, parser, engine - - def check_object_array_eq_ne(self, parser, engine): + def test_object_array_eq_ne(self, parser, engine): tm.skip_if_no_ne(engine) df = DataFrame({'a': list('aaaabbbbcccc'), 'b': list('aabbccddeeff'), @@ -997,11 +969,7 @@ def check_object_array_eq_ne(self, parser, engine): exp = df[df.a != df.b] assert_frame_equal(res, exp) - def test_object_array_eq_ne(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_object_array_eq_ne, parser, engine - - def check_query_with_nested_strings(self, parser, engine): + def test_query_with_nested_strings(self, parser, engine): tm.skip_if_no_ne(engine) skip_if_no_pandas_parser(parser) raw = """id event timestamp @@ -1025,11 +993,7 @@ def check_query_with_nested_strings(self, parser, engine): engine=engine) assert_frame_equal(expected, res) - def test_query_with_nested_string(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_query_with_nested_strings, parser, engine - - def check_query_with_nested_special_character(self, parser, engine): + def test_query_with_nested_special_character(self, parser, engine): skip_if_no_pandas_parser(parser) tm.skip_if_no_ne(engine) df = DataFrame({'a': ['a', 'b', 'test & test'], @@ -1038,12 +1002,7 @@ def check_query_with_nested_special_character(self, parser, engine): expec = df[df.a == 'test & test'] assert_frame_equal(res, expec) - def test_query_with_nested_special_character(self): - for parser, engine in product(PARSERS, ENGINES): - yield (self.check_query_with_nested_special_character, - parser, engine) - - def check_query_lex_compare_strings(self, parser, engine): + def test_query_lex_compare_strings(self, parser, engine): tm.skip_if_no_ne(engine=engine) import operator as opr @@ -1058,11 +1017,7 @@ def check_query_lex_compare_strings(self, parser, engine): expected = df[func(df.X, 'd')] assert_frame_equal(res, expected) - def test_query_lex_compare_strings(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_query_lex_compare_strings, parser, engine - - def check_query_single_element_booleans(self, parser, engine): + def test_query_single_element_booleans(self, parser, engine): tm.skip_if_no_ne(engine) columns = 'bid', 'bidsize', 'ask', 'asksize' data = np.random.randint(2, size=(1, len(columns))).astype(bool) @@ -1071,12 +1026,9 @@ def check_query_single_element_booleans(self, parser, engine): expected = df[df.bid & df.ask] assert_frame_equal(res, expected) - def test_query_single_element_booleans(self): - for parser, engine in product(PARSERS, ENGINES): - yield self.check_query_single_element_booleans, parser, engine - - def check_query_string_scalar_variable(self, parser, engine): + def test_query_string_scalar_variable(self, parser, engine): tm.skip_if_no_ne(engine) + skip_if_no_pandas_parser(parser) df = pd.DataFrame({'Symbol': ['BUD US', 'BUD US', 'IBM US', 'IBM US'], 'Price': [109.70, 109.72, 183.30, 183.35]}) e = df[df.Symbol == 'BUD US'] @@ -1084,24 +1036,19 @@ def check_query_string_scalar_variable(self, parser, engine): r = df.query('Symbol == @symb', parser=parser, engine=engine) assert_frame_equal(e, r) - def test_query_string_scalar_variable(self): - for parser, engine in product(['pandas'], ENGINES): - yield self.check_query_string_scalar_variable, parser, engine - -class TestDataFrameEvalNumExprPandas(tm.TestCase): +class TestDataFrameEvalNumExprPandas(object): @classmethod - def setUpClass(cls): - super(TestDataFrameEvalNumExprPandas, cls).setUpClass() + def setup_class(cls): cls.engine = 'numexpr' cls.parser = 'pandas' tm.skip_if_no_ne() - def setUp(self): + def setup_method(self, method): self.frame = DataFrame(randn(10, 3), columns=list('abc')) - def tearDown(self): + def teardown_method(self, method): del self.frame def test_simple_expr(self): @@ -1129,8 +1076,8 @@ def test_invalid_type_for_operator_raises(self): class TestDataFrameEvalNumExprPython(TestDataFrameEvalNumExprPandas): @classmethod - def setUpClass(cls): - super(TestDataFrameEvalNumExprPython, cls).setUpClass() + def setup_class(cls): + super(TestDataFrameEvalNumExprPython, cls).setup_class() cls.engine = 'numexpr' cls.parser = 'python' tm.skip_if_no_ne(cls.engine) @@ -1139,8 +1086,8 @@ def setUpClass(cls): class TestDataFrameEvalPythonPandas(TestDataFrameEvalNumExprPandas): @classmethod - def setUpClass(cls): - super(TestDataFrameEvalPythonPandas, cls).setUpClass() + def setup_class(cls): + super(TestDataFrameEvalPythonPandas, cls).setup_class() cls.engine = 'python' cls.parser = 'pandas' @@ -1148,6 +1095,5 @@ def setUpClass(cls): class TestDataFrameEvalPythonPython(TestDataFrameEvalNumExprPython): @classmethod - def setUpClass(cls): - super(TestDataFrameEvalPythonPython, cls).tearDownClass() + def setup_class(cls): cls.engine = cls.parser = 'python' diff --git a/pandas/tests/frame/test_rank.py b/pandas/tests/frame/test_rank.py index b115218d76958..acf887d047c9e 100644 --- a/pandas/tests/frame/test_rank.py +++ b/pandas/tests/frame/test_rank.py @@ -12,7 +12,7 @@ from pandas.tests.frame.common import TestData -class TestRank(tm.TestCase, TestData): +class TestRank(TestData): s = Series([1, 3, 4, 2, nan, 2, 1, 5, nan, 3]) df = DataFrame({'A': s, 'B': s}) diff --git a/pandas/tests/frame/test_replace.py b/pandas/tests/frame/test_replace.py index 3f160012cb446..fbc4accd0e41e 100644 --- a/pandas/tests/frame/test_replace.py +++ b/pandas/tests/frame/test_replace.py @@ -23,7 +23,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameReplace(tm.TestCase, TestData): +class TestDataFrameReplace(TestData): def test_replace_inplace(self): self.tsframe['A'][:5] = nan diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr_info.py index 0300c53e086cd..cc37f8cc3cb02 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr_info.py @@ -23,7 +23,7 @@ # structure -class TestDataFrameReprInfoEtc(tm.TestCase, TestData): +class TestDataFrameReprInfoEtc(TestData): def test_repr_empty(self): # empty diff --git a/pandas/tests/frame/test_reshape.py b/pandas/tests/frame/test_reshape.py index 79ee76ee362c3..fdb0119d8ae60 100644 --- a/pandas/tests/frame/test_reshape.py +++ b/pandas/tests/frame/test_reshape.py @@ -24,7 +24,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameReshape(tm.TestCase, TestData): +class TestDataFrameReshape(TestData): def test_pivot(self): data = { diff --git a/pandas/tests/frame/test_sorting.py b/pandas/tests/frame/test_sorting.py index 457ea32ec56f7..98f7f82c0ace7 100644 --- a/pandas/tests/frame/test_sorting.py +++ b/pandas/tests/frame/test_sorting.py @@ -18,7 +18,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameSorting(tm.TestCase, TestData): +class TestDataFrameSorting(TestData): def test_sort(self): frame = DataFrame(np.arange(16).reshape(4, 4), index=[1, 2, 3, 4], @@ -315,7 +315,7 @@ def test_sort_nat_values_in_int_column(self): assert_frame_equal(df_sorted, df_reversed) -class TestDataFrameSortIndexKinds(tm.TestCase, TestData): +class TestDataFrameSortIndexKinds(TestData): def test_sort_index_multicolumn(self): A = np.arange(5).repeat(20) diff --git a/pandas/tests/frame/test_subclass.py b/pandas/tests/frame/test_subclass.py index 40a8ece852623..52c591e4dcbb0 100644 --- a/pandas/tests/frame/test_subclass.py +++ b/pandas/tests/frame/test_subclass.py @@ -12,7 +12,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameSubclassing(tm.TestCase, TestData): +class TestDataFrameSubclassing(TestData): def test_frame_subclassing_and_slicing(self): # Subclass frame and ensure it returns the right class on slicing it diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py index f52f4697b1b08..143a7ea8f6fb2 100644 --- a/pandas/tests/frame/test_timeseries.py +++ b/pandas/tests/frame/test_timeseries.py @@ -24,7 +24,7 @@ from pandas.tests.frame.common import TestData -class TestDataFrameTimeSeriesMethods(tm.TestCase, TestData): +class TestDataFrameTimeSeriesMethods(TestData): def test_diff(self): the_diff = self.tsframe.diff(1) diff --git a/pandas/tests/frame/test_to_csv.py b/pandas/tests/frame/test_to_csv.py index 3e38f2a71d99d..69bd2b008416f 100644 --- a/pandas/tests/frame/test_to_csv.py +++ b/pandas/tests/frame/test_to_csv.py @@ -29,7 +29,7 @@ 'int32', 'int64'] -class TestDataFrameToCSV(tm.TestCase, TestData): +class TestDataFrameToCSV(TestData): def test_to_csv_from_csv1(self): diff --git a/pandas/tests/frame/test_validate.py b/pandas/tests/frame/test_validate.py index 4c4abb7e58e75..d6065e6042908 100644 --- a/pandas/tests/frame/test_validate.py +++ b/pandas/tests/frame/test_validate.py @@ -1,10 +1,9 @@ -from unittest import TestCase from pandas.core.frame import DataFrame import pytest -class TestDataFrameValidate(TestCase): +class TestDataFrameValidate(object): """Tests for error handling related to data types of method arguments.""" df = DataFrame({'a': [1, 2], 'b': [3, 4]}) diff --git a/pandas/tests/groupby/common.py b/pandas/tests/groupby/common.py index f3dccf473f53a..3e99e8211b4f8 100644 --- a/pandas/tests/groupby/common.py +++ b/pandas/tests/groupby/common.py @@ -28,7 +28,7 @@ def df(): class MixIn(object): - def setUp(self): + def setup_method(self, method): self.ts = tm.makeTimeSeries() self.seriesd = tm.getSeriesData() diff --git a/pandas/tests/groupby/test_aggregate.py b/pandas/tests/groupby/test_aggregate.py index 310a5aca77b77..d7b46e6748b99 100644 --- a/pandas/tests/groupby/test_aggregate.py +++ b/pandas/tests/groupby/test_aggregate.py @@ -25,9 +25,9 @@ import pandas.util.testing as tm -class TestGroupByAggregate(tm.TestCase): +class TestGroupByAggregate(object): - def setUp(self): + def setup_method(self, method): self.ts = tm.makeTimeSeries() self.seriesd = tm.getSeriesData() diff --git a/pandas/tests/groupby/test_bin_groupby.py b/pandas/tests/groupby/test_bin_groupby.py index 320acacff483c..f527c732fb76b 100644 --- a/pandas/tests/groupby/test_bin_groupby.py +++ b/pandas/tests/groupby/test_bin_groupby.py @@ -46,9 +46,9 @@ def test_series_bin_grouper(): assert_almost_equal(counts, exp_counts) -class TestBinGroupers(tm.TestCase): +class TestBinGroupers(object): - def setUp(self): + def setup_method(self, method): self.obj = np.random.randn(10, 1) self.labels = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2], dtype=np.int64) self.bins = np.array([3, 6], dtype=np.int64) @@ -117,11 +117,11 @@ def _ohlc(group): _check('float64') -class TestMoments(tm.TestCase): +class TestMoments(object): pass -class TestReducer(tm.TestCase): +class TestReducer(object): def test_int_index(self): from pandas.core.series import Series diff --git a/pandas/tests/groupby/test_categorical.py b/pandas/tests/groupby/test_categorical.py index 9d2134927389d..fdc03acd3e931 100644 --- a/pandas/tests/groupby/test_categorical.py +++ b/pandas/tests/groupby/test_categorical.py @@ -15,7 +15,7 @@ from .common import MixIn -class TestGroupByCategorical(MixIn, tm.TestCase): +class TestGroupByCategorical(MixIn): def test_level_groupby_get_group(self): # GH15155 diff --git a/pandas/tests/groupby/test_filters.py b/pandas/tests/groupby/test_filters.py index 2cfbe0ab68c8e..cac6b46af8f87 100644 --- a/pandas/tests/groupby/test_filters.py +++ b/pandas/tests/groupby/test_filters.py @@ -23,9 +23,9 @@ import pandas as pd -class TestGroupByFilter(tm.TestCase): +class TestGroupByFilter(object): - def setUp(self): + def setup_method(self, method): self.ts = tm.makeTimeSeries() self.seriesd = tm.getSeriesData() diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 8d86d40c379bf..88afa51e46b6c 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -28,7 +28,7 @@ from .common import MixIn -class TestGroupBy(MixIn, tm.TestCase): +class TestGroupBy(MixIn): def test_basic(self): def checkit(dtype): diff --git a/pandas/tests/groupby/test_nth.py b/pandas/tests/groupby/test_nth.py index 0b6aeaf155f86..7912b4bf3bdf6 100644 --- a/pandas/tests/groupby/test_nth.py +++ b/pandas/tests/groupby/test_nth.py @@ -2,13 +2,12 @@ import pandas as pd from pandas import DataFrame, MultiIndex, Index, Series, isnull from pandas.compat import lrange -from pandas.util import testing as tm from pandas.util.testing import assert_frame_equal, assert_series_equal from .common import MixIn -class TestNth(MixIn, tm.TestCase): +class TestNth(MixIn): def test_first_last_nth(self): # tests for first / last / nth diff --git a/pandas/tests/groupby/test_timegrouper.py b/pandas/tests/groupby/test_timegrouper.py index 42caecbdb700e..2196318d1920e 100644 --- a/pandas/tests/groupby/test_timegrouper.py +++ b/pandas/tests/groupby/test_timegrouper.py @@ -14,7 +14,7 @@ from pandas.util.testing import assert_frame_equal, assert_series_equal -class TestGroupBy(tm.TestCase): +class TestGroupBy(object): def test_groupby_with_timegrouper(self): # GH 4161 diff --git a/pandas/tests/groupby/test_transform.py b/pandas/tests/groupby/test_transform.py index 0b81235ef2117..40434ff510421 100644 --- a/pandas/tests/groupby/test_transform.py +++ b/pandas/tests/groupby/test_transform.py @@ -17,7 +17,7 @@ from pandas.core.config import option_context -class TestGroupBy(MixIn, tm.TestCase): +class TestGroupBy(MixIn): def test_transform(self): data = Series(np.arange(9) // 3, index=np.arange(9)) diff --git a/pandas/tests/indexes/datetimes/test_astype.py b/pandas/tests/indexes/datetimes/test_astype.py index 1c8189d0c75ac..0f7acf1febae8 100644 --- a/pandas/tests/indexes/datetimes/test_astype.py +++ b/pandas/tests/indexes/datetimes/test_astype.py @@ -9,7 +9,7 @@ Int64Index, Period) -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_astype(self): # GH 13149, GH 13209 @@ -185,9 +185,9 @@ def _check_rng(rng): _check_rng(rng_utc) -class TestToPeriod(tm.TestCase): +class TestToPeriod(object): - def setUp(self): + def setup_method(self, method): data = [Timestamp('2007-01-01 10:11:12.123456Z'), Timestamp('2007-01-01 10:11:13.789123Z')] self.index = DatetimeIndex(data) diff --git a/pandas/tests/indexes/datetimes/test_construction.py b/pandas/tests/indexes/datetimes/test_construction.py index 9af4136afd025..fcfc56ea823da 100644 --- a/pandas/tests/indexes/datetimes/test_construction.py +++ b/pandas/tests/indexes/datetimes/test_construction.py @@ -12,7 +12,7 @@ to_datetime) -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_construction_caching(self): @@ -446,7 +446,7 @@ def test_000constructor_resolution(self): assert idx.nanosecond[0] == t1.nanosecond -class TestTimeSeries(tm.TestCase): +class TestTimeSeries(object): def test_dti_constructor_preserve_dti_freq(self): rng = date_range('1/1/2000', '1/2/2000', freq='5min') diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index a9fdd40406770..0586ea9c4db2b 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -26,7 +26,7 @@ def eq_gen_range(kwargs, expected): assert (np.array_equal(list(rng), expected)) -class TestDateRanges(TestData, tm.TestCase): +class TestDateRanges(TestData): def test_date_range_gen_error(self): rng = date_range('1/1/2000 00:00', '1/1/2000 00:18', freq='5min') @@ -147,7 +147,7 @@ def test_catch_infinite_loop(self): datetime(2011, 11, 12), freq=offset) -class TestGenRangeGeneration(tm.TestCase): +class TestGenRangeGeneration(object): def test_generate(self): rng1 = list(generate_range(START, END, offset=BDay())) @@ -196,9 +196,9 @@ def test_precision_finer_than_offset(self): tm.assert_index_equal(result2, expected2) -class TestBusinessDateRange(tm.TestCase): +class TestBusinessDateRange(object): - def setUp(self): + def setup_method(self, method): self.rng = bdate_range(START, END) def test_constructor(self): @@ -482,8 +482,8 @@ def test_freq_divides_end_in_nanos(self): tm.assert_index_equal(result_2, expected_2) -class TestCustomDateRange(tm.TestCase): - def setUp(self): +class TestCustomDateRange(object): + def setup_method(self, method): self.rng = cdate_range(START, END) def test_constructor(self): diff --git a/pandas/tests/indexes/datetimes/test_datetime.py b/pandas/tests/indexes/datetimes/test_datetime.py index 7b22d1615fbeb..96c8da546ff9d 100644 --- a/pandas/tests/indexes/datetimes/test_datetime.py +++ b/pandas/tests/indexes/datetimes/test_datetime.py @@ -15,7 +15,7 @@ randn = np.random.randn -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_get_loc(self): idx = pd.date_range('2000-01-01', periods=3) diff --git a/pandas/tests/indexes/datetimes/test_datetimelike.py b/pandas/tests/indexes/datetimes/test_datetimelike.py index 0eb565bf0ec55..3b970ee382521 100644 --- a/pandas/tests/indexes/datetimes/test_datetimelike.py +++ b/pandas/tests/indexes/datetimes/test_datetimelike.py @@ -8,10 +8,10 @@ from ..datetimelike import DatetimeLike -class TestDatetimeIndex(DatetimeLike, tm.TestCase): +class TestDatetimeIndex(DatetimeLike): _holder = DatetimeIndex - def setUp(self): + def setup_method(self, method): self.indices = dict(index=tm.makeDateIndex(10)) self.setup_indices() diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 92134a296b08f..a9ea028c9d0f7 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -7,7 +7,7 @@ from pandas import notnull, Index, DatetimeIndex, datetime, date_range -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_where_other(self): diff --git a/pandas/tests/indexes/datetimes/test_misc.py b/pandas/tests/indexes/datetimes/test_misc.py index d9a61776a0d1c..951aa2c520d0f 100644 --- a/pandas/tests/indexes/datetimes/test_misc.py +++ b/pandas/tests/indexes/datetimes/test_misc.py @@ -7,7 +7,7 @@ Float64Index, date_range, Timestamp) -class TestDateTimeIndexToJulianDate(tm.TestCase): +class TestDateTimeIndexToJulianDate(object): def test_1700(self): r1 = Float64Index([2345897.5, 2345898.5, 2345899.5, 2345900.5, @@ -53,7 +53,7 @@ def test_second(self): tm.assert_index_equal(r1, r2) -class TestTimeSeries(tm.TestCase): +class TestTimeSeries(object): def test_pass_datetimeindex_to_index(self): # Bugs in #1396 @@ -170,7 +170,7 @@ def test_normalize(self): assert not rng.is_normalized -class TestDatetime64(tm.TestCase): +class TestDatetime64(object): def test_datetimeindex_accessors(self): diff --git a/pandas/tests/indexes/datetimes/test_missing.py b/pandas/tests/indexes/datetimes/test_missing.py index 0c356e3251e2f..adc0b7b3d81e8 100644 --- a/pandas/tests/indexes/datetimes/test_missing.py +++ b/pandas/tests/indexes/datetimes/test_missing.py @@ -2,7 +2,7 @@ import pandas.util.testing as tm -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_fillna_datetime64(self): # GH 11343 diff --git a/pandas/tests/indexes/datetimes/test_ops.py b/pandas/tests/indexes/datetimes/test_ops.py index e25e3d448190e..80e93a1f76a66 100644 --- a/pandas/tests/indexes/datetimes/test_ops.py +++ b/pandas/tests/indexes/datetimes/test_ops.py @@ -23,8 +23,8 @@ class TestDatetimeIndexOps(Ops): tz = [None, 'UTC', 'Asia/Tokyo', 'US/Eastern', 'dateutil/Asia/Singapore', 'dateutil/US/Pacific'] - def setUp(self): - super(TestDatetimeIndexOps, self).setUp() + def setup_method(self, method): + super(TestDatetimeIndexOps, self).setup_method(method) mask = lambda x: (isinstance(x, DatetimeIndex) or isinstance(x, PeriodIndex)) self.is_valid_objs = [o for o in self.objs if mask(o)] @@ -931,7 +931,7 @@ def test_equals(self): assert not idx.equals(pd.Series(idx3)) -class TestDateTimeIndexToJulianDate(tm.TestCase): +class TestDateTimeIndexToJulianDate(object): def test_1700(self): r1 = Float64Index([2345897.5, 2345898.5, 2345899.5, 2345900.5, @@ -1107,9 +1107,9 @@ def test_shift_months(years, months): tm.assert_index_equal(actual, expected) -class TestBusinessDatetimeIndex(tm.TestCase): +class TestBusinessDatetimeIndex(object): - def setUp(self): + def setup_method(self, method): self.rng = bdate_range(START, END) def test_comparison(self): @@ -1207,9 +1207,9 @@ def test_identical(self): assert not t1.identical(t2v) -class TestCustomDatetimeIndex(tm.TestCase): +class TestCustomDatetimeIndex(object): - def setUp(self): + def setup_method(self, method): self.rng = cdate_range(START, END) def test_comparison(self): diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index b3661ae0e7a97..e7d03aa193cbd 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -11,7 +11,7 @@ from pandas.util import testing as tm -class TestSlicing(tm.TestCase): +class TestSlicing(object): def test_slice_year(self): dti = DatetimeIndex(freq='B', start=datetime(2005, 1, 1), periods=500) diff --git a/pandas/tests/indexes/datetimes/test_setops.py b/pandas/tests/indexes/datetimes/test_setops.py index b25fdaf6be3b0..f3af7dd30c27f 100644 --- a/pandas/tests/indexes/datetimes/test_setops.py +++ b/pandas/tests/indexes/datetimes/test_setops.py @@ -12,7 +12,7 @@ START, END = datetime(2009, 1, 1), datetime(2010, 1, 1) -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_union(self): i1 = Int64Index(np.arange(0, 20, 2)) @@ -199,9 +199,9 @@ def test_join_nonunique(self): assert rs.is_monotonic -class TestBusinessDatetimeIndex(tm.TestCase): +class TestBusinessDatetimeIndex(object): - def setUp(self): + def setup_method(self, method): self.rng = bdate_range(START, END) def test_union(self): @@ -343,9 +343,9 @@ def test_month_range_union_tz_dateutil(self): early_dr.union(late_dr) -class TestCustomDatetimeIndex(tm.TestCase): +class TestCustomDatetimeIndex(object): - def setUp(self): + def setup_method(self, method): self.rng = cdate_range(START, END) def test_union(self): diff --git a/pandas/tests/indexes/datetimes/test_tools.py b/pandas/tests/indexes/datetimes/test_tools.py index 3c7f2e424f779..648df01be5289 100644 --- a/pandas/tests/indexes/datetimes/test_tools.py +++ b/pandas/tests/indexes/datetimes/test_tools.py @@ -22,7 +22,7 @@ compat) -class TimeConversionFormats(tm.TestCase): +class TimeConversionFormats(object): def test_to_datetime_format(self): values = ['1/1/2000', '1/2/2000', '1/3/2000'] @@ -170,7 +170,7 @@ def test_to_datetime_format_weeks(self): assert to_datetime(s, format=format) == dt -class TestToDatetime(tm.TestCase): +class TestToDatetime(object): def test_to_datetime_dt64s(self): in_bound_dts = [ @@ -335,7 +335,7 @@ def test_datetime_invalid_datatype(self): pd.to_datetime(pd.to_datetime) -class ToDatetimeUnit(tm.TestCase): +class ToDatetimeUnit(object): def test_unit(self): # GH 11758 @@ -595,7 +595,7 @@ def test_dataframe_dtypes(self): to_datetime(df) -class ToDatetimeMisc(tm.TestCase): +class ToDatetimeMisc(object): def test_index_to_datetime(self): idx = Index(['1/1/2000', '1/2/2000', '1/3/2000']) @@ -829,7 +829,7 @@ def test_dayfirst(self): tm.assert_index_equal(expected, idx6) -class TestGuessDatetimeFormat(tm.TestCase): +class TestGuessDatetimeFormat(object): def test_guess_datetime_format_with_parseable_formats(self): tm._skip_if_not_us_locale() @@ -914,7 +914,7 @@ def test_guess_datetime_format_for_array(self): assert format_for_string_of_nans is None -class TestToDatetimeInferFormat(tm.TestCase): +class TestToDatetimeInferFormat(object): def test_to_datetime_infer_datetime_format_consistent_format(self): s = pd.Series(pd.date_range('20000101', periods=50, freq='H')) @@ -974,7 +974,7 @@ def test_to_datetime_iso8601_noleading_0s(self): tm.assert_series_equal(pd.to_datetime(s, format='%Y-%m-%d'), expected) -class TestDaysInMonth(tm.TestCase): +class TestDaysInMonth(object): # tests for issue #10154 def test_day_not_in_month_coerce(self): @@ -1006,7 +1006,7 @@ def test_day_not_in_month_ignore(self): format="%Y-%m-%d") == '2015-04-31' -class TestDatetimeParsingWrappers(tm.TestCase): +class TestDatetimeParsingWrappers(object): def test_does_not_convert_mixed_integer(self): bad_date_strings = ('-50000', '999', '123.1234', 'm', 'T') @@ -1362,7 +1362,7 @@ def test_parsers_iso8601(self): raise Exception(date_str) -class TestArrayToDatetime(tm.TestCase): +class TestArrayToDatetime(object): def test_try_parse_dates(self): from dateutil.parser import parse diff --git a/pandas/tests/indexes/period/test_asfreq.py b/pandas/tests/indexes/period/test_asfreq.py index f9effd3d1aea6..c8724b2a3bc91 100644 --- a/pandas/tests/indexes/period/test_asfreq.py +++ b/pandas/tests/indexes/period/test_asfreq.py @@ -6,9 +6,9 @@ from pandas import PeriodIndex, Series, DataFrame -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_asfreq(self): diff --git a/pandas/tests/indexes/period/test_construction.py b/pandas/tests/indexes/period/test_construction.py index a95ad808cadce..6a188c0987f91 100644 --- a/pandas/tests/indexes/period/test_construction.py +++ b/pandas/tests/indexes/period/test_construction.py @@ -9,9 +9,9 @@ Series, Index) -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_construction_base_constructor(self): @@ -473,9 +473,9 @@ def test_map_with_string_constructor(self): tm.assert_index_equal(res, expected) -class TestSeriesPeriod(tm.TestCase): +class TestSeriesPeriod(object): - def setUp(self): + def setup_method(self, method): self.series = Series(period_range('2000-01-01', periods=10, freq='D')) def test_constructor_cant_cast_period(self): diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index ebbe05d51598c..d4dac1cf88fff 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -11,9 +11,9 @@ period_range, Period, _np_version_under1p9) -class TestGetItem(tm.TestCase): +class TestGetItem(object): - def setUp(self): + def setup_method(self, method): pass def test_getitem(self): @@ -200,7 +200,7 @@ def test_getitem_day(self): s[v] -class TestIndexing(tm.TestCase): +class TestIndexing(object): def test_get_loc_msg(self): idx = period_range('2000-1-1', freq='A', periods=10) diff --git a/pandas/tests/indexes/period/test_ops.py b/pandas/tests/indexes/period/test_ops.py index fb688bda58ae8..7acc335c31be4 100644 --- a/pandas/tests/indexes/period/test_ops.py +++ b/pandas/tests/indexes/period/test_ops.py @@ -15,8 +15,8 @@ class TestPeriodIndexOps(Ops): - def setUp(self): - super(TestPeriodIndexOps, self).setUp() + def setup_method(self, method): + super(TestPeriodIndexOps, self).setup_method(method) mask = lambda x: (isinstance(x, DatetimeIndex) or isinstance(x, PeriodIndex)) self.is_valid_objs = [o for o in self.objs if mask(o)] @@ -851,7 +851,7 @@ def test_equals(self): assert not idx.equals(pd.Series(idx3)) -class TestPeriodIndexSeriesMethods(tm.TestCase): +class TestPeriodIndexSeriesMethods(object): """ Test PeriodIndex and Period Series Ops consistency """ def _check(self, values, func, expected): @@ -1135,9 +1135,9 @@ def test_pi_comp_period_nat(self): self._check(idx, f, exp) -class TestSeriesPeriod(tm.TestCase): +class TestSeriesPeriod(object): - def setUp(self): + def setup_method(self, method): self.series = Series(period_range('2000-01-01', periods=10, freq='D')) def test_ops_series_timedelta(self): @@ -1175,7 +1175,7 @@ def test_ops_series_period(self): tm.assert_series_equal(s - s2, -exp) -class TestFramePeriod(tm.TestCase): +class TestFramePeriod(object): def test_ops_frame_period(self): # GH 13043 @@ -1206,7 +1206,7 @@ def test_ops_frame_period(self): tm.assert_frame_equal(df - df2, -exp) -class TestPeriodIndexComparisons(tm.TestCase): +class TestPeriodIndexComparisons(object): def test_pi_pi_comp(self): diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index 04b4e6795e770..6d142722c315a 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -8,9 +8,9 @@ DataFrame, _np_version_under1p12, Period) -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_slice_with_negative_step(self): diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index 6ec567509cd76..6f73e7c15e4d9 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -13,11 +13,11 @@ from ..datetimelike import DatetimeLike -class TestPeriodIndex(DatetimeLike, tm.TestCase): +class TestPeriodIndex(DatetimeLike): _holder = PeriodIndex _multiprocess_can_split_ = True - def setUp(self): + def setup_method(self, method): self.indices = dict(index=tm.makePeriodIndex(10)) self.setup_indices() diff --git a/pandas/tests/indexes/period/test_setops.py b/pandas/tests/indexes/period/test_setops.py index 025ee7e732a7c..1ac05f9fa94b7 100644 --- a/pandas/tests/indexes/period/test_setops.py +++ b/pandas/tests/indexes/period/test_setops.py @@ -12,9 +12,9 @@ def _permute(obj): return obj.take(np.random.permutation(len(obj))) -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_joins(self): diff --git a/pandas/tests/indexes/period/test_tools.py b/pandas/tests/indexes/period/test_tools.py index 9e5994dd54f50..074678164e6f9 100644 --- a/pandas/tests/indexes/period/test_tools.py +++ b/pandas/tests/indexes/period/test_tools.py @@ -11,7 +11,7 @@ date_range, to_datetime, period_range) -class TestPeriodRepresentation(tm.TestCase): +class TestPeriodRepresentation(object): """ Wish to match NumPy units """ @@ -73,7 +73,7 @@ def test_negone_ordinals(self): repr(period) -class TestTslib(tm.TestCase): +class TestTslib(object): def test_intraday_conversion_factors(self): assert period_asfreq(1, get_freq('D'), get_freq('H'), False) == 24 assert period_asfreq(1, get_freq('D'), get_freq('T'), False) == 1440 @@ -150,9 +150,9 @@ def test_period_ordinal_business_day(self): 0, 0, 0, 0, get_freq('B')) == 11418 -class TestPeriodIndex(tm.TestCase): +class TestPeriodIndex(object): - def setUp(self): + def setup_method(self, method): pass def test_tolist(self): diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 10958681af450..6a2087b37631e 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -29,10 +29,10 @@ from pandas._libs.lib import Timestamp -class TestIndex(Base, tm.TestCase): +class TestIndex(Base): _holder = Index - def setUp(self): + def setup_method(self, method): self.indices = dict(unicodeIndex=tm.makeUnicodeIndex(100), strIndex=tm.makeStringIndex(100), dateIndex=tm.makeDateIndex(100), @@ -1801,14 +1801,14 @@ def test_string_index_repr(self): assert coerce(idx) == expected -class TestMixedIntIndex(Base, tm.TestCase): +class TestMixedIntIndex(Base): # Mostly the tests from common.py for which the results differ # in py2 and py3 because ints and strings are uncomparable in py3 # (GH 13514) _holder = Index - def setUp(self): + def setup_method(self, method): self.indices = dict(mixedIndex=Index([0, 'a', 1, 'b', 2, 'c'])) self.setup_indices() diff --git a/pandas/tests/indexes/test_category.py b/pandas/tests/indexes/test_category.py index 6a2eea0b84b72..4e4f9b29f9a4c 100644 --- a/pandas/tests/indexes/test_category.py +++ b/pandas/tests/indexes/test_category.py @@ -19,10 +19,10 @@ unicode = lambda x: x -class TestCategoricalIndex(Base, tm.TestCase): +class TestCategoricalIndex(Base): _holder = CategoricalIndex - def setUp(self): + def setup_method(self, method): self.indices = dict(catIndex=tm.makeCategoricalIndex(100)) self.setup_indices() diff --git a/pandas/tests/indexes/test_frozen.py b/pandas/tests/indexes/test_frozen.py index ed2e3d94aa4a4..ca9841112b1d5 100644 --- a/pandas/tests/indexes/test_frozen.py +++ b/pandas/tests/indexes/test_frozen.py @@ -5,11 +5,11 @@ from pandas.compat import u -class TestFrozenList(CheckImmutable, CheckStringMixin, tm.TestCase): +class TestFrozenList(CheckImmutable, CheckStringMixin): mutable_methods = ('extend', 'pop', 'remove', 'insert') unicode_container = FrozenList([u("\u05d0"), u("\u05d1"), "c"]) - def setUp(self): + def setup_method(self, method): self.lst = [1, 2, 3, 4, 5] self.container = FrozenList(self.lst) self.klass = FrozenList @@ -31,11 +31,11 @@ def test_inplace(self): self.check_result(r, self.lst) -class TestFrozenNDArray(CheckImmutable, CheckStringMixin, tm.TestCase): +class TestFrozenNDArray(CheckImmutable, CheckStringMixin): mutable_methods = ('put', 'itemset', 'fill') unicode_container = FrozenNDArray([u("\u05d0"), u("\u05d1"), "c"]) - def setUp(self): + def setup_method(self, method): self.lst = [3, 5, 7, -2] self.container = FrozenNDArray(self.lst) self.klass = FrozenNDArray diff --git a/pandas/tests/indexes/test_interval.py b/pandas/tests/indexes/test_interval.py index 00897f290f292..33745017fe3d6 100644 --- a/pandas/tests/indexes/test_interval.py +++ b/pandas/tests/indexes/test_interval.py @@ -12,10 +12,10 @@ import pandas as pd -class TestIntervalIndex(Base, tm.TestCase): +class TestIntervalIndex(Base): _holder = IntervalIndex - def setUp(self): + def setup_method(self, method): self.index = IntervalIndex.from_arrays([0, 1], [1, 2]) self.index_with_nan = IntervalIndex.from_tuples( [(0, 1), np.nan, (1, 2)]) @@ -682,7 +682,7 @@ def f(): pytest.raises(ValueError, f) -class TestIntervalRange(tm.TestCase): +class TestIntervalRange(object): def test_construction(self): result = interval_range(0, 5, name='foo', closed='both') @@ -720,8 +720,8 @@ def f(): pytest.raises(ValueError, f) -class TestIntervalTree(tm.TestCase): - def setUp(self): +class TestIntervalTree(object): + def setup_method(self, method): gentree = lambda dtype: IntervalTree(np.arange(5, dtype=dtype), np.arange(5, dtype=dtype) + 2) self.tree = gentree('int64') diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index a840711e37fb0..1fe4d85815c4b 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -27,11 +27,11 @@ from .common import Base -class TestMultiIndex(Base, tm.TestCase): +class TestMultiIndex(Base): _holder = MultiIndex _compat_props = ['shape', 'ndim', 'size', 'itemsize'] - def setUp(self): + def setup_method(self, method): major_axis = Index(['foo', 'bar', 'baz', 'qux']) minor_axis = Index(['one', 'two']) @@ -486,7 +486,7 @@ def test_copy_names(self): def test_names(self): - # names are assigned in __init__ + # names are assigned in setup names = self.index_names level_names = [level.name for level in self.index.levels] assert names == level_names diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 428c261df5654..3d06f1672ae32 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -176,10 +176,10 @@ def test_modulo(self): tm.assert_index_equal(index % 2, expected) -class TestFloat64Index(Numeric, tm.TestCase): +class TestFloat64Index(Numeric): _holder = Float64Index - def setUp(self): + def setup_method(self, method): self.indices = dict(mixed=Float64Index([1.5, 2, 3, 4, 5]), float=Float64Index(np.arange(5) * 2.5)) self.setup_indices() @@ -621,11 +621,11 @@ def test_ufunc_coercions(self): tm.assert_index_equal(result, exp) -class TestInt64Index(NumericInt, tm.TestCase): +class TestInt64Index(NumericInt): _dtype = 'int64' _holder = Int64Index - def setUp(self): + def setup_method(self, method): self.indices = dict(index=Int64Index(np.arange(0, 20, 2))) self.setup_indices() @@ -915,12 +915,12 @@ def test_join_outer(self): tm.assert_numpy_array_equal(ridx, eridx) -class TestUInt64Index(NumericInt, tm.TestCase): +class TestUInt64Index(NumericInt): _dtype = 'uint64' _holder = UInt64Index - def setUp(self): + def setup_method(self, method): self.indices = dict(index=UInt64Index([2**63, 2**63 + 10, 2**63 + 15, 2**63 + 20, 2**63 + 25])) self.setup_indices() diff --git a/pandas/tests/indexes/test_range.py b/pandas/tests/indexes/test_range.py index 0379718b004e1..18539989084e9 100644 --- a/pandas/tests/indexes/test_range.py +++ b/pandas/tests/indexes/test_range.py @@ -20,11 +20,11 @@ from .test_numeric import Numeric -class TestRangeIndex(Numeric, tm.TestCase): +class TestRangeIndex(Numeric): _holder = RangeIndex _compat_props = ['shape', 'ndim', 'size', 'itemsize'] - def setUp(self): + def setup_method(self, method): self.indices = dict(index=RangeIndex(0, 20, 2, name='foo')) self.setup_indices() diff --git a/pandas/tests/indexes/timedeltas/test_astype.py b/pandas/tests/indexes/timedeltas/test_astype.py index 6e82f165e4909..586b96f980f8f 100644 --- a/pandas/tests/indexes/timedeltas/test_astype.py +++ b/pandas/tests/indexes/timedeltas/test_astype.py @@ -10,11 +10,11 @@ from ..datetimelike import DatetimeLike -class TestTimedeltaIndex(DatetimeLike, tm.TestCase): +class TestTimedeltaIndex(DatetimeLike): _holder = TimedeltaIndex _multiprocess_can_split_ = True - def setUp(self): + def setup_method(self, method): self.indices = dict(index=tm.makeTimedeltaIndex(10)) self.setup_indices() diff --git a/pandas/tests/indexes/timedeltas/test_construction.py b/pandas/tests/indexes/timedeltas/test_construction.py index bdaa62c5ce221..dd25e2cca2e55 100644 --- a/pandas/tests/indexes/timedeltas/test_construction.py +++ b/pandas/tests/indexes/timedeltas/test_construction.py @@ -8,7 +8,7 @@ from pandas import TimedeltaIndex, timedelta_range, to_timedelta -class TestTimedeltaIndex(tm.TestCase): +class TestTimedeltaIndex(object): _multiprocess_can_split_ = True def test_construction_base_constructor(self): diff --git a/pandas/tests/indexes/timedeltas/test_indexing.py b/pandas/tests/indexes/timedeltas/test_indexing.py index 6ffe3516c4a94..844033cc19eed 100644 --- a/pandas/tests/indexes/timedeltas/test_indexing.py +++ b/pandas/tests/indexes/timedeltas/test_indexing.py @@ -6,7 +6,7 @@ from pandas import TimedeltaIndex, timedelta_range, compat, Index, Timedelta -class TestTimedeltaIndex(tm.TestCase): +class TestTimedeltaIndex(object): _multiprocess_can_split_ = True def test_insert(self): diff --git a/pandas/tests/indexes/timedeltas/test_ops.py b/pandas/tests/indexes/timedeltas/test_ops.py index 474dd283530c5..9a9912d4f0ab1 100644 --- a/pandas/tests/indexes/timedeltas/test_ops.py +++ b/pandas/tests/indexes/timedeltas/test_ops.py @@ -16,8 +16,8 @@ class TestTimedeltaIndexOps(Ops): - def setUp(self): - super(TestTimedeltaIndexOps, self).setUp() + def setup_method(self, method): + super(TestTimedeltaIndexOps, self).setup_method(method) mask = lambda x: isinstance(x, TimedeltaIndex) self.is_valid_objs = [o for o in self.objs if mask(o)] self.not_valid_objs = [] @@ -861,7 +861,7 @@ def test_equals(self): assert not idx.equals(pd.Series(idx2)) -class TestTimedeltas(tm.TestCase): +class TestTimedeltas(object): _multiprocess_can_split_ = True def test_ops(self): @@ -1209,7 +1209,7 @@ def test_compare_timedelta_ndarray(self): tm.assert_numpy_array_equal(result, expected) -class TestSlicing(tm.TestCase): +class TestSlicing(object): def test_tdi_ops_attributes(self): rng = timedelta_range('2 days', periods=5, freq='2D', name='x') diff --git a/pandas/tests/indexes/timedeltas/test_partial_slicing.py b/pandas/tests/indexes/timedeltas/test_partial_slicing.py index 5e6e1440a7c04..8e5eae2a7a3ef 100644 --- a/pandas/tests/indexes/timedeltas/test_partial_slicing.py +++ b/pandas/tests/indexes/timedeltas/test_partial_slicing.py @@ -8,7 +8,7 @@ from pandas.util.testing import assert_series_equal -class TestSlicing(tm.TestCase): +class TestSlicing(object): def test_partial_slice(self): rng = timedelta_range('1 day 10:11:12', freq='h', periods=500) diff --git a/pandas/tests/indexes/timedeltas/test_setops.py b/pandas/tests/indexes/timedeltas/test_setops.py index 8779f6d49cdd5..22546d25273a7 100644 --- a/pandas/tests/indexes/timedeltas/test_setops.py +++ b/pandas/tests/indexes/timedeltas/test_setops.py @@ -5,7 +5,7 @@ from pandas import TimedeltaIndex, timedelta_range, Int64Index -class TestTimedeltaIndex(tm.TestCase): +class TestTimedeltaIndex(object): _multiprocess_can_split_ = True def test_union(self): diff --git a/pandas/tests/indexes/timedeltas/test_timedelta.py b/pandas/tests/indexes/timedeltas/test_timedelta.py index d1379973dfec5..79fe0a864f246 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta.py @@ -16,11 +16,11 @@ randn = np.random.randn -class TestTimedeltaIndex(DatetimeLike, tm.TestCase): +class TestTimedeltaIndex(DatetimeLike): _holder = TimedeltaIndex _multiprocess_can_split_ = True - def setUp(self): + def setup_method(self, method): self.indices = dict(index=tm.makeTimedeltaIndex(10)) self.setup_indices() @@ -563,7 +563,7 @@ def test_freq_conversion(self): assert_index_equal(result, expected) -class TestSlicing(tm.TestCase): +class TestSlicing(object): def test_timedelta(self): # this is valid too @@ -589,7 +589,7 @@ def test_timedelta(self): tm.assert_index_equal(result2, result3) -class TestTimeSeries(tm.TestCase): +class TestTimeSeries(object): _multiprocess_can_split_ = True def test_series_box_timedelta(self): diff --git a/pandas/tests/indexes/timedeltas/test_timedelta_range.py b/pandas/tests/indexes/timedeltas/test_timedelta_range.py index 55f16c10e9945..4732a0ce110de 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta_range.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta_range.py @@ -7,7 +7,7 @@ from pandas.util.testing import assert_frame_equal -class TestTimedeltas(tm.TestCase): +class TestTimedeltas(object): _multiprocess_can_split_ = True def test_timedelta_range(self): diff --git a/pandas/tests/indexes/timedeltas/test_tools.py b/pandas/tests/indexes/timedeltas/test_tools.py index faee627488dc0..a991b7bbe140a 100644 --- a/pandas/tests/indexes/timedeltas/test_tools.py +++ b/pandas/tests/indexes/timedeltas/test_tools.py @@ -11,7 +11,7 @@ from pandas._libs.tslib import iNaT -class TestTimedeltas(tm.TestCase): +class TestTimedeltas(object): _multiprocess_can_split_ = True def test_to_timedelta(self): diff --git a/pandas/tests/indexing/common.py b/pandas/tests/indexing/common.py index bd5b7f45a6f4c..259a8aea94df0 100644 --- a/pandas/tests/indexing/common.py +++ b/pandas/tests/indexing/common.py @@ -31,7 +31,7 @@ class Base(object): _typs = set(['ints', 'uints', 'labels', 'mixed', 'ts', 'floats', 'empty', 'ts_rev']) - def setUp(self): + def setup_method(self, method): self.series_ints = Series(np.random.rand(4), index=lrange(0, 8, 2)) self.frame_ints = DataFrame(np.random.randn(4, 4), diff --git a/pandas/tests/indexing/test_callable.py b/pandas/tests/indexing/test_callable.py index 727c87ac90872..95b406517be62 100644 --- a/pandas/tests/indexing/test_callable.py +++ b/pandas/tests/indexing/test_callable.py @@ -6,7 +6,7 @@ import pandas.util.testing as tm -class TestIndexingCallable(tm.TestCase): +class TestIndexingCallable(object): def test_frame_loc_ix_callable(self): # GH 11485 diff --git a/pandas/tests/indexing/test_categorical.py b/pandas/tests/indexing/test_categorical.py index f9fcef16c12d4..6874fedaa705f 100644 --- a/pandas/tests/indexing/test_categorical.py +++ b/pandas/tests/indexing/test_categorical.py @@ -10,9 +10,9 @@ from pandas.util import testing as tm -class TestCategoricalIndex(tm.TestCase): +class TestCategoricalIndex(object): - def setUp(self): + def setup_method(self, method): self.df = DataFrame({'A': np.arange(6, dtype='int64'), 'B': Series(list('aabbca')).astype( diff --git a/pandas/tests/indexing/test_chaining_and_caching.py b/pandas/tests/indexing/test_chaining_and_caching.py index c1f5d2941106d..27a889e58e55e 100644 --- a/pandas/tests/indexing/test_chaining_and_caching.py +++ b/pandas/tests/indexing/test_chaining_and_caching.py @@ -10,7 +10,7 @@ from pandas.util import testing as tm -class TestCaching(tm.TestCase): +class TestCaching(object): def test_slice_consolidate_invalidate_item_cache(self): @@ -90,7 +90,7 @@ def test_setitem_cache_updating(self): tm.assert_series_equal(out['A'], expected['A']) -class TestChaining(tm.TestCase): +class TestChaining(object): def test_setitem_chained_setfault(self): diff --git a/pandas/tests/indexing/test_coercion.py b/pandas/tests/indexing/test_coercion.py index 56bc8c1d72bb8..25cc810299678 100644 --- a/pandas/tests/indexing/test_coercion.py +++ b/pandas/tests/indexing/test_coercion.py @@ -44,7 +44,7 @@ def test_has_comprehensive_tests(self): raise AssertionError(msg.format(type(self), method_name)) -class TestSetitemCoercion(CoercionBase, tm.TestCase): +class TestSetitemCoercion(CoercionBase): method = 'setitem' @@ -330,7 +330,7 @@ def test_setitem_index_period(self): pass -class TestInsertIndexCoercion(CoercionBase, tm.TestCase): +class TestInsertIndexCoercion(CoercionBase): klasses = ['index'] method = 'insert' @@ -514,7 +514,7 @@ def test_insert_index_period(self): self._assert_insert_conversion(obj, 'x', exp, np.object) -class TestWhereCoercion(CoercionBase, tm.TestCase): +class TestWhereCoercion(CoercionBase): method = 'where' @@ -852,7 +852,7 @@ def test_where_index_period(self): pass -class TestFillnaSeriesCoercion(CoercionBase, tm.TestCase): +class TestFillnaSeriesCoercion(CoercionBase): # not indexing, but place here for consisntency @@ -1139,14 +1139,14 @@ def test_fillna_index_period(self): pass -class TestReplaceSeriesCoercion(CoercionBase, tm.TestCase): +class TestReplaceSeriesCoercion(CoercionBase): # not indexing, but place here for consisntency klasses = ['series'] method = 'replace' - def setUp(self): + def setup_method(self, method): self.rep = {} self.rep['object'] = ['a', 'b'] self.rep['int64'] = [4, 5] diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py index 3089bc1dbddea..da8a896cb6f4a 100644 --- a/pandas/tests/indexing/test_datetime.py +++ b/pandas/tests/indexing/test_datetime.py @@ -6,7 +6,7 @@ from pandas.util import testing as tm -class TestDatetimeIndex(tm.TestCase): +class TestDatetimeIndex(object): def test_indexing_with_datetime_tz(self): diff --git a/pandas/tests/indexing/test_floats.py b/pandas/tests/indexing/test_floats.py index 1701dd9f6ba90..00a2b8166ceed 100644 --- a/pandas/tests/indexing/test_floats.py +++ b/pandas/tests/indexing/test_floats.py @@ -9,7 +9,7 @@ import pandas.util.testing as tm -class TestFloatIndexers(tm.TestCase): +class TestFloatIndexers(object): def check(self, result, original, indexer, getitem): """ diff --git a/pandas/tests/indexing/test_iloc.py b/pandas/tests/indexing/test_iloc.py index 3e625fa483f7b..af4b9e1f0cc25 100644 --- a/pandas/tests/indexing/test_iloc.py +++ b/pandas/tests/indexing/test_iloc.py @@ -12,7 +12,7 @@ from pandas.tests.indexing.common import Base -class TestiLoc(Base, tm.TestCase): +class TestiLoc(Base): def test_iloc_exceeds_bounds(self): diff --git a/pandas/tests/indexing/test_indexing.py b/pandas/tests/indexing/test_indexing.py index 0759dc2333ad5..9fa677eb624ae 100644 --- a/pandas/tests/indexing/test_indexing.py +++ b/pandas/tests/indexing/test_indexing.py @@ -26,7 +26,7 @@ # Indexing test cases -class TestFancy(Base, tm.TestCase): +class TestFancy(Base): """ pure get/set item & fancy indexing """ def test_setitem_ndarray_1d(self): @@ -599,7 +599,7 @@ def test_index_type_coercion(self): assert s2.index.is_object() -class TestMisc(Base, tm.TestCase): +class TestMisc(Base): def test_indexer_caching(self): # GH5727 @@ -800,7 +800,7 @@ def test_maybe_numeric_slice(self): assert result == expected -class TestSeriesNoneCoercion(tm.TestCase): +class TestSeriesNoneCoercion(object): EXPECTED_RESULTS = [ # For numeric series, we should coerce to NaN. ([1, 2, 3], [np.nan, 2, 3]), @@ -847,7 +847,7 @@ def test_coercion_with_loc_and_series(self): tm.assert_series_equal(start_series, expected_series) -class TestDataframeNoneCoercion(tm.TestCase): +class TestDataframeNoneCoercion(object): EXPECTED_SINGLE_ROW_RESULTS = [ # For numeric series, we should coerce to NaN. ([1, 2, 3], [np.nan, 2, 3]), diff --git a/pandas/tests/indexing/test_indexing_slow.py b/pandas/tests/indexing/test_indexing_slow.py index 21cdbb17f52ce..08d390a6a213e 100644 --- a/pandas/tests/indexing/test_indexing_slow.py +++ b/pandas/tests/indexing/test_indexing_slow.py @@ -8,7 +8,7 @@ import pandas.util.testing as tm -class TestIndexingSlow(tm.TestCase): +class TestIndexingSlow(object): @tm.slow def test_multiindex_get_loc(self): # GH7724, GH2646 diff --git a/pandas/tests/indexing/test_interval.py b/pandas/tests/indexing/test_interval.py index bccc21ed6c086..2552fc066cc87 100644 --- a/pandas/tests/indexing/test_interval.py +++ b/pandas/tests/indexing/test_interval.py @@ -6,9 +6,9 @@ import pandas.util.testing as tm -class TestIntervalIndex(tm.TestCase): +class TestIntervalIndex(object): - def setUp(self): + def setup_method(self, method): self.s = Series(np.arange(5), IntervalIndex.from_breaks(np.arange(6))) def test_loc_with_scalar(self): diff --git a/pandas/tests/indexing/test_ix.py b/pandas/tests/indexing/test_ix.py index 8290bc80edac1..dc9a591ee3101 100644 --- a/pandas/tests/indexing/test_ix.py +++ b/pandas/tests/indexing/test_ix.py @@ -14,7 +14,7 @@ from pandas.errors import PerformanceWarning -class TestIX(tm.TestCase): +class TestIX(object): def test_ix_deprecation(self): # GH 15114 diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 410d01431ef5a..fe2318be72eda 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -14,7 +14,7 @@ from pandas.tests.indexing.common import Base -class TestLoc(Base, tm.TestCase): +class TestLoc(Base): def test_loc_getitem_dups(self): # GH 5678 diff --git a/pandas/tests/indexing/test_multiindex.py b/pandas/tests/indexing/test_multiindex.py index b8c34f9f28d83..483c39ed8694e 100644 --- a/pandas/tests/indexing/test_multiindex.py +++ b/pandas/tests/indexing/test_multiindex.py @@ -9,7 +9,7 @@ from pandas.tests.indexing.common import _mklbl -class TestMultiIndexBasic(tm.TestCase): +class TestMultiIndexBasic(object): def test_iloc_getitem_multiindex2(self): # TODO(wesm): fix this @@ -698,7 +698,7 @@ def test_multiindex_slice_first_level(self): tm.assert_frame_equal(result, expected) -class TestMultiIndexSlicers(tm.TestCase): +class TestMultiIndexSlicers(object): def test_per_axis_per_level_getitem(self): @@ -1188,7 +1188,7 @@ def f(): tm.assert_frame_equal(df, expected) -class TestMultiIndexPanel(tm.TestCase): +class TestMultiIndexPanel(object): def test_iloc_getitem_panel_multiindex(self): diff --git a/pandas/tests/indexing/test_panel.py b/pandas/tests/indexing/test_panel.py index b704e15b81502..2d4ffd6a4e783 100644 --- a/pandas/tests/indexing/test_panel.py +++ b/pandas/tests/indexing/test_panel.py @@ -6,7 +6,7 @@ from pandas import Panel, date_range, DataFrame -class TestPanel(tm.TestCase): +class TestPanel(object): def test_iloc_getitem_panel(self): diff --git a/pandas/tests/indexing/test_partial.py b/pandas/tests/indexing/test_partial.py index 20cec2a3aa7db..93a85e247a787 100644 --- a/pandas/tests/indexing/test_partial.py +++ b/pandas/tests/indexing/test_partial.py @@ -14,7 +14,7 @@ from pandas.util import testing as tm -class TestPartialSetting(tm.TestCase): +class TestPartialSetting(object): def test_partial_setting(self): diff --git a/pandas/tests/indexing/test_scalar.py b/pandas/tests/indexing/test_scalar.py index fb40c539e16ba..5dd1714b903eb 100644 --- a/pandas/tests/indexing/test_scalar.py +++ b/pandas/tests/indexing/test_scalar.py @@ -10,7 +10,7 @@ from pandas.tests.indexing.common import Base -class TestScalar(Base, tm.TestCase): +class TestScalar(Base): def test_at_and_iat_get(self): def _check(f, func, values=False): diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index 5f0088382ce57..cf8cc6c2d345d 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -2,7 +2,7 @@ from pandas.util import testing as tm -class TestTimedeltaIndexing(tm.TestCase): +class TestTimedeltaIndexing(object): def test_boolean_indexing(self): # GH 14946 diff --git a/pandas/tests/io/formats/test_eng_formatting.py b/pandas/tests/io/formats/test_eng_formatting.py index e064d1200d672..9d5773283176c 100644 --- a/pandas/tests/io/formats/test_eng_formatting.py +++ b/pandas/tests/io/formats/test_eng_formatting.py @@ -6,7 +6,7 @@ from pandas.util import testing as tm -class TestEngFormatter(tm.TestCase): +class TestEngFormatter(object): def test_eng_float_formatter(self): df = DataFrame({'A': [1.41, 141., 14100, 1410000.]}) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index ac00e441047dd..3f08013e05ac8 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -29,7 +29,7 @@ import pandas.io.formats.printing as printing import pandas.util.testing as tm -from pandas.util.terminal import get_terminal_size +from pandas.io.formats.terminal import get_terminal_size from pandas.core.config import (set_option, get_option, option_context, reset_option) @@ -105,16 +105,16 @@ def has_expanded_repr(df): return False -class TestDataFrameFormatting(tm.TestCase): +class TestDataFrameFormatting(object): - def setUp(self): + def setup_method(self, method): self.warn_filters = warnings.filters warnings.filterwarnings('ignore', category=FutureWarning, module=".*format") self.frame = _frame.copy() - def tearDown(self): + def teardown_method(self, method): warnings.filters = self.warn_filters def test_repr_embedded_ndarray(self): @@ -1604,9 +1604,9 @@ def gen_series_formatting(): return test_sers -class TestSeriesFormatting(tm.TestCase): +class TestSeriesFormatting(object): - def setUp(self): + def setup_method(self, method): self.ts = tm.makeTimeSeries() def test_repr_unicode(self): @@ -2152,7 +2152,7 @@ def _three_digit_exp(): return '%.4g' % 1.7e8 == '1.7e+008' -class TestFloatArrayFormatter(tm.TestCase): +class TestFloatArrayFormatter(object): def test_misc(self): obj = fmt.FloatArrayFormatter(np.array([], dtype=np.float64)) @@ -2238,7 +2238,7 @@ def test_too_long(self): assert str(df) == ' x\n0 1.2346e+04\n1 2.0000e+06' -class TestRepr_timedelta64(tm.TestCase): +class TestRepr_timedelta64(object): def test_none(self): delta_1d = pd.to_timedelta(1, unit='D') @@ -2311,7 +2311,7 @@ def test_all(self): assert drepr(delta_1ns) == "0 days 00:00:00.000000001" -class TestTimedelta64Formatter(tm.TestCase): +class TestTimedelta64Formatter(object): def test_days(self): x = pd.to_timedelta(list(range(5)) + [pd.NaT], unit='D') @@ -2357,7 +2357,7 @@ def test_zero(self): assert result[0].strip() == "'0 days'" -class TestDatetime64Formatter(tm.TestCase): +class TestDatetime64Formatter(object): def test_mixed(self): x = Series([datetime(2013, 1, 1), datetime(2013, 1, 1, 12), pd.NaT]) @@ -2438,7 +2438,7 @@ def format_func(x): assert result == ['10:10', '12:12'] -class TestNaTFormatting(tm.TestCase): +class TestNaTFormatting(object): def test_repr(self): assert repr(pd.NaT) == "NaT" @@ -2447,7 +2447,7 @@ def test_str(self): assert str(pd.NaT) == "NaT" -class TestDatetimeIndexFormat(tm.TestCase): +class TestDatetimeIndexFormat(object): def test_datetime(self): formatted = pd.to_datetime([datetime(2003, 1, 1, 12), pd.NaT]).format() @@ -2474,7 +2474,7 @@ def test_date_explict_date_format(self): assert formatted[1] == "UT" -class TestDatetimeIndexUnicode(tm.TestCase): +class TestDatetimeIndexUnicode(object): def test_dates(self): text = str(pd.to_datetime([datetime(2013, 1, 1), datetime(2014, 1, 1) @@ -2489,7 +2489,7 @@ def test_mixed(self): assert "'2014-01-01 00:00:00']" in text -class TestStringRepTimestamp(tm.TestCase): +class TestStringRepTimestamp(object): def test_no_tz(self): dt_date = datetime(2013, 1, 2) diff --git a/pandas/tests/io/formats/test_printing.py b/pandas/tests/io/formats/test_printing.py index 44fbd5a958d8c..aae3ba31648ff 100644 --- a/pandas/tests/io/formats/test_printing.py +++ b/pandas/tests/io/formats/test_printing.py @@ -7,7 +7,6 @@ from pandas import compat import pandas.io.formats.printing as printing import pandas.io.formats.format as fmt -import pandas.util.testing as tm import pandas.core.config as cf @@ -35,7 +34,7 @@ def test_repr_binary_type(): assert res == b -class TestFormattBase(tm.TestCase): +class TestFormattBase(object): def test_adjoin(self): data = [['a', 'b', 'c'], ['dd', 'ee', 'ff'], ['ggg', 'hhh', 'iii']] @@ -123,10 +122,10 @@ def test_ambiguous_width(self): assert adjoined == expected -class TestTableSchemaRepr(tm.TestCase): +class TestTableSchemaRepr(object): @classmethod - def setUpClass(cls): + def setup_class(cls): pytest.importorskip('IPython') try: import mock diff --git a/pandas/tests/io/formats/test_style.py b/pandas/tests/io/formats/test_style.py index 1cd338479bd0c..ee7356f12f498 100644 --- a/pandas/tests/io/formats/test_style.py +++ b/pandas/tests/io/formats/test_style.py @@ -5,16 +5,15 @@ import numpy as np import pandas as pd from pandas import DataFrame -from pandas.util.testing import TestCase import pandas.util.testing as tm jinja2 = pytest.importorskip('jinja2') from pandas.io.formats.style import Styler, _get_level_lengths # noqa -class TestStyler(TestCase): +class TestStyler(object): - def setUp(self): + def setup_method(self, method): np.random.seed(24) self.s = DataFrame({'A': np.random.permutation(range(6))}) self.df = DataFrame({'A': [0, 1], 'B': np.random.randn(2)}) @@ -813,10 +812,10 @@ def test_mi_sparse_column_names(self): assert head == expected -@tm.mplskip -class TestStylerMatplotlibDep(TestCase): +class TestStylerMatplotlibDep(object): def test_background_gradient(self): + tm._skip_if_no_mpl() df = pd.DataFrame([[1, 2], [2, 4]], columns=['A', 'B']) for c_map in [None, 'YlOrRd']: diff --git a/pandas/tests/io/formats/test_to_csv.py b/pandas/tests/io/formats/test_to_csv.py index 552fb77bb54cc..1073fbcef5aec 100644 --- a/pandas/tests/io/formats/test_to_csv.py +++ b/pandas/tests/io/formats/test_to_csv.py @@ -4,7 +4,7 @@ from pandas.util import testing as tm -class TestToCSV(tm.TestCase): +class TestToCSV(object): def test_to_csv_quotechar(self): df = DataFrame({'col': [1, 2]}) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 4a4546dd807f1..cde920b1511d2 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -22,7 +22,7 @@ pass -class TestToHTML(tm.TestCase): +class TestToHTML(object): def test_to_html_with_col_space(self): def check_with_width(df, col_space): diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py index c3a976973bb29..e447a74b2b462 100644 --- a/pandas/tests/io/json/test_json_table_schema.py +++ b/pandas/tests/io/json/test_json_table_schema.py @@ -9,7 +9,6 @@ from pandas import DataFrame from pandas.core.dtypes.dtypes import ( PeriodDtype, CategoricalDtype, DatetimeTZDtype) -import pandas.util.testing as tm from pandas.io.json.table_schema import ( as_json_table_type, build_table_schema, @@ -17,9 +16,9 @@ set_default_names) -class TestBuildSchema(tm.TestCase): +class TestBuildSchema(object): - def setUp(self): + def setup_method(self, method): self.df = DataFrame( {'A': [1, 2, 3, 4], 'B': ['a', 'b', 'c', 'c'], @@ -85,7 +84,7 @@ def test_multiindex(self): assert result == expected -class TestTableSchemaType(tm.TestCase): +class TestTableSchemaType(object): def test_as_json_table_type_int_data(self): int_data = [1, 2, 3] @@ -169,9 +168,9 @@ def test_as_json_table_type_categorical_dtypes(self): assert as_json_table_type(CategoricalDtype()) == 'any' -class TestTableOrient(tm.TestCase): +class TestTableOrient(object): - def setUp(self): + def setup_method(self, method): self.df = DataFrame( {'A': [1, 2, 3, 4], 'B': ['a', 'b', 'c', 'c'], diff --git a/pandas/tests/io/json/test_normalize.py b/pandas/tests/io/json/test_normalize.py index d24250f534521..49b765b18d623 100644 --- a/pandas/tests/io/json/test_normalize.py +++ b/pandas/tests/io/json/test_normalize.py @@ -212,7 +212,7 @@ def test_non_ascii_key(self): tm.assert_frame_equal(result, expected) -class TestNestedToRecord(tm.TestCase): +class TestNestedToRecord(object): def test_flat_stays_flat(self): recs = [dict(flat1=1, flat2=2), diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index 2e92910f82b74..671d4248818e4 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -35,9 +35,9 @@ _mixed_frame = _frame.copy() -class TestPandasContainer(tm.TestCase): +class TestPandasContainer(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.ts = tm.makeTimeSeries() @@ -59,7 +59,7 @@ def setUp(self): self.mixed_frame = _mixed_frame.copy() self.categorical = _cat_frame.copy() - def tearDown(self): + def teardown_method(self, method): del self.dirpath del self.ts diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py index b749cd150d445..86b0e5a0c6a2d 100644 --- a/pandas/tests/io/json/test_ujson.py +++ b/pandas/tests/io/json/test_ujson.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from unittest import TestCase - try: import json except ImportError: @@ -15,7 +13,7 @@ import decimal from functools import partial from pandas.compat import range, zip, StringIO, u -import pandas.io.json.libjson as ujson +import pandas._libs.json as ujson import pandas.compat as compat import numpy as np @@ -27,7 +25,7 @@ else partial(json.dumps, encoding="utf-8")) -class UltraJSONTests(TestCase): +class UltraJSONTests(object): @pytest.mark.skipif(compat.is_platform_32bit(), reason="not compliant on 32-bit, xref #15865") @@ -948,7 +946,7 @@ def my_obj_handler(obj): ujson.decode(ujson.encode(l, default_handler=str))) -class NumpyJSONTests(TestCase): +class NumpyJSONTests(object): def testBool(self): b = np.bool(True) @@ -1224,7 +1222,7 @@ def testArrayNumpyLabelled(self): assert (np.array(['a', 'b']) == output[2]).all() -class PandasJSONTests(TestCase): +class PandasJSONTests(object): def testDataFrame(self): df = DataFrame([[1, 2, 3], [4, 5, 6]], index=[ diff --git a/pandas/tests/io/msgpack/test_limits.py b/pandas/tests/io/msgpack/test_limits.py index e906d14a2b5a8..07044dbb7e5de 100644 --- a/pandas/tests/io/msgpack/test_limits.py +++ b/pandas/tests/io/msgpack/test_limits.py @@ -4,12 +4,10 @@ import pytest -import pandas.util.testing as tm - from pandas.io.msgpack import packb, unpackb, Packer, Unpacker, ExtType -class TestLimits(tm.TestCase): +class TestLimits(object): def test_integer(self): x = -(2 ** 63) diff --git a/pandas/tests/io/msgpack/test_unpack.py b/pandas/tests/io/msgpack/test_unpack.py index 158094d111b54..c056f8d800e11 100644 --- a/pandas/tests/io/msgpack/test_unpack.py +++ b/pandas/tests/io/msgpack/test_unpack.py @@ -1,11 +1,10 @@ from io import BytesIO import sys from pandas.io.msgpack import Unpacker, packb, OutOfData, ExtType -import pandas.util.testing as tm import pytest -class TestUnpack(tm.TestCase): +class TestUnpack(object): def test_unpack_array_header_from_file(self): f = BytesIO(packb([1, 2, 3, 4])) diff --git a/pandas/tests/io/parser/test_network.py b/pandas/tests/io/parser/test_network.py index cabee76dd6dfc..e12945a6a3102 100644 --- a/pandas/tests/io/parser/test_network.py +++ b/pandas/tests/io/parser/test_network.py @@ -47,9 +47,9 @@ def check_compressed_urls(salaries_table, compression, extension, mode, tm.assert_frame_equal(url_table, salaries_table) -class TestS3(tm.TestCase): +class TestS3(object): - def setUp(self): + def setup_method(self, method): try: import s3fs # noqa except ImportError: diff --git a/pandas/tests/io/parser/test_parsers.py b/pandas/tests/io/parser/test_parsers.py index 2ae557a7d57db..8d59e3acb3230 100644 --- a/pandas/tests/io/parser/test_parsers.py +++ b/pandas/tests/io/parser/test_parsers.py @@ -42,7 +42,7 @@ def read_table(self, *args, **kwargs): def float_precision_choices(self): raise AbstractMethodError(self) - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.csv1 = os.path.join(self.dirpath, 'test1.csv') self.csv2 = os.path.join(self.dirpath, 'test2.csv') @@ -50,7 +50,7 @@ def setUp(self): self.csv_shiftjs = os.path.join(self.dirpath, 'sauron.SHIFT_JIS.csv') -class TestCParserHighMemory(BaseParser, CParserTests, tm.TestCase): +class TestCParserHighMemory(BaseParser, CParserTests): engine = 'c' low_memory = False float_precision_choices = [None, 'high', 'round_trip'] @@ -68,7 +68,7 @@ def read_table(self, *args, **kwds): return read_table(*args, **kwds) -class TestCParserLowMemory(BaseParser, CParserTests, tm.TestCase): +class TestCParserLowMemory(BaseParser, CParserTests): engine = 'c' low_memory = True float_precision_choices = [None, 'high', 'round_trip'] @@ -86,7 +86,7 @@ def read_table(self, *args, **kwds): return read_table(*args, **kwds) -class TestPythonParser(BaseParser, PythonParserTests, tm.TestCase): +class TestPythonParser(BaseParser, PythonParserTests): engine = 'python' float_precision_choices = [None] diff --git a/pandas/tests/io/parser/test_read_fwf.py b/pandas/tests/io/parser/test_read_fwf.py index 90231e01d0173..0bfeb5215f370 100644 --- a/pandas/tests/io/parser/test_read_fwf.py +++ b/pandas/tests/io/parser/test_read_fwf.py @@ -19,7 +19,7 @@ from pandas.io.parsers import read_csv, read_fwf, EmptyDataError -class TestFwfParsing(tm.TestCase): +class TestFwfParsing(object): def test_fwf(self): data_expected = """\ diff --git a/pandas/tests/io/parser/test_textreader.py b/pandas/tests/io/parser/test_textreader.py index d8ae66a2b275c..c9088d2ecc5e7 100644 --- a/pandas/tests/io/parser/test_textreader.py +++ b/pandas/tests/io/parser/test_textreader.py @@ -22,13 +22,13 @@ import pandas.util.testing as tm -from pandas.io.libparsers import TextReader -import pandas.io.libparsers as parser +from pandas._libs.parsers import TextReader +import pandas._libs.parsers as parser -class TestTextReader(tm.TestCase): +class TestTextReader(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.csv1 = os.path.join(self.dirpath, 'test1.csv') self.csv2 = os.path.join(self.dirpath, 'test2.csv') diff --git a/pandas/tests/io/parser/test_unsupported.py b/pandas/tests/io/parser/test_unsupported.py index 6c2d883aeb16b..3f62ff44531fb 100644 --- a/pandas/tests/io/parser/test_unsupported.py +++ b/pandas/tests/io/parser/test_unsupported.py @@ -17,7 +17,7 @@ from pandas.io.parsers import read_csv, read_table -class TestUnsupportedFeatures(tm.TestCase): +class TestUnsupportedFeatures(object): def test_mangle_dupe_cols_false(self): # see gh-12935 @@ -102,7 +102,7 @@ def test_python_engine(self): read_csv(StringIO(data), engine=engine, **kwargs) -class TestDeprecatedFeatures(tm.TestCase): +class TestDeprecatedFeatures(object): def test_deprecated_args(self): data = '1,2,3' diff --git a/pandas/tests/io/sas/test_sas.py b/pandas/tests/io/sas/test_sas.py index 461c0fe1fd848..617df99b99f0b 100644 --- a/pandas/tests/io/sas/test_sas.py +++ b/pandas/tests/io/sas/test_sas.py @@ -1,11 +1,10 @@ import pytest -import pandas.util.testing as tm from pandas.compat import StringIO from pandas import read_sas -class TestSas(tm.TestCase): +class TestSas(object): def test_sas_buffer_format(self): diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index afd40e7017cff..a5157744038f4 100644 --- a/pandas/tests/io/sas/test_sas7bdat.py +++ b/pandas/tests/io/sas/test_sas7bdat.py @@ -6,9 +6,9 @@ import numpy as np -class TestSAS7BDAT(tm.TestCase): +class TestSAS7BDAT(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.data = [] self.test_ix = [list(range(1, 16)), [16]] diff --git a/pandas/tests/io/sas/test_xport.py b/pandas/tests/io/sas/test_xport.py index 2ed7ebbbfce32..de31c3e36a8d5 100644 --- a/pandas/tests/io/sas/test_xport.py +++ b/pandas/tests/io/sas/test_xport.py @@ -16,9 +16,9 @@ def numeric_as_float(data): data[v] = data[v].astype(np.float64) -class TestXport(tm.TestCase): +class TestXport(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.file01 = os.path.join(self.dirpath, "DEMO_G.xpt") self.file02 = os.path.join(self.dirpath, "SSHSV1_A.xpt") diff --git a/pandas/tests/io/test_clipboard.py b/pandas/tests/io/test_clipboard.py index 756dd0db8c3b7..940a331a9de84 100644 --- a/pandas/tests/io/test_clipboard.py +++ b/pandas/tests/io/test_clipboard.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import numpy as np from numpy.random import randint +from textwrap import dedent import pytest import pandas as pd @@ -10,7 +11,8 @@ from pandas import get_option from pandas.util import testing as tm from pandas.util.testing import makeCustomDataframe as mkdf -from pandas.util.clipboard.exceptions import PyperclipException +from pandas.io.clipboard.exceptions import PyperclipException +from pandas.io.clipboard import clipboard_set try: @@ -23,11 +25,10 @@ @pytest.mark.single @pytest.mark.skipif(not _DEPS_INSTALLED, reason="clipboard primitives not installed") -class TestClipboard(tm.TestCase): +class TestClipboard(object): @classmethod - def setUpClass(cls): - super(TestClipboard, cls).setUpClass() + def setup_class(cls): cls.data = {} cls.data['string'] = mkdf(5, 3, c_idx_type='s', r_idx_type='i', c_idx_names=[None], r_idx_names=[None]) @@ -62,8 +63,7 @@ def setUpClass(cls): cls.data_types = list(cls.data.keys()) @classmethod - def tearDownClass(cls): - super(TestClipboard, cls).tearDownClass() + def teardown_class(cls): del cls.data_types, cls.data def check_round_trip_frame(self, data_type, excel=None, sep=None, @@ -91,8 +91,6 @@ def test_round_trip_frame(self): self.check_round_trip_frame(dt) def test_read_clipboard_infer_excel(self): - from textwrap import dedent - from pandas.util.clipboard import clipboard_set text = dedent(""" John James Charlie Mingus diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index c427fab4103e0..a1a95e09915f1 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -24,7 +24,7 @@ pass -class TestCommonIOCapabilities(tm.TestCase): +class TestCommonIOCapabilities(object): data1 = """index,A,B,C,D foo,2,3,4,5 bar,7,8,9,10 @@ -90,9 +90,9 @@ def test_iterator(self): tm.assert_frame_equal(concat(it), expected.iloc[1:]) -class TestMMapWrapper(tm.TestCase): +class TestMMapWrapper(object): - def setUp(self): + def setup_method(self, method): self.mmap_file = os.path.join(tm.get_data_path(), 'test_mmap.csv') diff --git a/pandas/tests/io/test_excel.py b/pandas/tests/io/test_excel.py index d733f26b2c04d..c70b5937fea3f 100644 --- a/pandas/tests/io/test_excel.py +++ b/pandas/tests/io/test_excel.py @@ -84,7 +84,7 @@ def _skip_if_no_s3fs(): class SharedItems(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.frame = _frame.copy() self.frame2 = _frame2.copy() @@ -161,9 +161,9 @@ class ReadingTestsBase(SharedItems): # 3. Add a property engine_name, which is the name of the reader class. # For the reader this is not used for anything at the moment. - def setUp(self): + def setup_method(self, method): self.check_skip() - super(ReadingTestsBase, self).setUp() + super(ReadingTestsBase, self).setup_method(method) def test_parse_cols_int(self): @@ -989,19 +989,19 @@ def test_read_excel_squeeze(self): tm.assert_series_equal(actual, expected) -class XlsReaderTests(XlrdTests, tm.TestCase): +class XlsReaderTests(XlrdTests): ext = '.xls' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) -class XlsxReaderTests(XlrdTests, tm.TestCase): +class XlsxReaderTests(XlrdTests): ext = '.xlsx' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) -class XlsmReaderTests(XlrdTests, tm.TestCase): +class XlsmReaderTests(XlrdTests): ext = '.xlsm' engine_name = 'xlrd' check_skip = staticmethod(_skip_if_no_xlrd) @@ -1019,14 +1019,14 @@ class ExcelWriterBase(SharedItems): # Test with MultiIndex and Hierarchical Rows as merged cells. merge_cells = True - def setUp(self): + def setup_method(self, method): self.check_skip() - super(ExcelWriterBase, self).setUp() + super(ExcelWriterBase, self).setup_method(method) self.option_name = 'io.excel.%s.writer' % self.ext.strip('.') self.prev_engine = get_option(self.option_name) set_option(self.option_name, self.engine_name) - def tearDown(self): + def teardown_method(self, method): set_option(self.option_name, self.prev_engine) def test_excel_sheet_by_name_raise(self): @@ -1887,7 +1887,7 @@ def versioned_raise_on_incompat_version(cls): @raise_on_incompat_version(1) -class OpenpyxlTests(ExcelWriterBase, tm.TestCase): +class OpenpyxlTests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl1' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -1923,10 +1923,10 @@ def test_to_excel_styleconverter(self): def skip_openpyxl_gt21(cls): - """Skip a TestCase instance if openpyxl >= 2.2""" + """Skip test case if openpyxl >= 2.2""" @classmethod - def setUpClass(cls): + def setup_class(cls): _skip_if_no_openpyxl() import openpyxl ver = openpyxl.__version__ @@ -1934,13 +1934,13 @@ def setUpClass(cls): LooseVersion(ver) < LooseVersion('2.2.0'))): pytest.skip("openpyxl %s >= 2.2" % str(ver)) - cls.setUpClass = setUpClass + cls.setup_class = setup_class return cls @raise_on_incompat_version(2) @skip_openpyxl_gt21 -class Openpyxl20Tests(ExcelWriterBase, tm.TestCase): +class Openpyxl20Tests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl20' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -2040,23 +2040,23 @@ def test_write_cells_merge_styled(self): def skip_openpyxl_lt22(cls): - """Skip a TestCase instance if openpyxl < 2.2""" + """Skip test case if openpyxl < 2.2""" @classmethod - def setUpClass(cls): + def setup_class(cls): _skip_if_no_openpyxl() import openpyxl ver = openpyxl.__version__ if LooseVersion(ver) < LooseVersion('2.2.0'): pytest.skip("openpyxl %s < 2.2" % str(ver)) - cls.setUpClass = setUpClass + cls.setup_class = setup_class return cls @raise_on_incompat_version(2) @skip_openpyxl_lt22 -class Openpyxl22Tests(ExcelWriterBase, tm.TestCase): +class Openpyxl22Tests(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl22' check_skip = staticmethod(lambda *args, **kwargs: None) @@ -2151,7 +2151,7 @@ def test_write_cells_merge_styled(self): assert xcell_a2.font == openpyxl_sty_merged -class XlwtTests(ExcelWriterBase, tm.TestCase): +class XlwtTests(ExcelWriterBase): ext = '.xls' engine_name = 'xlwt' check_skip = staticmethod(_skip_if_no_xlwt) @@ -2208,7 +2208,7 @@ def test_to_excel_styleconverter(self): assert xlwt.Alignment.VERT_TOP == xls_style.alignment.vert -class XlsxWriterTests(ExcelWriterBase, tm.TestCase): +class XlsxWriterTests(ExcelWriterBase): ext = '.xlsx' engine_name = 'xlsxwriter' check_skip = staticmethod(_skip_if_no_xlsxwriter) @@ -2261,7 +2261,7 @@ def test_column_format(self): assert read_num_format == num_format -class OpenpyxlTests_NoMerge(ExcelWriterBase, tm.TestCase): +class OpenpyxlTests_NoMerge(ExcelWriterBase): ext = '.xlsx' engine_name = 'openpyxl' check_skip = staticmethod(_skip_if_no_openpyxl) @@ -2270,7 +2270,7 @@ class OpenpyxlTests_NoMerge(ExcelWriterBase, tm.TestCase): merge_cells = False -class XlwtTests_NoMerge(ExcelWriterBase, tm.TestCase): +class XlwtTests_NoMerge(ExcelWriterBase): ext = '.xls' engine_name = 'xlwt' check_skip = staticmethod(_skip_if_no_xlwt) @@ -2279,7 +2279,7 @@ class XlwtTests_NoMerge(ExcelWriterBase, tm.TestCase): merge_cells = False -class XlsxWriterTests_NoMerge(ExcelWriterBase, tm.TestCase): +class XlsxWriterTests_NoMerge(ExcelWriterBase): ext = '.xlsx' engine_name = 'xlsxwriter' check_skip = staticmethod(_skip_if_no_xlsxwriter) @@ -2288,7 +2288,7 @@ class XlsxWriterTests_NoMerge(ExcelWriterBase, tm.TestCase): merge_cells = False -class ExcelWriterEngineTests(tm.TestCase): +class ExcelWriterEngineTests(object): def test_ExcelWriter_dispatch(self): with tm.assert_raises_regex(ValueError, 'No engine'): diff --git a/pandas/tests/io/test_gbq.py b/pandas/tests/io/test_gbq.py index 138def3ea1ac9..58a84ad4d47f8 100644 --- a/pandas/tests/io/test_gbq.py +++ b/pandas/tests/io/test_gbq.py @@ -10,7 +10,6 @@ from pandas import compat, DataFrame from pandas.compat import range -import pandas.util.testing as tm pandas_gbq = pytest.importorskip('pandas_gbq') @@ -94,10 +93,10 @@ def make_mixed_dataframe_v2(test_size): @pytest.mark.single -class TestToGBQIntegrationWithServiceAccountKeyPath(tm.TestCase): +class TestToGBQIntegrationWithServiceAccountKeyPath(object): @classmethod - def setUpClass(cls): + def setup_class(cls): # - GLOBAL CLASS FIXTURES - # put here any instruction you want to execute only *ONCE* *BEFORE* # executing *ALL* tests described below. @@ -111,7 +110,7 @@ def setUpClass(cls): ).create(DATASET_ID + "1") @classmethod - def tearDownClass(cls): + def teardown_class(cls): # - GLOBAL CLASS FIXTURES - # put here any instruction you want to execute only *ONCE* *AFTER* # executing all tests. diff --git a/pandas/tests/io/test_html.py b/pandas/tests/io/test_html.py index 0a79173df731c..6da77bf423609 100644 --- a/pandas/tests/io/test_html.py +++ b/pandas/tests/io/test_html.py @@ -23,7 +23,7 @@ is_platform_windows) from pandas.io.common import URLError, urlopen, file_path_to_url from pandas.io.html import read_html -from pandas.io.libparsers import ParserError +from pandas._libs.parsers import ParserError import pandas.util.testing as tm from pandas.util.testing import makeCustomDataframe as mkdf, network @@ -93,14 +93,13 @@ def read_html(self, *args, **kwargs): return read_html(*args, **kwargs) -class TestReadHtml(tm.TestCase, ReadHtmlMixin): +class TestReadHtml(ReadHtmlMixin): flavor = 'bs4' spam_data = os.path.join(DATA_PATH, 'spam.html') banklist_data = os.path.join(DATA_PATH, 'banklist.html') @classmethod - def setUpClass(cls): - super(TestReadHtml, cls).setUpClass() + def setup_class(cls): _skip_if_none_of(('bs4', 'html5lib')) def test_to_html_compat(self): @@ -778,13 +777,12 @@ def _lang_enc(filename): return os.path.splitext(os.path.basename(filename))[0].split('_') -class TestReadHtmlEncoding(tm.TestCase): +class TestReadHtmlEncoding(object): files = glob.glob(os.path.join(DATA_PATH, 'html_encoding', '*.html')) flavor = 'bs4' @classmethod - def setUpClass(cls): - super(TestReadHtmlEncoding, cls).setUpClass() + def setup_class(cls): _skip_if_none_of((cls.flavor, 'html5lib')) def read_html(self, *args, **kwargs): @@ -825,17 +823,16 @@ class TestReadHtmlEncodingLxml(TestReadHtmlEncoding): flavor = 'lxml' @classmethod - def setUpClass(cls): - super(TestReadHtmlEncodingLxml, cls).setUpClass() + def setup_class(cls): + super(TestReadHtmlEncodingLxml, cls).setup_class() _skip_if_no(cls.flavor) -class TestReadHtmlLxml(tm.TestCase, ReadHtmlMixin): +class TestReadHtmlLxml(ReadHtmlMixin): flavor = 'lxml' @classmethod - def setUpClass(cls): - super(TestReadHtmlLxml, cls).setUpClass() + def setup_class(cls): _skip_if_no('lxml') def test_data_fail(self): diff --git a/pandas/tests/io/test_packers.py b/pandas/tests/io/test_packers.py index 451cce125e228..4b1145129c364 100644 --- a/pandas/tests/io/test_packers.py +++ b/pandas/tests/io/test_packers.py @@ -90,12 +90,12 @@ def check_arbitrary(a, b): assert(a == b) -class TestPackers(tm.TestCase): +class TestPackers(object): - def setUp(self): + def setup_method(self, method): self.path = '__%s__.msg' % tm.rands(10) - def tearDown(self): + def teardown_method(self, method): pass def encode_decode(self, x, compress=None, **kwargs): @@ -301,8 +301,8 @@ def test_timedeltas(self): class TestIndex(TestPackers): - def setUp(self): - super(TestIndex, self).setUp() + def setup_method(self, method): + super(TestIndex, self).setup_method(method) self.d = { 'string': tm.makeStringIndex(100), @@ -364,8 +364,8 @@ def categorical_index(self): class TestSeries(TestPackers): - def setUp(self): - super(TestSeries, self).setUp() + def setup_method(self, method): + super(TestSeries, self).setup_method(method) self.d = {} @@ -412,8 +412,8 @@ def test_basic(self): class TestCategorical(TestPackers): - def setUp(self): - super(TestCategorical, self).setUp() + def setup_method(self, method): + super(TestCategorical, self).setup_method(method) self.d = {} @@ -435,8 +435,8 @@ def test_basic(self): class TestNDFrame(TestPackers): - def setUp(self): - super(TestNDFrame, self).setUp() + def setup_method(self, method): + super(TestNDFrame, self).setup_method(method) data = { 'A': [0., 1., 2., 3., np.nan], @@ -579,7 +579,7 @@ class TestCompression(TestPackers): """See https://github.com/pandas-dev/pandas/pull/9783 """ - def setUp(self): + def setup_method(self, method): try: from sqlalchemy import create_engine self._create_sql_engine = create_engine @@ -588,7 +588,7 @@ def setUp(self): else: self._SQLALCHEMY_INSTALLED = True - super(TestCompression, self).setUp() + super(TestCompression, self).setup_method(method) data = { 'A': np.arange(1000, dtype=np.float64), 'B': np.arange(1000, dtype=np.int32), @@ -773,8 +773,8 @@ def test_readonly_axis_zlib_to_sql(self): class TestEncoding(TestPackers): - def setUp(self): - super(TestEncoding, self).setUp() + def setup_method(self, method): + super(TestEncoding, self).setup_method(method) data = { 'A': [compat.u('\u2019')] * 1000, 'B': np.arange(1000, dtype=np.int32), diff --git a/pandas/tests/io/test_pytables.py b/pandas/tests/io/test_pytables.py index a268fa96175cf..ee44fea55e51a 100644 --- a/pandas/tests/io/test_pytables.py +++ b/pandas/tests/io/test_pytables.py @@ -121,31 +121,29 @@ def _maybe_remove(store, key): pass -class Base(tm.TestCase): +class Base(object): @classmethod - def setUpClass(cls): - super(Base, cls).setUpClass() + def setup_class(cls): # Pytables 3.0.0 deprecates lots of things tm.reset_testing_mode() @classmethod - def tearDownClass(cls): - super(Base, cls).tearDownClass() + def teardown_class(cls): # Pytables 3.0.0 deprecates lots of things tm.set_testing_mode() - def setUp(self): + def setup_method(self, method): self.path = 'tmp.__%s__.h5' % tm.rands(10) - def tearDown(self): + def teardown_method(self, method): pass @pytest.mark.single -class TestHDFStore(Base, tm.TestCase): +class TestHDFStore(Base): def test_factory_fun(self): path = create_tempfile(self.path) @@ -5228,7 +5226,7 @@ def test_complex_append(self): assert_frame_equal(pd.concat([df, df], 0), result) -class TestTimezones(Base, tm.TestCase): +class TestTimezones(Base): def _compare_with_tz(self, a, b): tm.assert_frame_equal(a, b) diff --git a/pandas/tests/io/test_s3.py b/pandas/tests/io/test_s3.py index 36a0304bddfaf..8c2a32af33765 100644 --- a/pandas/tests/io/test_s3.py +++ b/pandas/tests/io/test_s3.py @@ -1,9 +1,7 @@ -from pandas.util import testing as tm - from pandas.io.common import _is_s3_url -class TestS3URL(tm.TestCase): +class TestS3URL(object): def test_is_s3_url(self): assert _is_s3_url("s3://pandas/somethingelse.com") diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 52883a41b08c2..7b3717281bf89 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -20,7 +20,6 @@ from __future__ import print_function from warnings import catch_warnings import pytest -import unittest import sqlite3 import csv import os @@ -179,7 +178,7 @@ class MixInBase(object): - def tearDown(self): + def teardown_method(self, method): for tbl in self._get_all_tables(): self.drop_table(tbl) self._close_conn() @@ -498,7 +497,7 @@ class _TestSQLApi(PandasSQLTest): flavor = 'sqlite' mode = None - def setUp(self): + def setup_method(self, method): self.conn = self.connect() self._load_iris_data() self._load_iris_view() @@ -819,7 +818,7 @@ def test_unicode_column_name(self): @pytest.mark.single -class TestSQLApi(SQLAlchemyMixIn, _TestSQLApi, unittest.TestCase): +class TestSQLApi(SQLAlchemyMixIn, _TestSQLApi): """ Test the public API as it would be used directly @@ -981,8 +980,8 @@ class _EngineToConnMixin(object): A mixin that causes setup_connect to create a conn rather than an engine. """ - def setUp(self): - super(_EngineToConnMixin, self).setUp() + def setup_method(self, method): + super(_EngineToConnMixin, self).setup_method(method) engine = self.conn conn = engine.connect() self.__tx = conn.begin() @@ -990,21 +989,21 @@ def setUp(self): self.__engine = engine self.conn = conn - def tearDown(self): + def teardown_method(self, method): self.__tx.rollback() self.conn.close() self.conn = self.__engine self.pandasSQL = sql.SQLDatabase(self.__engine) - super(_EngineToConnMixin, self).tearDown() + super(_EngineToConnMixin, self).teardown_method(method) @pytest.mark.single -class TestSQLApiConn(_EngineToConnMixin, TestSQLApi, unittest.TestCase): +class TestSQLApiConn(_EngineToConnMixin, TestSQLApi): pass @pytest.mark.single -class TestSQLiteFallbackApi(SQLiteMixIn, _TestSQLApi, unittest.TestCase): +class TestSQLiteFallbackApi(SQLiteMixIn, _TestSQLApi): """ Test the public sqlite connection fallback API @@ -1093,7 +1092,7 @@ class _TestSQLAlchemy(SQLAlchemyMixIn, PandasSQLTest): flavor = None @classmethod - def setUpClass(cls): + def setup_class(cls): cls.setup_import() cls.setup_driver() @@ -1105,7 +1104,7 @@ def setUpClass(cls): msg = "{0} - can't connect to {1} server".format(cls, cls.flavor) pytest.skip(msg) - def setUp(self): + def setup_method(self, method): self.setup_connect() self._load_iris_data() @@ -1822,37 +1821,32 @@ def test_schema_support(self): @pytest.mark.single -class TestMySQLAlchemy(_TestMySQLAlchemy, _TestSQLAlchemy, unittest.TestCase): +class TestMySQLAlchemy(_TestMySQLAlchemy, _TestSQLAlchemy): pass @pytest.mark.single -class TestMySQLAlchemyConn(_TestMySQLAlchemy, _TestSQLAlchemyConn, - unittest.TestCase): +class TestMySQLAlchemyConn(_TestMySQLAlchemy, _TestSQLAlchemyConn): pass @pytest.mark.single -class TestPostgreSQLAlchemy(_TestPostgreSQLAlchemy, _TestSQLAlchemy, - unittest.TestCase): +class TestPostgreSQLAlchemy(_TestPostgreSQLAlchemy, _TestSQLAlchemy): pass @pytest.mark.single -class TestPostgreSQLAlchemyConn(_TestPostgreSQLAlchemy, _TestSQLAlchemyConn, - unittest.TestCase): +class TestPostgreSQLAlchemyConn(_TestPostgreSQLAlchemy, _TestSQLAlchemyConn): pass @pytest.mark.single -class TestSQLiteAlchemy(_TestSQLiteAlchemy, _TestSQLAlchemy, - unittest.TestCase): +class TestSQLiteAlchemy(_TestSQLiteAlchemy, _TestSQLAlchemy): pass @pytest.mark.single -class TestSQLiteAlchemyConn(_TestSQLiteAlchemy, _TestSQLAlchemyConn, - unittest.TestCase): +class TestSQLiteAlchemyConn(_TestSQLiteAlchemy, _TestSQLAlchemyConn): pass @@ -1860,7 +1854,7 @@ class TestSQLiteAlchemyConn(_TestSQLiteAlchemy, _TestSQLAlchemyConn, # -- Test Sqlite / MySQL fallback @pytest.mark.single -class TestSQLiteFallback(SQLiteMixIn, PandasSQLTest, unittest.TestCase): +class TestSQLiteFallback(SQLiteMixIn, PandasSQLTest): """ Test the fallback mode against an in-memory sqlite database. @@ -1871,7 +1865,7 @@ class TestSQLiteFallback(SQLiteMixIn, PandasSQLTest, unittest.TestCase): def connect(cls): return sqlite3.connect(':memory:') - def setUp(self): + def setup_method(self, method): self.conn = self.connect() self.pandasSQL = sql.SQLiteDatabase(self.conn) @@ -2084,9 +2078,10 @@ def _skip_if_no_pymysql(): @pytest.mark.single -class TestXSQLite(SQLiteMixIn, tm.TestCase): +class TestXSQLite(SQLiteMixIn): - def setUp(self): + def setup_method(self, method): + self.method = method self.conn = sqlite3.connect(':memory:') def test_basic(self): @@ -2186,7 +2181,7 @@ def test_execute_closed_connection(self): tquery("select * from test", con=self.conn) # Initialize connection again (needed for tearDown) - self.setUp() + self.setup_method(self.method) def test_na_roundtrip(self): pass @@ -2287,7 +2282,7 @@ def clean_up(test_table_to_drop): @pytest.mark.single -class TestSQLFlavorDeprecation(tm.TestCase): +class TestSQLFlavorDeprecation(object): """ gh-13611: test that the 'flavor' parameter is appropriately deprecated by checking the @@ -2314,10 +2309,10 @@ def test_deprecated_flavor(self): @pytest.mark.single @pytest.mark.skip(reason="gh-13611: there is no support for MySQL " "if SQLAlchemy is not installed") -class TestXMySQL(MySQLMixIn, tm.TestCase): +class TestXMySQL(MySQLMixIn): @classmethod - def setUpClass(cls): + def setup_class(cls): _skip_if_no_pymysql() # test connection @@ -2345,7 +2340,7 @@ def setUpClass(cls): "[pandas] in your system's mysql default file, " "typically located at ~/.my.cnf or /etc/.my.cnf. ") - def setUp(self): + def setup_method(self, method): _skip_if_no_pymysql() import pymysql try: @@ -2371,6 +2366,8 @@ def setUp(self): "[pandas] in your system's mysql default file, " "typically located at ~/.my.cnf or /etc/.my.cnf. ") + self.method = method + def test_basic(self): _skip_if_no_pymysql() frame = tm.makeTimeDataFrame() @@ -2498,7 +2495,7 @@ def test_execute_closed_connection(self): tquery("select * from test", con=self.conn) # Initialize connection again (needed for tearDown) - self.setUp() + self.setup_method(self.method) def test_na_roundtrip(self): _skip_if_no_pymysql() diff --git a/pandas/tests/io/test_stata.py b/pandas/tests/io/test_stata.py index 945f0b009a9da..4c92c19c51e7a 100644 --- a/pandas/tests/io/test_stata.py +++ b/pandas/tests/io/test_stata.py @@ -23,9 +23,9 @@ from pandas.core.dtypes.common import is_categorical_dtype -class TestStata(tm.TestCase): +class TestStata(object): - def setUp(self): + def setup_method(self, method): self.dirpath = tm.get_data_path() self.dta1_114 = os.path.join(self.dirpath, 'stata1_114.dta') self.dta1_117 = os.path.join(self.dirpath, 'stata1_117.dta') diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index 2c0ac974e9e43..1dbba676e4bc5 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -7,7 +7,7 @@ from pandas import DataFrame, Series from pandas.compat import zip, iteritems -from pandas.util.decorators import cache_readonly +from pandas.util._decorators import cache_readonly from pandas.core.dtypes.api import is_list_like import pandas.util.testing as tm from pandas.util.testing import (ensure_clean, @@ -19,11 +19,12 @@ import pandas.plotting as plotting from pandas.plotting._tools import _flatten - """ This is a common base class used for various plotting tests """ +tm._skip_module_if_no_mpl() + def _skip_if_no_scipy_gaussian_kde(): try: @@ -41,10 +42,9 @@ def _ok_for_gaussian_kde(kind): return True -@tm.mplskip -class TestPlotBase(tm.TestCase): +class TestPlotBase(object): - def setUp(self): + def setup_method(self, method): import matplotlib as mpl mpl.rcdefaults() @@ -95,7 +95,7 @@ def setUp(self): "C": np.arange(20) + np.random.uniform( size=20)}) - def tearDown(self): + def teardown_method(self, method): tm.close() @cache_readonly diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 1f70d408767f3..1e06c13980657 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -21,6 +21,8 @@ """ Test cases for .boxplot method """ +tm._skip_module_if_no_mpl() + def _skip_if_mpl_14_or_dev_boxplot(): # GH 8382 @@ -31,7 +33,6 @@ def _skip_if_mpl_14_or_dev_boxplot(): pytest.skip("Matplotlib Regression in 1.4 and current dev.") -@tm.mplskip class TestDataFramePlots(TestPlotBase): @slow @@ -165,7 +166,6 @@ def test_fontsize(self): xlabelsize=16, ylabelsize=16) -@tm.mplskip class TestDataFrameGroupByPlots(TestPlotBase): @slow diff --git a/pandas/tests/plotting/test_converter.py b/pandas/tests/plotting/test_converter.py index e23bc2ef6c563..e1f64bed5598d 100644 --- a/pandas/tests/plotting/test_converter.py +++ b/pandas/tests/plotting/test_converter.py @@ -15,9 +15,9 @@ def test_timtetonum_accepts_unicode(): assert (converter.time2num("00:01") == converter.time2num(u("00:01"))) -class TestDateTimeConverter(tm.TestCase): +class TestDateTimeConverter(object): - def setUp(self): + def setup_method(self, method): self.dtc = converter.DatetimeConverter() self.tc = converter.TimeFormatter(None) @@ -146,9 +146,9 @@ def test_convert_nested(self): assert result == expected -class TestPeriodConverter(tm.TestCase): +class TestPeriodConverter(object): - def setUp(self): + def setup_method(self, method): self.pc = converter.PeriodConverter() class Axis(object): diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index ae8faa031174e..ed198de11bac1 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -20,12 +20,13 @@ from pandas.tests.plotting.common import (TestPlotBase, _skip_if_no_scipy_gaussian_kde) +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestTSPlot(TestPlotBase): - def setUp(self): - TestPlotBase.setUp(self) + def setup_method(self, method): + TestPlotBase.setup_method(self, method) freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q', 'A'] idx = [period_range('12/31/1999', freq=x, periods=100) for x in freq] @@ -41,7 +42,7 @@ def setUp(self): columns=['A', 'B', 'C']) for x in idx] - def tearDown(self): + def teardown_method(self, method): tm.close() @slow diff --git a/pandas/tests/plotting/test_deprecated.py b/pandas/tests/plotting/test_deprecated.py index d7eaa69460a3a..48030df48deca 100644 --- a/pandas/tests/plotting/test_deprecated.py +++ b/pandas/tests/plotting/test_deprecated.py @@ -18,8 +18,9 @@ pandas.tools.plotting """ +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestDeprecatedNameSpace(TestPlotBase): @slow diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index 03bc477d6f852..4a4a71d7ea639 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -27,12 +27,13 @@ _skip_if_no_scipy_gaussian_kde, _ok_for_gaussian_kde) +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestDataFramePlots(TestPlotBase): - def setUp(self): - TestPlotBase.setUp(self) + def setup_method(self, method): + TestPlotBase.setup_method(self, method) import matplotlib as mpl mpl.rcdefaults() diff --git a/pandas/tests/plotting/test_groupby.py b/pandas/tests/plotting/test_groupby.py index 121f2f9b75698..8dcf73bce03c0 100644 --- a/pandas/tests/plotting/test_groupby.py +++ b/pandas/tests/plotting/test_groupby.py @@ -10,8 +10,9 @@ from pandas.tests.plotting.common import TestPlotBase +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestDataFrameGroupByPlots(TestPlotBase): def test_series_groupby_plotting_nominally_works(self): diff --git a/pandas/tests/plotting/test_hist_method.py b/pandas/tests/plotting/test_hist_method.py index b75fcd4d8b680..c3e32f52e0474 100644 --- a/pandas/tests/plotting/test_hist_method.py +++ b/pandas/tests/plotting/test_hist_method.py @@ -15,11 +15,13 @@ from pandas.tests.plotting.common import (TestPlotBase, _check_plot_works) -@tm.mplskip +tm._skip_module_if_no_mpl() + + class TestSeriesPlots(TestPlotBase): - def setUp(self): - TestPlotBase.setUp(self) + def setup_method(self, method): + TestPlotBase.setup_method(self, method) import matplotlib as mpl mpl.rcdefaults() @@ -140,7 +142,6 @@ def test_plot_fails_when_ax_differs_from_figure(self): self.ts.hist(ax=ax1, figure=fig2) -@tm.mplskip class TestDataFramePlots(TestPlotBase): @slow @@ -251,7 +252,6 @@ def test_tight_layout(self): tm.close() -@tm.mplskip class TestDataFrameGroupByPlots(TestPlotBase): @slow diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index 3a9cb309db707..9eace32aa19a3 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -17,12 +17,13 @@ from pandas.tests.plotting.common import (TestPlotBase, _check_plot_works, _ok_for_gaussian_kde) +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestSeriesPlots(TestPlotBase): - def setUp(self): - TestPlotBase.setUp(self) + def setup_method(self, method): + TestPlotBase.setup_method(self, method) import matplotlib as mpl mpl.rcdefaults() @@ -50,7 +51,6 @@ def test_bootstrap_plot(self): _check_plot_works(bootstrap_plot, series=self.ts, size=10) -@tm.mplskip class TestDataFramePlots(TestPlotBase): @slow diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 91a27142069c7..448661c7af0e9 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -22,12 +22,13 @@ _skip_if_no_scipy_gaussian_kde, _ok_for_gaussian_kde) +tm._skip_module_if_no_mpl() + -@tm.mplskip class TestSeriesPlots(TestPlotBase): - def setUp(self): - TestPlotBase.setUp(self) + def setup_method(self, method): + TestPlotBase.setup_method(self, method) import matplotlib as mpl mpl.rcdefaults() diff --git a/pandas/tests/reshape/test_concat.py b/pandas/tests/reshape/test_concat.py index 2d4d0a09060de..4dfa2904313ce 100644 --- a/pandas/tests/reshape/test_concat.py +++ b/pandas/tests/reshape/test_concat.py @@ -17,9 +17,9 @@ import pytest -class ConcatenateBase(tm.TestCase): +class ConcatenateBase(object): - def setUp(self): + def setup_method(self, method): self.frame = DataFrame(tm.getSeriesData()) self.mixed_frame = self.frame.copy() self.mixed_frame['foo'] = 'bar' @@ -31,7 +31,7 @@ class TestConcatAppendCommon(ConcatenateBase): Test common dtype coercion rules between concat and append. """ - def setUp(self): + def setup_method(self, method): dt_data = [pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), diff --git a/pandas/tests/reshape/test_join.py b/pandas/tests/reshape/test_join.py index cda343175fd0a..e25661fb65271 100644 --- a/pandas/tests/reshape/test_join.py +++ b/pandas/tests/reshape/test_join.py @@ -19,9 +19,9 @@ a_ = np.array -class TestJoin(tm.TestCase): +class TestJoin(object): - def setUp(self): + def setup_method(self, method): # aggregate multiple columns self.df = DataFrame({'key1': get_test_data(), 'key2': get_test_data(), diff --git a/pandas/tests/reshape/test_merge.py b/pandas/tests/reshape/test_merge.py index db0e4631381f1..d3257243d7a2c 100644 --- a/pandas/tests/reshape/test_merge.py +++ b/pandas/tests/reshape/test_merge.py @@ -33,9 +33,9 @@ def get_test_data(ngroups=NGROUPS, n=N): return arr -class TestMerge(tm.TestCase): +class TestMerge(object): - def setUp(self): + def setup_method(self, method): # aggregate multiple columns self.df = DataFrame({'key1': get_test_data(), 'key2': get_test_data(), @@ -737,9 +737,9 @@ def _check_merge(x, y): assert_frame_equal(result, expected, check_names=False) -class TestMergeMulti(tm.TestCase): +class TestMergeMulti(object): - def setUp(self): + def setup_method(self, method): self.index = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'], ['one', 'two', 'three']], labels=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3], diff --git a/pandas/tests/reshape/test_merge_asof.py b/pandas/tests/reshape/test_merge_asof.py index 7934b8abf85a8..78bfa2ff8597c 100644 --- a/pandas/tests/reshape/test_merge_asof.py +++ b/pandas/tests/reshape/test_merge_asof.py @@ -11,7 +11,7 @@ from pandas.util.testing import assert_frame_equal -class TestAsOfMerge(tm.TestCase): +class TestAsOfMerge(object): def read_data(self, name, dedupe=False): path = os.path.join(tm.get_data_path(), name) @@ -23,7 +23,7 @@ def read_data(self, name, dedupe=False): x.time = to_datetime(x.time) return x - def setUp(self): + def setup_method(self, method): self.trades = self.read_data('trades.csv') self.quotes = self.read_data('quotes.csv', dedupe=True) diff --git a/pandas/tests/reshape/test_merge_ordered.py b/pandas/tests/reshape/test_merge_ordered.py index 1f1eee0e9980b..9469e98f336fd 100644 --- a/pandas/tests/reshape/test_merge_ordered.py +++ b/pandas/tests/reshape/test_merge_ordered.py @@ -6,9 +6,9 @@ from numpy import nan -class TestOrderedMerge(tm.TestCase): +class TestOrderedMerge(object): - def setUp(self): + def setup_method(self, method): self.left = DataFrame({'key': ['a', 'c', 'e'], 'lvalue': [1, 2., 3]}) diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index df679966e0002..270a93e4ae382 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -15,9 +15,9 @@ from pandas.tseries.util import pivot_annual, isleapyear -class TestPivotTable(tm.TestCase): +class TestPivotTable(object): - def setUp(self): + def setup_method(self, method): self.data = DataFrame({'A': ['foo', 'foo', 'foo', 'foo', 'bar', 'bar', 'bar', 'bar', 'foo', 'foo', 'foo'], @@ -982,9 +982,9 @@ def test_pivot_table_not_series(self): tm.assert_frame_equal(result, expected) -class TestCrosstab(tm.TestCase): +class TestCrosstab(object): - def setUp(self): + def setup_method(self, method): df = DataFrame({'A': ['foo', 'foo', 'foo', 'foo', 'bar', 'bar', 'bar', 'bar', 'foo', 'foo', 'foo'], @@ -1397,7 +1397,7 @@ def test_crosstab_with_numpy_size(self): tm.assert_frame_equal(result, expected) -class TestPivotAnnual(tm.TestCase): +class TestPivotAnnual(object): """ New pandas of scikits.timeseries pivot_annual """ diff --git a/pandas/tests/reshape/test_reshape.py b/pandas/tests/reshape/test_reshape.py index 87cd0637f1125..79626d89026a7 100644 --- a/pandas/tests/reshape/test_reshape.py +++ b/pandas/tests/reshape/test_reshape.py @@ -17,9 +17,9 @@ from pandas.compat import range, u -class TestMelt(tm.TestCase): +class TestMelt(object): - def setUp(self): + def setup_method(self, method): self.df = tm.makeTimeDataFrame()[:10] self.df['id1'] = (self.df['A'] > 0).astype(np.int64) self.df['id2'] = (self.df['B'] > 0).astype(np.int64) @@ -216,11 +216,11 @@ def test_multiindex(self): assert res.columns.tolist() == ['CAP', 'low', 'value'] -class TestGetDummies(tm.TestCase): +class TestGetDummies(object): sparse = False - def setUp(self): + def setup_method(self, method): self.df = DataFrame({'A': ['a', 'b', 'a'], 'B': ['b', 'b', 'c'], 'C': [1, 2, 3]}) @@ -644,7 +644,7 @@ class TestGetDummiesSparse(TestGetDummies): sparse = True -class TestMakeAxisDummies(tm.TestCase): +class TestMakeAxisDummies(object): def test_preserve_categorical_dtype(self): # GH13854 @@ -665,7 +665,7 @@ def test_preserve_categorical_dtype(self): tm.assert_frame_equal(result, expected) -class TestLreshape(tm.TestCase): +class TestLreshape(object): def test_pairs(self): data = {'birthdt': ['08jan2009', '20dec2008', '30dec2008', '21dec2008', @@ -737,7 +737,7 @@ def test_pairs(self): pytest.raises(ValueError, lreshape, df, spec) -class TestWideToLong(tm.TestCase): +class TestWideToLong(object): def test_simple(self): np.random.seed(123) diff --git a/pandas/tests/reshape/test_tile.py b/pandas/tests/reshape/test_tile.py index 2291030a2735c..8602b33856fea 100644 --- a/pandas/tests/reshape/test_tile.py +++ b/pandas/tests/reshape/test_tile.py @@ -14,7 +14,7 @@ import pandas.core.reshape.tile as tmod -class TestCut(tm.TestCase): +class TestCut(object): def test_simple(self): data = np.ones(5, dtype='int64') diff --git a/pandas/tests/reshape/test_union_categoricals.py b/pandas/tests/reshape/test_union_categoricals.py index 5cc476718add2..fe8d54005ba9b 100644 --- a/pandas/tests/reshape/test_union_categoricals.py +++ b/pandas/tests/reshape/test_union_categoricals.py @@ -7,7 +7,7 @@ from pandas.util import testing as tm -class TestUnionCategoricals(tm.TestCase): +class TestUnionCategoricals(object): def test_union_categorical(self): # GH 13361 diff --git a/pandas/tests/reshape/test_util.py b/pandas/tests/reshape/test_util.py index a7fbe8d305011..e4a9591b95c26 100644 --- a/pandas/tests/reshape/test_util.py +++ b/pandas/tests/reshape/test_util.py @@ -5,7 +5,7 @@ from pandas.core.reshape.util import cartesian_product -class TestCartesianProduct(tm.TestCase): +class TestCartesianProduct(object): def test_simple(self): x, y = list('ABC'), [1, 22] diff --git a/pandas/tests/scalar/test_interval.py b/pandas/tests/scalar/test_interval.py index 079c41657bec6..e06f7cb34eb52 100644 --- a/pandas/tests/scalar/test_interval.py +++ b/pandas/tests/scalar/test_interval.py @@ -5,8 +5,8 @@ import pandas.util.testing as tm -class TestInterval(tm.TestCase): - def setUp(self): +class TestInterval(object): + def setup_method(self, method): self.interval = Interval(0, 1) def test_properties(self): diff --git a/pandas/tests/scalar/test_period.py b/pandas/tests/scalar/test_period.py index 2e60cfdb7a4f2..54366dc9b1c3f 100644 --- a/pandas/tests/scalar/test_period.py +++ b/pandas/tests/scalar/test_period.py @@ -14,7 +14,7 @@ from pandas.tseries.frequencies import DAYS, MONTHS -class TestPeriodProperties(tm.TestCase): +class TestPeriodProperties(object): "Test properties such as year, month, weekday, etc...." def test_is_leap_year(self): @@ -911,7 +911,7 @@ def test_round_trip(self): assert new_p == p -class TestPeriodField(tm.TestCase): +class TestPeriodField(object): def test_get_period_field_raises_on_out_of_range(self): pytest.raises(ValueError, libperiod.get_period_field, -1, 0, 0) @@ -921,9 +921,9 @@ def test_get_period_field_array_raises_on_out_of_range(self): np.empty(1), 0) -class TestComparisons(tm.TestCase): +class TestComparisons(object): - def setUp(self): + def setup_method(self, method): self.january1 = Period('2000-01', 'M') self.january2 = Period('2000-01', 'M') self.february = Period('2000-02', 'M') @@ -1006,7 +1006,7 @@ def test_period_nat_comp(self): assert not left >= right -class TestMethods(tm.TestCase): +class TestMethods(object): def test_add(self): dt1 = Period(freq='D', year=2008, month=1, day=1) diff --git a/pandas/tests/scalar/test_period_asfreq.py b/pandas/tests/scalar/test_period_asfreq.py index 7011cfeef90ae..32cea60c333b7 100644 --- a/pandas/tests/scalar/test_period_asfreq.py +++ b/pandas/tests/scalar/test_period_asfreq.py @@ -4,7 +4,7 @@ from pandas.tseries.frequencies import _period_code_map -class TestFreqConversion(tm.TestCase): +class TestFreqConversion(object): """Test frequency conversion of date objects""" def test_asfreq_corner(self): diff --git a/pandas/tests/scalar/test_timedelta.py b/pandas/tests/scalar/test_timedelta.py index 5659bc26fc1cc..ecc44204924d3 100644 --- a/pandas/tests/scalar/test_timedelta.py +++ b/pandas/tests/scalar/test_timedelta.py @@ -12,10 +12,10 @@ from pandas._libs.tslib import iNaT, NaTType -class TestTimedeltas(tm.TestCase): +class TestTimedeltas(object): _multiprocess_can_split_ = True - def setUp(self): + def setup_method(self, method): pass def test_construction(self): diff --git a/pandas/tests/scalar/test_timestamp.py b/pandas/tests/scalar/test_timestamp.py index 04b33bbc6c3bf..5caa0252b69b8 100644 --- a/pandas/tests/scalar/test_timestamp.py +++ b/pandas/tests/scalar/test_timestamp.py @@ -22,7 +22,7 @@ RESO_MS, RESO_SEC) -class TestTimestamp(tm.TestCase): +class TestTimestamp(object): def test_constructor(self): base_str = '2014-07-01 09:00' @@ -1094,9 +1094,9 @@ def test_is_leap_year(self): assert not dt.is_leap_year -class TestTimestampNsOperations(tm.TestCase): +class TestTimestampNsOperations(object): - def setUp(self): + def setup_method(self, method): self.timestamp = Timestamp(datetime.utcnow()) def assert_ns_timedelta(self, modified_timestamp, expected_value): @@ -1181,7 +1181,7 @@ def test_nanosecond_timestamp(self): assert t.nanosecond == 10 -class TestTimestampOps(tm.TestCase): +class TestTimestampOps(object): def test_timestamp_and_datetime(self): assert ((Timestamp(datetime(2013, 10, 13)) - @@ -1256,7 +1256,7 @@ def test_resolution(self): assert result == expected -class TestTimestampToJulianDate(tm.TestCase): +class TestTimestampToJulianDate(object): def test_compare_1700(self): r = Timestamp('1700-06-23').to_julian_date() @@ -1279,7 +1279,7 @@ def test_compare_hour13(self): assert r == 2451769.0416666666666666 -class TestTimeSeries(tm.TestCase): +class TestTimeSeries(object): def test_timestamp_to_datetime(self): tm._skip_if_no_pytz() @@ -1490,7 +1490,7 @@ def test_woy_boundary(self): assert (result == [52, 52, 53, 53]).all() -class TestTsUtil(tm.TestCase): +class TestTsUtil(object): def test_min_valid(self): # Ensure that Timestamp.min is a valid Timestamp diff --git a/pandas/tests/series/common.py b/pandas/tests/series/common.py index 613961e1c670f..0c25dcb29c3b2 100644 --- a/pandas/tests/series/common.py +++ b/pandas/tests/series/common.py @@ -1,4 +1,4 @@ -from pandas.util.decorators import cache_readonly +from pandas.util._decorators import cache_readonly import pandas.util.testing as tm import pandas as pd diff --git a/pandas/tests/series/test_alter_axes.py b/pandas/tests/series/test_alter_axes.py index 33a4cdb6e26c4..150767ee9e2b2 100644 --- a/pandas/tests/series/test_alter_axes.py +++ b/pandas/tests/series/test_alter_axes.py @@ -18,7 +18,7 @@ from .common import TestData -class TestSeriesAlterAxes(TestData, tm.TestCase): +class TestSeriesAlterAxes(TestData): def test_setindex(self): # wrong type diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index 71131452393a7..ec6a118ec3639 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -19,7 +19,7 @@ import pandas.core.nanops as nanops -from pandas.compat import lrange, range +from pandas.compat import lrange, range, is_platform_windows from pandas import compat from pandas.util.testing import (assert_series_equal, assert_almost_equal, assert_frame_equal, assert_index_equal) @@ -28,7 +28,11 @@ from .common import TestData -class TestSeriesAnalytics(TestData, tm.TestCase): +skip_if_bottleneck_on_windows = (is_platform_windows() and + nanops._USE_BOTTLENECK) + + +class TestSeriesAnalytics(TestData): def test_sum_zero(self): arr = np.array([]) @@ -64,14 +68,6 @@ def test_overflow(self): result = s.max(skipna=False) assert int(result) == v[-1] - # use bottleneck if available - result = s.sum() - assert int(result) == v.sum(dtype='int64') - result = s.min() - assert int(result) == 0 - result = s.max() - assert int(result) == v[-1] - for dtype in ['float32', 'float64']: v = np.arange(5000000, dtype=dtype) s = Series(v) @@ -84,6 +80,28 @@ def test_overflow(self): result = s.max(skipna=False) assert np.allclose(float(result), v[-1]) + @pytest.mark.xfail( + skip_if_bottleneck_on_windows, + reason="buggy bottleneck with sum overflow on windows") + def test_overflow_with_bottleneck(self): + # GH 6915 + # overflowing on the smaller int dtypes + for dtype in ['int32', 'int64']: + v = np.arange(5000000, dtype=dtype) + s = Series(v) + + # use bottleneck if available + result = s.sum() + assert int(result) == v.sum(dtype='int64') + result = s.min() + assert int(result) == 0 + result = s.max() + assert int(result) == v[-1] + + for dtype in ['float32', 'float64']: + v = np.arange(5000000, dtype=dtype) + s = Series(v) + # use bottleneck if available result = s.sum() assert result == v.sum(dtype=dtype) @@ -92,6 +110,9 @@ def test_overflow(self): result = s.max() assert np.allclose(float(result), v[-1]) + @pytest.mark.xfail( + skip_if_bottleneck_on_windows, + reason="buggy bottleneck with sum overflow on windows") def test_sum(self): self._check_stat_op('sum', np.sum, check_allna=True) diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 5bb463c7a2ebe..1eb2b98a7d7cc 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -118,7 +118,7 @@ def test_to_sparse_pass_name(self): assert result.name == self.ts.name -class TestSeriesMisc(TestData, SharedWithSparse, tm.TestCase): +class TestSeriesMisc(TestData, SharedWithSparse): def test_tab_completion(self): # GH 9910 diff --git a/pandas/tests/series/test_apply.py b/pandas/tests/series/test_apply.py index 089a2c36a5574..c273d3161fff5 100644 --- a/pandas/tests/series/test_apply.py +++ b/pandas/tests/series/test_apply.py @@ -17,7 +17,7 @@ from .common import TestData -class TestSeriesApply(TestData, tm.TestCase): +class TestSeriesApply(TestData): def test_apply(self): with np.errstate(all='ignore'): @@ -151,7 +151,7 @@ def test_apply_dict_depr(self): tsdf.A.agg({'foo': ['sum', 'mean']}) -class TestSeriesAggregate(TestData, tm.TestCase): +class TestSeriesAggregate(TestData): _multiprocess_can_split_ = True @@ -307,7 +307,7 @@ def test_reduce(self): assert_series_equal(result, expected) -class TestSeriesMap(TestData, tm.TestCase): +class TestSeriesMap(TestData): def test_map(self): index, data = tm.getMixedTypeDict() diff --git a/pandas/tests/series/test_asof.py b/pandas/tests/series/test_asof.py index a839d571c116c..1f62d618b20e1 100644 --- a/pandas/tests/series/test_asof.py +++ b/pandas/tests/series/test_asof.py @@ -11,7 +11,7 @@ from .common import TestData -class TestSeriesAsof(TestData, tm.TestCase): +class TestSeriesAsof(TestData): def test_basic(self): diff --git a/pandas/tests/series/test_combine_concat.py b/pandas/tests/series/test_combine_concat.py index 1291449ae7ce9..bb998b7fa55dd 100644 --- a/pandas/tests/series/test_combine_concat.py +++ b/pandas/tests/series/test_combine_concat.py @@ -18,7 +18,7 @@ from .common import TestData -class TestSeriesCombine(TestData, tm.TestCase): +class TestSeriesCombine(TestData): def test_append(self): appendedSeries = self.series.append(self.objSeries) @@ -217,7 +217,7 @@ def test_combine_first_dt64(self): assert_series_equal(rs, xp) -class TestTimeseries(tm.TestCase): +class TestTimeseries(object): def test_append_concat(self): rng = date_range('5/8/2012 1:45', periods=10, freq='5T') diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index a0a68a332f735..d591aa4f567a9 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -28,7 +28,7 @@ from .common import TestData -class TestSeriesConstructors(TestData, tm.TestCase): +class TestSeriesConstructors(TestData): def test_invalid_dtype(self): # GH15520 diff --git a/pandas/tests/series/test_datetime_values.py b/pandas/tests/series/test_datetime_values.py index 50914eef1abc8..e1fc9af0cca89 100644 --- a/pandas/tests/series/test_datetime_values.py +++ b/pandas/tests/series/test_datetime_values.py @@ -20,7 +20,7 @@ from .common import TestData -class TestSeriesDatetimeValues(TestData, tm.TestCase): +class TestSeriesDatetimeValues(TestData): def test_dt_namespace_accessor(self): diff --git a/pandas/tests/series/test_indexing.py b/pandas/tests/series/test_indexing.py index 394ae88983faa..7f876357ad3ab 100644 --- a/pandas/tests/series/test_indexing.py +++ b/pandas/tests/series/test_indexing.py @@ -31,7 +31,7 @@ JOIN_TYPES = ['inner', 'outer', 'left', 'right'] -class TestSeriesIndexing(TestData, tm.TestCase): +class TestSeriesIndexing(TestData): def test_get(self): @@ -2252,9 +2252,9 @@ def test_setitem_slice_into_readonly_backing_data(self): assert not array.any() -class TestTimeSeriesDuplicates(tm.TestCase): +class TestTimeSeriesDuplicates(object): - def setUp(self): + def setup_method(self, method): dates = [datetime(2000, 1, 2), datetime(2000, 1, 2), datetime(2000, 1, 2), datetime(2000, 1, 3), datetime(2000, 1, 3), datetime(2000, 1, 3), @@ -2494,12 +2494,12 @@ def test_indexing(self): pytest.raises(KeyError, df.__getitem__, df.index[2], ) -class TestDatetimeIndexing(tm.TestCase): +class TestDatetimeIndexing(object): """ Also test support for datetime64[ns] in Series / DataFrame """ - def setUp(self): + def setup_method(self, method): dti = DatetimeIndex(start=datetime(2005, 1, 1), end=datetime(2005, 1, 10), freq='Min') self.series = Series(np.random.rand(len(dti)), dti) @@ -2638,9 +2638,9 @@ def test_frame_datetime64_duplicated(self): assert (-result).all() -class TestNatIndexing(tm.TestCase): +class TestNatIndexing(object): - def setUp(self): + def setup_method(self, method): self.series = Series(date_range('1/1/2000', periods=10)) # --------------------------------------------------------------------- diff --git a/pandas/tests/series/test_internals.py b/pandas/tests/series/test_internals.py index 31492a4ab214a..79e23459ac992 100644 --- a/pandas/tests/series/test_internals.py +++ b/pandas/tests/series/test_internals.py @@ -16,7 +16,7 @@ import pandas.util.testing as tm -class TestSeriesInternals(tm.TestCase): +class TestSeriesInternals(object): def test_convert_objects(self): diff --git a/pandas/tests/series/test_io.py b/pandas/tests/series/test_io.py index 24bb3bbc7fc16..cce9249e98c0d 100644 --- a/pandas/tests/series/test_io.py +++ b/pandas/tests/series/test_io.py @@ -2,6 +2,8 @@ # pylint: disable-msg=E1101,W0612 from datetime import datetime +import collections +import pytest import numpy as np import pandas as pd @@ -16,7 +18,7 @@ from .common import TestData -class TestSeriesToCSV(TestData, tm.TestCase): +class TestSeriesToCSV(TestData): def test_from_csv(self): @@ -108,7 +110,7 @@ def test_to_csv_path_is_none(self): assert isinstance(csv_str, str) -class TestSeriesIO(TestData, tm.TestCase): +class TestSeriesIO(TestData): def test_to_frame(self): self.ts.name = None @@ -126,9 +128,6 @@ def test_to_frame(self): dict(testdifferent=self.ts.values), index=self.ts.index) assert_frame_equal(rs, xp) - def test_to_dict(self): - tm.assert_series_equal(Series(self.ts.to_dict(), name='ts'), self.ts) - def test_timeseries_periodindex(self): # GH2891 from pandas import period_range @@ -167,8 +166,21 @@ class SubclassedFrame(DataFrame): expected = SubclassedFrame({'X': [1, 2, 3]}) assert_frame_equal(result, expected) - -class TestSeriesToList(TestData, tm.TestCase): + @pytest.mark.parametrize('mapping', ( + dict, + collections.defaultdict(list), + collections.OrderedDict)) + def test_to_dict(self, mapping): + # GH16122 + ts = TestData().ts + tm.assert_series_equal( + Series(ts.to_dict(mapping), name='ts'), ts) + from_method = Series(ts.to_dict(collections.Counter)) + from_constructor = Series(collections.Counter(ts.iteritems())) + tm.assert_series_equal(from_method, from_constructor) + + +class TestSeriesToList(TestData): def test_tolist(self): rs = self.ts.tolist() diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py index 0eaab2e588cc2..c52c41877d5c0 100644 --- a/pandas/tests/series/test_missing.py +++ b/pandas/tests/series/test_missing.py @@ -48,7 +48,7 @@ def _simple_ts(start, end, freq='D'): return Series(np.random.randn(len(rng)), index=rng) -class TestSeriesMissingData(TestData, tm.TestCase): +class TestSeriesMissingData(TestData): def test_timedelta_fillna(self): # GH 3371 @@ -700,7 +700,7 @@ def test_series_pad_backfill_limit(self): assert_series_equal(result, expected) -class TestSeriesInterpolateData(TestData, tm.TestCase): +class TestSeriesInterpolateData(TestData): def test_interpolate(self): ts = Series(np.arange(len(self.ts), dtype=float), self.ts.index) diff --git a/pandas/tests/series/test_operators.py b/pandas/tests/series/test_operators.py index 7c7b98961d960..db0d06aa35a2a 100644 --- a/pandas/tests/series/test_operators.py +++ b/pandas/tests/series/test_operators.py @@ -28,7 +28,7 @@ from .common import TestData -class TestSeriesOperators(TestData, tm.TestCase): +class TestSeriesOperators(TestData): def test_series_comparison_scalars(self): series = Series(date_range('1/1/2000', periods=10)) diff --git a/pandas/tests/series/test_period.py b/pandas/tests/series/test_period.py index 5ea27d605c28a..6e8ee38d366e2 100644 --- a/pandas/tests/series/test_period.py +++ b/pandas/tests/series/test_period.py @@ -10,9 +10,9 @@ def _permute(obj): return obj.take(np.random.permutation(len(obj))) -class TestSeriesPeriod(tm.TestCase): +class TestSeriesPeriod(object): - def setUp(self): + def setup_method(self, method): self.series = Series(period_range('2000-01-01', periods=10, freq='D')) def test_auto_conversion(self): diff --git a/pandas/tests/series/test_quantile.py b/pandas/tests/series/test_quantile.py index 6d2cdd046ea7f..2d02260ac7303 100644 --- a/pandas/tests/series/test_quantile.py +++ b/pandas/tests/series/test_quantile.py @@ -13,7 +13,7 @@ from .common import TestData -class TestSeriesQuantile(TestData, tm.TestCase): +class TestSeriesQuantile(TestData): def test_quantile(self): diff --git a/pandas/tests/series/test_rank.py b/pandas/tests/series/test_rank.py index 1a1829eb5829f..ff489eb7f15b1 100644 --- a/pandas/tests/series/test_rank.py +++ b/pandas/tests/series/test_rank.py @@ -15,7 +15,7 @@ from pandas.tests.series.common import TestData -class TestSeriesRank(tm.TestCase, TestData): +class TestSeriesRank(TestData): s = Series([1, 3, 4, 2, nan, 2, 1, 5, nan, 3]) results = { diff --git a/pandas/tests/series/test_replace.py b/pandas/tests/series/test_replace.py index 19a99c8351db8..35d13a62ca083 100644 --- a/pandas/tests/series/test_replace.py +++ b/pandas/tests/series/test_replace.py @@ -11,7 +11,7 @@ from .common import TestData -class TestSeriesReplace(TestData, tm.TestCase): +class TestSeriesReplace(TestData): def test_replace(self): N = 100 ser = pd.Series(np.random.randn(N)) diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py index 8c1d74c5c2c23..3af61b0a902d3 100644 --- a/pandas/tests/series/test_repr.py +++ b/pandas/tests/series/test_repr.py @@ -18,7 +18,7 @@ from .common import TestData -class TestSeriesRepr(TestData, tm.TestCase): +class TestSeriesRepr(TestData): def test_multilevel_name_print(self): index = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'], ['one', 'two', diff --git a/pandas/tests/series/test_sorting.py b/pandas/tests/series/test_sorting.py index 791a7d5db9a26..40b0280de3719 100644 --- a/pandas/tests/series/test_sorting.py +++ b/pandas/tests/series/test_sorting.py @@ -13,7 +13,7 @@ from .common import TestData -class TestSeriesSorting(TestData, tm.TestCase): +class TestSeriesSorting(TestData): def test_sortlevel_deprecated(self): ts = self.ts.copy() diff --git a/pandas/tests/series/test_subclass.py b/pandas/tests/series/test_subclass.py index fe8a5e7658d9c..37c8d7343f7f1 100644 --- a/pandas/tests/series/test_subclass.py +++ b/pandas/tests/series/test_subclass.py @@ -6,7 +6,7 @@ import pandas.util.testing as tm -class TestSeriesSubclassing(tm.TestCase): +class TestSeriesSubclassing(object): def test_indexing_sliced(self): s = tm.SubclassedSeries([1, 2, 3, 4], index=list('abcd')) @@ -33,7 +33,7 @@ def test_to_frame(self): assert isinstance(res, tm.SubclassedDataFrame) -class TestSparseSeriesSubclassing(tm.TestCase): +class TestSparseSeriesSubclassing(object): def test_subclass_sparse_slice(self): # int64 diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 78e5d87636532..d5517bdcceac7 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -33,7 +33,7 @@ def assert_range_equal(left, right): assert (left.tz == right.tz) -class TestTimeSeries(TestData, tm.TestCase): +class TestTimeSeries(TestData): def test_shift(self): shifted = self.ts.shift(1) diff --git a/pandas/tests/sparse/test_arithmetics.py b/pandas/tests/sparse/test_arithmetics.py index 468d856ca68ce..f023cd0003910 100644 --- a/pandas/tests/sparse/test_arithmetics.py +++ b/pandas/tests/sparse/test_arithmetics.py @@ -3,7 +3,7 @@ import pandas.util.testing as tm -class TestSparseArrayArithmetics(tm.TestCase): +class TestSparseArrayArithmetics(object): _base = np.array _klass = pd.SparseArray diff --git a/pandas/tests/sparse/test_array.py b/pandas/tests/sparse/test_array.py index 9a2c958a252af..4ce03f72dbba6 100644 --- a/pandas/tests/sparse/test_array.py +++ b/pandas/tests/sparse/test_array.py @@ -10,14 +10,14 @@ from pandas import _np_version_under1p8 from pandas.core.sparse.api import SparseArray, SparseSeries -from pandas.core.sparse.libsparse import IntIndex +from pandas._libs.sparse import IntIndex from pandas.util.testing import assert_almost_equal import pandas.util.testing as tm -class TestSparseArray(tm.TestCase): +class TestSparseArray(object): - def setUp(self): + def setup_method(self, method): self.arr_data = np.array([nan, nan, 1, 2, 3, nan, 4, 5, nan, 6]) self.arr = SparseArray(self.arr_data) self.zarr = SparseArray([0, 0, 1, 2, 3, 0, 4, 5, 0, 6], fill_value=0) @@ -656,7 +656,7 @@ def test_fillna_overlap(self): tm.assert_sp_array_equal(res, exp) -class TestSparseArrayAnalytics(tm.TestCase): +class TestSparseArrayAnalytics(object): def test_sum(self): data = np.arange(10).astype(float) diff --git a/pandas/tests/sparse/test_combine_concat.py b/pandas/tests/sparse/test_combine_concat.py index 57b4065744e32..15639fbe156c6 100644 --- a/pandas/tests/sparse/test_combine_concat.py +++ b/pandas/tests/sparse/test_combine_concat.py @@ -5,7 +5,7 @@ import pandas.util.testing as tm -class TestSparseSeriesConcat(tm.TestCase): +class TestSparseSeriesConcat(object): def test_concat(self): val1 = np.array([1, 2, np.nan, np.nan, 0, np.nan]) @@ -122,9 +122,9 @@ def test_concat_sparse_dense(self): tm.assert_sp_series_equal(res, exp) -class TestSparseDataFrameConcat(tm.TestCase): +class TestSparseDataFrameConcat(object): - def setUp(self): + def setup_method(self, method): self.dense1 = pd.DataFrame({'A': [0., 1., 2., np.nan], 'B': [0., 0., 0., 0.], diff --git a/pandas/tests/sparse/test_format.py b/pandas/tests/sparse/test_format.py index 74be14ff5cf15..d983bd209085a 100644 --- a/pandas/tests/sparse/test_format.py +++ b/pandas/tests/sparse/test_format.py @@ -13,7 +13,7 @@ use_32bit_repr = is_platform_windows() or is_platform_32bit() -class TestSparseSeriesFormatting(tm.TestCase): +class TestSparseSeriesFormatting(object): @property def dtype_format_for_platform(self): @@ -105,7 +105,7 @@ def test_sparse_int(self): assert result == exp -class TestSparseDataFrameFormatting(tm.TestCase): +class TestSparseDataFrameFormatting(object): def test_sparse_frame(self): # GH 13110 diff --git a/pandas/tests/sparse/test_frame.py b/pandas/tests/sparse/test_frame.py index f2dd2aa79cc6a..0312b76ec30a5 100644 --- a/pandas/tests/sparse/test_frame.py +++ b/pandas/tests/sparse/test_frame.py @@ -21,15 +21,15 @@ from pandas import compat from pandas.core.sparse import frame as spf -from pandas.core.sparse.libsparse import BlockIndex, IntIndex +from pandas._libs.sparse import BlockIndex, IntIndex from pandas.core.sparse.api import SparseSeries, SparseDataFrame, SparseArray from pandas.tests.frame.test_api import SharedWithSparse -class TestSparseDataFrame(tm.TestCase, SharedWithSparse): +class TestSparseDataFrame(SharedWithSparse): klass = SparseDataFrame - def setUp(self): + def setup_method(self, method): self.data = {'A': [nan, nan, nan, 0, 1, 2, 3, 4, 5, 6], 'B': [0, 1, 2, nan, nan, nan, 3, 4, 5, 6], 'C': np.arange(10, dtype=np.float64), @@ -1245,7 +1245,7 @@ def test_from_to_scipy_object(spmatrix, fill_value): assert sdf.to_coo().dtype == res_dtype -class TestSparseDataFrameArithmetic(tm.TestCase): +class TestSparseDataFrameArithmetic(object): def test_numeric_op_scalar(self): df = pd.DataFrame({'A': [nan, nan, 0, 1, ], @@ -1274,8 +1274,8 @@ def test_comparison_op_scalar(self): tm.assert_frame_equal(res.to_dense(), df != 0) -class TestSparseDataFrameAnalytics(tm.TestCase): - def setUp(self): +class TestSparseDataFrameAnalytics(object): + def setup_method(self, method): self.data = {'A': [nan, nan, nan, 0, 1, 2, 3, 4, 5, 6], 'B': [0, 1, 2, nan, nan, nan, 3, 4, 5, 6], 'C': np.arange(10, dtype=float), diff --git a/pandas/tests/sparse/test_groupby.py b/pandas/tests/sparse/test_groupby.py index 23bea94a2aef8..c9049ed9743dd 100644 --- a/pandas/tests/sparse/test_groupby.py +++ b/pandas/tests/sparse/test_groupby.py @@ -4,9 +4,9 @@ import pandas.util.testing as tm -class TestSparseGroupBy(tm.TestCase): +class TestSparseGroupBy(object): - def setUp(self): + def setup_method(self, method): self.dense = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B': ['one', 'one', 'two', 'three', diff --git a/pandas/tests/sparse/test_indexing.py b/pandas/tests/sparse/test_indexing.py index 0fc2211bbeeae..382cff4b9d0ac 100644 --- a/pandas/tests/sparse/test_indexing.py +++ b/pandas/tests/sparse/test_indexing.py @@ -6,9 +6,9 @@ import pandas.util.testing as tm -class TestSparseSeriesIndexing(tm.TestCase): +class TestSparseSeriesIndexing(object): - def setUp(self): + def setup_method(self, method): self.orig = pd.Series([1, np.nan, np.nan, 3, np.nan]) self.sparse = self.orig.to_sparse() @@ -446,7 +446,7 @@ def tests_indexing_with_sparse(self): class TestSparseSeriesMultiIndexing(TestSparseSeriesIndexing): - def setUp(self): + def setup_method(self, method): # Mi with duplicated values idx = pd.MultiIndex.from_tuples([('A', 0), ('A', 1), ('B', 0), ('C', 0), ('C', 1)]) @@ -589,7 +589,7 @@ def test_reindex(self): assert sparse is not res -class TestSparseDataFrameIndexing(tm.TestCase): +class TestSparseDataFrameIndexing(object): def test_getitem(self): orig = pd.DataFrame([[1, np.nan, np.nan], @@ -952,9 +952,9 @@ def test_reindex_fill_value(self): tm.assert_sp_frame_equal(res, exp) -class TestMultitype(tm.TestCase): +class TestMultitype(object): - def setUp(self): + def setup_method(self, method): self.cols = ['string', 'int', 'float', 'object'] self.string_series = pd.SparseSeries(['a', 'b', 'c']) diff --git a/pandas/tests/sparse/test_libsparse.py b/pandas/tests/sparse/test_libsparse.py index c7207870b22b9..4842ebdd103c4 100644 --- a/pandas/tests/sparse/test_libsparse.py +++ b/pandas/tests/sparse/test_libsparse.py @@ -8,7 +8,7 @@ from pandas import compat from pandas.core.sparse.array import IntIndex, BlockIndex, _make_index -import pandas.core.sparse.libsparse as splib +import pandas._libs.sparse as splib TEST_LENGTH = 20 @@ -42,7 +42,7 @@ def _check_case_dict(case): _check_case([], [], [], [], [], []) -class TestSparseIndexUnion(tm.TestCase): +class TestSparseIndexUnion(object): def test_index_make_union(self): def _check_case(xloc, xlen, yloc, ylen, eloc, elen): @@ -188,7 +188,7 @@ def test_intindex_make_union(self): a.make_union(b) -class TestSparseIndexIntersect(tm.TestCase): +class TestSparseIndexIntersect(object): def test_intersect(self): def _check_correct(a, b, expected): @@ -239,7 +239,7 @@ def test_intersect_identical(self): assert case.intersect(case).equals(case) -class TestSparseIndexCommon(tm.TestCase): +class TestSparseIndexCommon(object): def test_int_internal(self): idx = _make_index(4, np.array([2, 3], dtype=np.int32), kind='integer') @@ -387,7 +387,7 @@ def _check(index): # corner cases -class TestBlockIndex(tm.TestCase): +class TestBlockIndex(object): def test_block_internal(self): idx = _make_index(4, np.array([2, 3], dtype=np.int32), kind='block') @@ -472,7 +472,7 @@ def test_to_block_index(self): assert index.to_block_index() is index -class TestIntIndex(tm.TestCase): +class TestIntIndex(object): def test_check_integrity(self): @@ -557,7 +557,7 @@ def test_to_int_index(self): assert index.to_int_index() is index -class TestSparseOperators(tm.TestCase): +class TestSparseOperators(object): def _op_tests(self, sparse_op, python_op): def _check_case(xloc, xlen, yloc, ylen, eloc, elen): diff --git a/pandas/tests/sparse/test_list.py b/pandas/tests/sparse/test_list.py index 941e07a5582b0..6c721ca813a21 100644 --- a/pandas/tests/sparse/test_list.py +++ b/pandas/tests/sparse/test_list.py @@ -1,5 +1,4 @@ from pandas.compat import range -import unittest from numpy import nan import numpy as np @@ -8,9 +7,9 @@ import pandas.util.testing as tm -class TestSparseList(unittest.TestCase): +class TestSparseList(object): - def setUp(self): + def setup_method(self, method): self.na_data = np.array([nan, nan, 1, 2, 3, nan, 4, 5, nan, 6]) self.zero_data = np.array([0, 0, 1, 2, 3, 0, 4, 5, 0, 6]) diff --git a/pandas/tests/sparse/test_pivot.py b/pandas/tests/sparse/test_pivot.py index 4ff9f20093c67..e7eba63e4e0b3 100644 --- a/pandas/tests/sparse/test_pivot.py +++ b/pandas/tests/sparse/test_pivot.py @@ -3,9 +3,9 @@ import pandas.util.testing as tm -class TestPivotTable(tm.TestCase): +class TestPivotTable(object): - def setUp(self): + def setup_method(self, method): self.dense = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B': ['one', 'one', 'two', 'three', diff --git a/pandas/tests/sparse/test_series.py b/pandas/tests/sparse/test_series.py index 0f04e1a06900d..b524d6bfab418 100644 --- a/pandas/tests/sparse/test_series.py +++ b/pandas/tests/sparse/test_series.py @@ -17,7 +17,7 @@ import pandas.core.sparse.frame as spf -from pandas.core.sparse.libsparse import BlockIndex, IntIndex +from pandas._libs.sparse import BlockIndex, IntIndex from pandas.core.sparse.api import SparseSeries from pandas.tests.series.test_api import SharedWithSparse @@ -56,9 +56,9 @@ def _test_data2_zero(): return arr, index -class TestSparseSeries(tm.TestCase, SharedWithSparse): +class TestSparseSeries(SharedWithSparse): - def setUp(self): + def setup_method(self, method): arr, index = _test_data1() date_index = bdate_range('1/1/2011', periods=len(index)) @@ -934,9 +934,9 @@ def test_combine_first(self): tm.assert_sp_series_equal(result, expected) -class TestSparseHandlingMultiIndexes(tm.TestCase): +class TestSparseHandlingMultiIndexes(object): - def setUp(self): + def setup_method(self, method): miindex = pd.MultiIndex.from_product( [["x", "y"], ["10", "20"]], names=['row-foo', 'row-bar']) micol = pd.MultiIndex.from_product( @@ -960,10 +960,10 @@ def test_round_trip_preserve_multiindex_names(self): check_names=True) -class TestSparseSeriesScipyInteraction(tm.TestCase): +class TestSparseSeriesScipyInteraction(object): # Issue 8048: add SparseSeries coo methods - def setUp(self): + def setup_method(self, method): tm._skip_if_no_scipy() import scipy.sparse # SparseSeries inputs used in tests, the tests rely on the order @@ -1310,9 +1310,9 @@ def _dense_series_compare(s, f): tm.assert_series_equal(result.to_dense(), dense_result) -class TestSparseSeriesAnalytics(tm.TestCase): +class TestSparseSeriesAnalytics(object): - def setUp(self): + def setup_method(self, method): arr, index = _test_data1() self.bseries = SparseSeries(arr, index=index, kind='block', name='bseries') diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index 86d9ab3643cc9..093730fb2478b 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -23,7 +23,7 @@ from pandas.util.testing import assert_almost_equal -class TestMatch(tm.TestCase): +class TestMatch(object): def test_ints(self): values = np.array([0, 2, 1]) @@ -59,7 +59,7 @@ def test_strings(self): tm.assert_series_equal(result, expected) -class TestSafeSort(tm.TestCase): +class TestSafeSort(object): def test_basic_sort(self): values = [3, 1, 2, 0, 4] @@ -146,7 +146,7 @@ def test_exceptions(self): algos.safe_sort(values=[0, 1, 2, 1], labels=[0, 1]) -class TestFactorize(tm.TestCase): +class TestFactorize(object): def test_basic(self): @@ -282,7 +282,7 @@ def test_complex_sorting(self): # gh 12666 - check no segfault # Test not valid numpy versions older than 1.11 if pd._np_version_under1p11: - self.skipTest("Test valid only for numpy 1.11+") + pytest.skip("Test valid only for numpy 1.11+") x17 = np.array([complex(i) for i in range(17)], dtype=object) @@ -306,7 +306,7 @@ def test_uint64_factorize(self): tm.assert_numpy_array_equal(uniques, exp_uniques) -class TestUnique(tm.TestCase): +class TestUnique(object): def test_ints(self): arr = np.random.randint(0, 100, size=50) @@ -503,7 +503,7 @@ def test_order_of_appearance(self): tm.assert_categorical_equal(result, expected) -class TestIsin(tm.TestCase): +class TestIsin(object): def test_invalid(self): @@ -587,7 +587,7 @@ def test_large(self): tm.assert_numpy_array_equal(result, expected) -class TestValueCounts(tm.TestCase): +class TestValueCounts(object): def test_value_counts(self): np.random.seed(1234) @@ -779,7 +779,7 @@ def test_value_counts_uint64(self): tm.assert_series_equal(result, expected) -class TestDuplicated(tm.TestCase): +class TestDuplicated(object): def test_duplicated_with_nas(self): keys = np.array([0, 1, np.nan, 0, 2, np.nan], dtype=object) @@ -1014,7 +1014,7 @@ def test_group_var_constant(self): tm.assert_almost_equal(out[0, 0], 0.0) -class TestGroupVarFloat64(tm.TestCase, GroupVarTestMixin): +class TestGroupVarFloat64(GroupVarTestMixin): __test__ = True algo = libgroupby.group_var_float64 @@ -1037,7 +1037,7 @@ def test_group_var_large_inputs(self): tm.assert_almost_equal(out[0, 0], 1.0 / 12, check_less_precise=True) -class TestGroupVarFloat32(tm.TestCase, GroupVarTestMixin): +class TestGroupVarFloat32(GroupVarTestMixin): __test__ = True algo = libgroupby.group_var_float32 @@ -1045,7 +1045,7 @@ class TestGroupVarFloat32(tm.TestCase, GroupVarTestMixin): rtol = 1e-2 -class TestHashTable(tm.TestCase): +class TestHashTable(object): def test_lookup_nan(self): xs = np.array([2.718, 3.14, np.nan, -7, 5, 2, 3]) @@ -1116,7 +1116,7 @@ def test_unique_label_indices(): check_dtype=False) -class TestRank(tm.TestCase): +class TestRank(object): def test_scipy_compat(self): tm._skip_if_no_scipy() @@ -1184,7 +1184,7 @@ def test_arrmap(): assert (result.dtype == np.bool_) -class TestTseriesUtil(tm.TestCase): +class TestTseriesUtil(object): def test_combineFunc(self): pass @@ -1378,7 +1378,7 @@ def test_int64_add_overflow(): b_mask=np.array([False, True])) -class TestMode(tm.TestCase): +class TestMode(object): def test_no_mode(self): exp = Series([], dtype=np.float64) diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index ed0d61cdbbaf9..85976b9fabd66 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -86,7 +86,7 @@ def check_result(self, result, expected, klass=None): assert result == expected -class TestPandasDelegate(tm.TestCase): +class TestPandasDelegate(object): class Delegator(object): _properties = ['foo'] @@ -109,7 +109,7 @@ class Delegate(PandasDelegate): def __init__(self, obj): self.obj = obj - def setUp(self): + def setup_method(self, method): pass def test_invalida_delgation(self): @@ -152,7 +152,7 @@ def test_memory_usage(self): sys.getsizeof(delegate) -class Ops(tm.TestCase): +class Ops(object): def _allow_na_ops(self, obj): """Whether to skip test cases including NaN""" @@ -162,7 +162,7 @@ def _allow_na_ops(self, obj): return False return True - def setUp(self): + def setup_method(self, method): self.bool_index = tm.makeBoolIndex(10, name='a') self.int_index = tm.makeIntIndex(10, name='a') self.float_index = tm.makeFloatIndex(10, name='a') @@ -259,8 +259,8 @@ def test_binary_ops_docs(self): class TestIndexOps(Ops): - def setUp(self): - super(TestIndexOps, self).setUp() + def setup_method(self, method): + super(TestIndexOps, self).setup_method(method) self.is_valid_objs = [o for o in self.objs if o._allow_index_ops] self.not_valid_objs = [o for o in self.objs if not o._allow_index_ops] @@ -1008,7 +1008,7 @@ def test_numpy_transpose(self): np.transpose, obj, axes=1) -class TestNoNewAttributesMixin(tm.TestCase): +class TestNoNewAttributesMixin(object): def test_mixin(self): class T(NoNewAttributesMixin): diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py index 515ca8d9cedc5..03adf17f50300 100644 --- a/pandas/tests/test_categorical.py +++ b/pandas/tests/test_categorical.py @@ -28,9 +28,9 @@ from pandas.core.config import option_context -class TestCategorical(tm.TestCase): +class TestCategorical(object): - def setUp(self): + def setup_method(self, method): self.factor = Categorical(['a', 'b', 'b', 'a', 'a', 'c', 'c', 'c'], ordered=True) @@ -1600,9 +1600,9 @@ def test_validate_inplace(self): cat.sort_values(inplace=value) -class TestCategoricalAsBlock(tm.TestCase): +class TestCategoricalAsBlock(object): - def setUp(self): + def setup_method(self, method): self.factor = Categorical(['a', 'b', 'b', 'a', 'a', 'c', 'c', 'c']) df = DataFrame({'value': np.random.randint(0, 10000, 100)}) @@ -4411,7 +4411,7 @@ def test_concat_categorical(self): tm.assert_frame_equal(res, exp) -class TestCategoricalSubclassing(tm.TestCase): +class TestCategoricalSubclassing(object): def test_constructor(self): sc = tm.SubclassedCategorical(['a', 'b', 'c']) diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index d7dbaccb87ee8..ccece52154dd3 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- import pytest +import collections +from functools import partial import numpy as np @@ -195,3 +197,28 @@ def test_dict_compat(): assert (com._dict_compat(data_datetime64) == expected) assert (com._dict_compat(expected) == expected) assert (com._dict_compat(data_unchanged) == data_unchanged) + + +def test_standardize_mapping(): + # No non-empty + bad = {'bad': 'data'} + with pytest.raises(ValueError): + com._standardize_mapping(bad) + + # No uninitialized defaultdicts + with pytest.raises(TypeError): + com._standardize_mapping(collections.defaultdict) + + # No non-mapping subtypes, instance + with pytest.raises(TypeError): + com._standardize_mapping([]) + + # No non-mapping subtypes, class + with pytest.raises(TypeError): + com._standardize_mapping(list) + + # Convert instance to type + assert (com._standardize_mapping({}) == dict) + + dd = collections.defaultdict(list) + assert (type(com._standardize_mapping(dd)) == partial) diff --git a/pandas/tests/test_compat.py b/pandas/tests/test_compat.py index 5c56142687b5c..ff9d09c033164 100644 --- a/pandas/tests/test_compat.py +++ b/pandas/tests/test_compat.py @@ -6,10 +6,9 @@ from pandas.compat import (range, zip, map, filter, lrange, lzip, lmap, lfilter, builtins, iterkeys, itervalues, iteritems, next) -import pandas.util.testing as tm -class TestBuiltinIterators(tm.TestCase): +class TestBuiltinIterators(object): @classmethod def check_result(cls, actual, expected, lengths): diff --git a/pandas/tests/test_config.py b/pandas/tests/test_config.py index ba055b105dc41..8d6f36ac6a798 100644 --- a/pandas/tests/test_config.py +++ b/pandas/tests/test_config.py @@ -2,29 +2,35 @@ import pytest import pandas as pd -import unittest -import warnings +import warnings -class TestConfig(unittest.TestCase): - def __init__(self, *args): - super(TestConfig, self).__init__(*args) +class TestConfig(object): + @classmethod + def setup_class(cls): from copy import deepcopy - self.cf = pd.core.config - self.gc = deepcopy(getattr(self.cf, '_global_config')) - self.do = deepcopy(getattr(self.cf, '_deprecated_options')) - self.ro = deepcopy(getattr(self.cf, '_registered_options')) - def setUp(self): + cls.cf = pd.core.config + cls.gc = deepcopy(getattr(cls.cf, '_global_config')) + cls.do = deepcopy(getattr(cls.cf, '_deprecated_options')) + cls.ro = deepcopy(getattr(cls.cf, '_registered_options')) + + def setup_method(self, method): setattr(self.cf, '_global_config', {}) - setattr( - self.cf, 'options', self.cf.DictWrapper(self.cf._global_config)) + setattr(self.cf, 'options', self.cf.DictWrapper( + self.cf._global_config)) setattr(self.cf, '_deprecated_options', {}) setattr(self.cf, '_registered_options', {}) - def tearDown(self): + # Our test fixture in conftest.py sets "chained_assignment" + # to "raise" only after all test methods have been setup. + # However, after this setup, there is no longer any + # "chained_assignment" option, so re-register it. + self.cf.register_option('chained_assignment', 'raise') + + def teardown_method(self, method): setattr(self.cf, '_global_config', self.gc) setattr(self.cf, '_deprecated_options', self.do) setattr(self.cf, '_registered_options', self.ro) diff --git a/pandas/tests/test_expressions.py b/pandas/tests/test_expressions.py index 8ef29097b66e8..fae7bfa513dcd 100644 --- a/pandas/tests/test_expressions.py +++ b/pandas/tests/test_expressions.py @@ -56,9 +56,9 @@ @pytest.mark.skipif(not expr._USE_NUMEXPR, reason='not using numexpr') -class TestExpressions(tm.TestCase): +class TestExpressions(object): - def setUp(self): + def setup_method(self, method): self.frame = _frame.copy() self.frame2 = _frame2.copy() @@ -67,7 +67,7 @@ def setUp(self): self.integer = _integer.copy() self._MIN_ELEMENTS = expr._MIN_ELEMENTS - def tearDown(self): + def teardown_method(self, method): expr._MIN_ELEMENTS = self._MIN_ELEMENTS def run_arithmetic(self, df, other, assert_func, check_dtype=False, diff --git a/pandas/tests/test_internals.py b/pandas/tests/test_internals.py index 61b4369d21ab4..0900d21b250ed 100644 --- a/pandas/tests/test_internals.py +++ b/pandas/tests/test_internals.py @@ -192,9 +192,9 @@ def create_mgr(descr, item_shape=None): [mgr_items] + [np.arange(n) for n in item_shape]) -class TestBlock(tm.TestCase): +class TestBlock(object): - def setUp(self): + def setup_method(self, method): # self.fblock = get_float_ex() # a,c,e # self.cblock = get_complex_ex() # # self.oblock = get_obj_ex() @@ -309,7 +309,7 @@ def test_split_block_at(self): # assert len(bs), 0) -class TestDatetimeBlock(tm.TestCase): +class TestDatetimeBlock(object): def test_try_coerce_arg(self): block = create_block('datetime', [0]) @@ -1072,7 +1072,7 @@ def assert_reindex_indexer_is_ok(mgr, axis, new_labels, indexer, # reindex_indexer(new_labels, indexer, axis) -class TestBlockPlacement(tm.TestCase): +class TestBlockPlacement(object): def test_slice_len(self): assert len(BlockPlacement(slice(0, 4))) == 4 diff --git a/pandas/tests/test_join.py b/pandas/tests/test_join.py index e9e7ffba7fe54..3fc13d23b53f7 100644 --- a/pandas/tests/test_join.py +++ b/pandas/tests/test_join.py @@ -8,7 +8,7 @@ from pandas.util.testing import assert_almost_equal -class TestIndexer(tm.TestCase): +class TestIndexer(object): def test_outer_join_indexer(self): typemap = [('int32', _join.outer_join_indexer_int32), diff --git a/pandas/tests/test_lib.py b/pandas/tests/test_lib.py index 0ac05bae624e5..df97095035952 100644 --- a/pandas/tests/test_lib.py +++ b/pandas/tests/test_lib.py @@ -8,7 +8,7 @@ import pandas.util.testing as tm -class TestMisc(tm.TestCase): +class TestMisc(object): def test_max_len_string_array(self): @@ -41,7 +41,7 @@ def test_fast_unique_multiple_list_gen_sort(self): tm.assert_numpy_array_equal(np.array(out), expected) -class TestIndexing(tm.TestCase): +class TestIndexing(object): def test_maybe_indices_to_slice_left_edge(self): target = np.arange(100) @@ -201,7 +201,7 @@ def test_get_reverse_indexer(self): assert np.array_equal(result, expected) -class TestNullObj(tm.TestCase): +class TestNullObj(object): _1d_methods = ['isnullobj', 'isnullobj_old'] _2d_methods = ['isnullobj2d', 'isnullobj2d_old'] diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index f4cb07625faf2..ab28b8b43f359 100644 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -22,7 +22,7 @@ class Base(object): - def setUp(self): + def setup_method(self, method): index = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'], ['one', 'two', 'three']], @@ -56,7 +56,7 @@ def setUp(self): self.ymd.index.set_names(['year', 'month', 'day'], inplace=True) -class TestMultiLevel(Base, tm.TestCase): +class TestMultiLevel(Base): def test_append(self): a, b = self.frame[:5], self.frame[5:] @@ -2352,7 +2352,7 @@ def test_iloc_mi(self): tm.assert_frame_equal(result, expected) -class TestSorted(Base, tm.TestCase): +class TestSorted(Base): """ everthing you wanted to test about sorting """ def test_sort_index_preserve_levels(self): diff --git a/pandas/tests/test_nanops.py b/pandas/tests/test_nanops.py index efa647fd91a0d..6798e64b01d7e 100644 --- a/pandas/tests/test_nanops.py +++ b/pandas/tests/test_nanops.py @@ -16,9 +16,9 @@ use_bn = nanops._USE_BOTTLENECK -class TestnanopsDataFrame(tm.TestCase): +class TestnanopsDataFrame(object): - def setUp(self): + def setup_method(self, method): np.random.seed(11235) nanops._USE_BOTTLENECK = False @@ -118,7 +118,7 @@ def setUp(self): self.arr_float_nan_inf_1d = self.arr_float_nan_inf[:, 0, 0] self.arr_nan_nan_inf_1d = self.arr_nan_nan_inf[:, 0, 0] - def tearDown(self): + def teardown_method(self, method): nanops._USE_BOTTLENECK = use_bn def check_results(self, targ, res, axis, check_dtype=True): @@ -742,7 +742,7 @@ def test__bn_ok_dtype(self): assert not nanops._bn_ok_dtype(self.arr_obj.dtype, 'test') -class TestEnsureNumeric(tm.TestCase): +class TestEnsureNumeric(object): def test_numeric_values(self): # Test integer @@ -782,11 +782,11 @@ def test_non_convertable_values(self): pytest.raises(TypeError, lambda: nanops._ensure_numeric([])) -class TestNanvarFixedValues(tm.TestCase): +class TestNanvarFixedValues(object): # xref GH10242 - def setUp(self): + def setup_method(self, method): # Samples from a normal distribution. self.variance = variance = 3.0 self.samples = self.prng.normal(scale=variance ** 0.5, size=100000) @@ -895,11 +895,11 @@ def prng(self): return np.random.RandomState(1234) -class TestNanskewFixedValues(tm.TestCase): +class TestNanskewFixedValues(object): # xref GH 11974 - def setUp(self): + def setup_method(self, method): # Test data + skewness value (computed with scipy.stats.skew) self.samples = np.sin(np.linspace(0, 1, 200)) self.actual_skew = -0.1875895205961754 @@ -945,11 +945,11 @@ def prng(self): return np.random.RandomState(1234) -class TestNankurtFixedValues(tm.TestCase): +class TestNankurtFixedValues(object): # xref GH 11974 - def setUp(self): + def setup_method(self, method): # Test data + kurtosis value (computed with scipy.stats.kurtosis) self.samples = np.sin(np.linspace(0, 1, 200)) self.actual_kurt = -1.2058303433799713 diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py index b9cceab4d65f4..3243b69a25acd 100644 --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -901,14 +901,14 @@ def test_set_value(self): self.panel.set_value('a') -class TestPanel(tm.TestCase, PanelTests, CheckIndexing, SafeForLongAndSparse, +class TestPanel(PanelTests, CheckIndexing, SafeForLongAndSparse, SafeForSparse): @classmethod def assert_panel_equal(cls, x, y): assert_panel_equal(x, y) - def setUp(self): + def setup_method(self, method): self.panel = make_test_panel() self.panel.major_axis.name = None self.panel.minor_axis.name = None @@ -2430,12 +2430,12 @@ def test_all_any_unhandled(self): pytest.raises(NotImplementedError, self.panel.any, bool_only=True) -class TestLongPanel(tm.TestCase): +class TestLongPanel(object): """ LongPanel no longer exists, but... """ - def setUp(self): + def setup_method(self, method): panel = make_test_panel() self.panel = panel.to_frame() self.unfiltered_panel = panel.to_frame(filter_observations=False) diff --git a/pandas/tests/test_panel4d.py b/pandas/tests/test_panel4d.py index 1b611309aece0..96f02d63712fc 100644 --- a/pandas/tests/test_panel4d.py +++ b/pandas/tests/test_panel4d.py @@ -593,10 +593,10 @@ def test_set_value(self): assert is_float_dtype(res3['l4'].values) -class TestPanel4d(tm.TestCase, CheckIndexing, SafeForSparse, +class TestPanel4d(CheckIndexing, SafeForSparse, SafeForLongAndSparse): - def setUp(self): + def setup_method(self, method): with catch_warnings(record=True): self.panel4d = tm.makePanel4D(nper=8) add_nans(self.panel4d) @@ -685,7 +685,7 @@ def test_ctor_dict(self): tm.assert_panel_equal(panel4d['A'], self.panel4d['l1']) tm.assert_frame_equal(panel4d.loc['B', 'ItemB', :, :], self.panel4d.loc['l2', ['ItemB'], - :, :]['ItemB']) + :, :]['ItemB']) def test_constructor_dict_mixed(self): with catch_warnings(record=True): @@ -798,7 +798,7 @@ def test_reindex(self): method='pad') tm.assert_panel_equal(larger.loc[:, :, - self.panel4d.major_axis[1], :], + self.panel4d.major_axis[1], :], smaller.loc[:, :, smaller_major[0], :]) # don't necessarily copy diff --git a/pandas/tests/test_panelnd.py b/pandas/tests/test_panelnd.py index 33c37e9c8feb2..c473e3c09cc74 100644 --- a/pandas/tests/test_panelnd.py +++ b/pandas/tests/test_panelnd.py @@ -9,9 +9,9 @@ import pandas.util.testing as tm -class TestPanelnd(tm.TestCase): +class TestPanelnd(object): - def setUp(self): + def setup_method(self, method): pass def test_4d_construction(self): diff --git a/pandas/tests/test_resample.py b/pandas/tests/test_resample.py index 276e9a12c1993..9734431c8b012 100644 --- a/pandas/tests/test_resample.py +++ b/pandas/tests/test_resample.py @@ -50,9 +50,9 @@ def _simple_pts(start, end, freq='D'): return Series(np.random.randn(len(rng)), index=rng) -class TestResampleAPI(tm.TestCase): +class TestResampleAPI(object): - def setUp(self): + def setup_method(self, method): dti = DatetimeIndex(start=datetime(2005, 1, 1), end=datetime(2005, 1, 10), freq='Min') @@ -847,10 +847,10 @@ def test_resample_loffset_arg_type(self): assert_frame_equal(result_how, expected) -class TestDatetimeIndex(Base, tm.TestCase): +class TestDatetimeIndex(Base): _index_factory = lambda x: date_range - def setUp(self): + def setup_method(self, method): dti = DatetimeIndex(start=datetime(2005, 1, 1), end=datetime(2005, 1, 10), freq='Min') @@ -2165,7 +2165,7 @@ def test_resample_datetime_values(self): tm.assert_series_equal(res, exp) -class TestPeriodIndex(Base, tm.TestCase): +class TestPeriodIndex(Base): _index_factory = lambda x: period_range def create_series(self): @@ -2773,7 +2773,7 @@ def test_evenly_divisible_with_no_extra_bins(self): assert_frame_equal(result, expected) -class TestTimedeltaIndex(Base, tm.TestCase): +class TestTimedeltaIndex(Base): _index_factory = lambda x: timedelta_range def create_series(self): @@ -2794,9 +2794,9 @@ def test_asfreq_bug(self): assert_frame_equal(result, expected) -class TestResamplerGrouper(tm.TestCase): +class TestResamplerGrouper(object): - def setUp(self): + def setup_method(self, method): self.frame = DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8, 'B': np.arange(40)}, index=date_range('1/1/2000', @@ -2989,9 +2989,9 @@ def test_median_duplicate_columns(self): assert_frame_equal(result, expected) -class TestTimeGrouper(tm.TestCase): +class TestTimeGrouper(object): - def setUp(self): + def setup_method(self, method): self.ts = Series(np.random.randn(1000), index=date_range('1/1/2000', periods=1000)) diff --git a/pandas/tests/test_sorting.py b/pandas/tests/test_sorting.py index c40cbcfdec883..e09270bcadf27 100644 --- a/pandas/tests/test_sorting.py +++ b/pandas/tests/test_sorting.py @@ -16,7 +16,7 @@ lexsort_indexer) -class TestSorting(tm.TestCase): +class TestSorting(object): @pytest.mark.slow def test_int64_overflow(self): @@ -191,7 +191,7 @@ def test_nargsort(self): tm.assert_numpy_array_equal(result, np.array(exp), check_dtype=False) -class TestMerge(tm.TestCase): +class TestMerge(object): @pytest.mark.slow def test_int64_overflow_issues(self): diff --git a/pandas/tests/test_strings.py b/pandas/tests/test_strings.py index 412a88e13bb23..f28a5926087ac 100644 --- a/pandas/tests/test_strings.py +++ b/pandas/tests/test_strings.py @@ -19,7 +19,7 @@ import pandas.core.strings as strings -class TestStringMethods(tm.TestCase): +class TestStringMethods(object): def test_api(self): diff --git a/pandas/tests/test_take.py b/pandas/tests/test_take.py index 617d268be8f67..7b97b0e975df3 100644 --- a/pandas/tests/test_take.py +++ b/pandas/tests/test_take.py @@ -9,7 +9,7 @@ from pandas._libs.tslib import iNaT -class TestTake(tm.TestCase): +class TestTake(object): # standard incompatible fill error fill_error = re.compile("Incompatible type for fill_value") diff --git a/pandas/tests/test_window.py b/pandas/tests/test_window.py index d3e427dfb4c7b..634cd5fe2586b 100644 --- a/pandas/tests/test_window.py +++ b/pandas/tests/test_window.py @@ -30,7 +30,7 @@ def assert_equal(left, right): tm.assert_frame_equal(left, right) -class Base(tm.TestCase): +class Base(object): _nan_locs = np.arange(20, 40) _inf_locs = np.array([]) @@ -48,7 +48,7 @@ def _create_data(self): class TestApi(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_getitem(self): @@ -315,7 +315,7 @@ def test_how_compat(self): class TestWindow(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_constructor(self): @@ -360,7 +360,7 @@ def test_numpy_compat(self): class TestRolling(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_doc_string(self): @@ -444,7 +444,7 @@ def test_closed(self): class TestExpanding(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_doc_string(self): @@ -486,7 +486,7 @@ def test_numpy_compat(self): class TestEWM(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_doc_string(self): @@ -549,7 +549,7 @@ def test_numpy_compat(self): class TestDeprecations(Base): """ test that we are catching deprecation warnings """ - def setUp(self): + def setup_method(self, method): self._create_data() def test_deprecations(self): @@ -559,11 +559,11 @@ def test_deprecations(self): mom.rolling_mean(Series(np.ones(10)), 3, center=True, axis=0) -# GH #12373 : rolling functions error on float32 data +# gh-12373 : rolling functions error on float32 data # make sure rolling functions works for different dtypes # -# NOTE that these are yielded tests and so _create_data is -# explicity called, nor do these inherit from unittest.TestCase +# NOTE that these are yielded tests and so _create_data +# is explicitly called. # # further note that we are only checking rolling for fully dtype # compliance (though both expanding and ewm inherit) @@ -775,7 +775,7 @@ def _create_data(self): class TestMoments(Base): - def setUp(self): + def setup_method(self, method): self._create_data() def test_centered_axis_validation(self): @@ -1958,7 +1958,7 @@ def _create_data(self): super(TestMomentsConsistency, self)._create_data() self.data = _consistency_data - def setUp(self): + def setup_method(self, method): self._create_data() def _test_moments_consistency(self, min_periods, count, mean, mock_mean, @@ -3037,9 +3037,9 @@ def test_rolling_min_max_numeric_types(self): assert result.dtypes[0] == np.dtype("f8") -class TestGrouperGrouping(tm.TestCase): +class TestGrouperGrouping(object): - def setUp(self): + def setup_method(self, method): self.series = Series(np.arange(10)) self.frame = DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8, 'B': np.arange(40)}) @@ -3182,12 +3182,12 @@ def test_expanding_apply(self): tm.assert_frame_equal(result, expected) -class TestRollingTS(tm.TestCase): +class TestRollingTS(object): # rolling time-series friendly # xref GH13327 - def setUp(self): + def setup_method(self, method): self.regular = DataFrame({'A': pd.date_range('20130101', periods=5, diff --git a/pandas/tests/tools/test_numeric.py b/pandas/tests/tools/test_numeric.py index b298df4f4b5d8..f82ad97d7b70f 100644 --- a/pandas/tests/tools/test_numeric.py +++ b/pandas/tests/tools/test_numeric.py @@ -9,7 +9,7 @@ from numpy import iinfo -class TestToNumeric(tm.TestCase): +class TestToNumeric(object): def test_series(self): s = pd.Series(['1', '-3.14', '7']) diff --git a/pandas/tests/tseries/test_frequencies.py b/pandas/tests/tseries/test_frequencies.py index a78150e9cf728..2edca1bd4676b 100644 --- a/pandas/tests/tseries/test_frequencies.py +++ b/pandas/tests/tseries/test_frequencies.py @@ -19,7 +19,7 @@ from pandas import Timedelta -class TestToOffset(tm.TestCase): +class TestToOffset(object): def test_to_offset_multiple(self): freqstr = '2h30min' @@ -342,7 +342,7 @@ def _assert_depr(freq, expected, aliases): assert (frequencies._period_str_to_code('NS') == 12000) -class TestFrequencyCode(tm.TestCase): +class TestFrequencyCode(object): def test_freq_code(self): assert frequencies.get_freq('A') == 1000 @@ -493,7 +493,7 @@ def test_get_freq_code(self): _dti = DatetimeIndex -class TestFrequencyInference(tm.TestCase): +class TestFrequencyInference(object): def test_raise_if_period_index(self): index = PeriodIndex(start="1/1/1990", periods=20, freq="M") diff --git a/pandas/tests/tseries/test_holiday.py b/pandas/tests/tseries/test_holiday.py index 109adaaa7e0b0..59a2a225ab5f8 100644 --- a/pandas/tests/tseries/test_holiday.py +++ b/pandas/tests/tseries/test_holiday.py @@ -19,9 +19,9 @@ from pytz import utc -class TestCalendar(tm.TestCase): +class TestCalendar(object): - def setUp(self): + def setup_method(self, method): self.holiday_list = [ datetime(2012, 1, 2), datetime(2012, 1, 16), @@ -85,9 +85,9 @@ def test_rule_from_name(self): assert USFedCal.rule_from_name('Thanksgiving') == USThanksgivingDay -class TestHoliday(tm.TestCase): +class TestHoliday(object): - def setUp(self): + def setup_method(self, method): self.start_date = datetime(2011, 1, 1) self.end_date = datetime(2020, 12, 31) @@ -284,9 +284,9 @@ def test_factory(self): assert len(class_3.rules) == 2 -class TestObservanceRules(tm.TestCase): +class TestObservanceRules(object): - def setUp(self): + def setup_method(self, method): self.we = datetime(2014, 4, 9) self.th = datetime(2014, 4, 10) self.fr = datetime(2014, 4, 11) @@ -342,7 +342,7 @@ def test_after_nearest_workday(self): assert after_nearest_workday(self.fr) == self.mo -class TestFederalHolidayCalendar(tm.TestCase): +class TestFederalHolidayCalendar(object): def test_no_mlk_before_1984(self): # see gh-10278 @@ -375,7 +375,7 @@ class MemorialDay(AbstractHolidayCalendar): datetime(1979, 5, 28, 0, 0)] -class TestHolidayConflictingArguments(tm.TestCase): +class TestHolidayConflictingArguments(object): def test_both_offset_observance_raises(self): # see gh-10217 diff --git a/pandas/tests/tseries/test_offsets.py b/pandas/tests/tseries/test_offsets.py index 79190aa98f8d9..09de064c15183 100644 --- a/pandas/tests/tseries/test_offsets.py +++ b/pandas/tests/tseries/test_offsets.py @@ -97,7 +97,7 @@ def test_to_m8(): ##### -class Base(tm.TestCase): +class Base(object): _offset = None _offset_types = [getattr(offsets, o) for o in offsets.__all__] @@ -167,7 +167,7 @@ def test_apply_out_of_range(self): class TestCommon(Base): - def setUp(self): + def setup_method(self, method): # exected value created by Base._get_offset # are applied to 2011/01/01 09:00 (Saturday) # used for .apply and .rollforward @@ -507,7 +507,7 @@ def test_pickle_v0_15_2(self): class TestDateOffset(Base): - def setUp(self): + def setup_method(self, method): self.d = Timestamp(datetime(2008, 1, 2)) _offset_map.clear() @@ -547,7 +547,7 @@ def test_eq(self): class TestBusinessDay(Base): _offset = BDay - def setUp(self): + def setup_method(self, method): self.d = datetime(2008, 1, 1) self.offset = BDay() @@ -724,7 +724,7 @@ def test_offsets_compare_equal(self): class TestBusinessHour(Base): _offset = BusinessHour - def setUp(self): + def setup_method(self, method): self.d = datetime(2014, 7, 1, 10, 00) self.offset1 = BusinessHour() @@ -1418,7 +1418,7 @@ def test_datetimeindex(self): class TestCustomBusinessHour(Base): _offset = CustomBusinessHour - def setUp(self): + def setup_method(self, method): # 2014 Calendar to check custom holidays # Sun Mon Tue Wed Thu Fri Sat # 6/22 23 24 25 26 27 28 @@ -1674,7 +1674,7 @@ def test_apply_nanoseconds(self): class TestCustomBusinessDay(Base): _offset = CDay - def setUp(self): + def setup_method(self, method): self.d = datetime(2008, 1, 1) self.nd = np_datetime64_compat('2008-01-01 00:00:00Z') @@ -1910,7 +1910,7 @@ def test_pickle_compat_0_14_1(self): class CustomBusinessMonthBase(object): - def setUp(self): + def setup_method(self, method): self.d = datetime(2008, 1, 1) self.offset = self._object() @@ -4334,7 +4334,7 @@ def test_Easter(): assertEq(-Easter(2), datetime(2010, 4, 4), datetime(2008, 3, 23)) -class TestTicks(tm.TestCase): +class TestTicks(object): ticks = [Hour, Minute, Second, Milli, Micro, Nano] @@ -4491,7 +4491,7 @@ def test_compare_ticks(self): assert kls(3) != kls(4) -class TestOffsetNames(tm.TestCase): +class TestOffsetNames(object): def test_get_offset_name(self): assert BDay().freqstr == 'B' @@ -4547,7 +4547,7 @@ def test_get_offset_legacy(): get_offset(name) -class TestParseTimeString(tm.TestCase): +class TestParseTimeString(object): def test_parse_time_string(self): (date, parsed, reso) = parse_time_string('4Q1984') @@ -4610,9 +4610,9 @@ def test_quarterly_dont_normalize(): assert (result.time() == date.time()) -class TestOffsetAliases(tm.TestCase): +class TestOffsetAliases(object): - def setUp(self): + def setup_method(self, method): _offset_map.clear() def test_alias_equality(self): @@ -4691,12 +4691,12 @@ def get_all_subclasses(cls): return ret -class TestCaching(tm.TestCase): +class TestCaching(object): # as of GH 6479 (in 0.14.0), offset caching is turned off # as of v0.12.0 only BusinessMonth/Quarter were actually caching - def setUp(self): + def setup_method(self, method): _daterange_cache.clear() _offset_map.clear() @@ -4746,7 +4746,7 @@ def test_week_of_month_index_creation(self): assert inst2 not in _daterange_cache -class TestReprNames(tm.TestCase): +class TestReprNames(object): def test_str_for_named_is_name(self): # look at all the amazing combinations! @@ -4771,7 +4771,7 @@ def get_utc_offset_hours(ts): return (o.days * 24 * 3600 + o.seconds) / 3600.0 -class TestDST(tm.TestCase): +class TestDST(object): """ test DateOffset additions over Daylight Savings Time """ diff --git a/pandas/tests/tseries/test_timezones.py b/pandas/tests/tseries/test_timezones.py index 10776381974de..97c54922d36e9 100644 --- a/pandas/tests/tseries/test_timezones.py +++ b/pandas/tests/tseries/test_timezones.py @@ -50,9 +50,9 @@ def dst(self, dt): fixed_off_no_name = FixedOffset(-330, None) -class TestTimeZoneSupportPytz(tm.TestCase): +class TestTimeZoneSupportPytz(object): - def setUp(self): + def setup_method(self, method): tm._skip_if_no_pytz() def tz(self, tz): @@ -944,7 +944,7 @@ def test_datetimeindex_tz_nat(self): class TestTimeZoneSupportDateutil(TestTimeZoneSupportPytz): - def setUp(self): + def setup_method(self, method): tm._skip_if_no_dateutil() def tz(self, tz): @@ -1178,7 +1178,7 @@ def test_tz_convert_tzlocal(self): tm.assert_numpy_array_equal(dti2.asi8, dti.asi8) -class TestTimeZoneCacheKey(tm.TestCase): +class TestTimeZoneCacheKey(object): def test_cache_keys_are_distinct_for_pytz_vs_dateutil(self): tzs = pytz.common_timezones @@ -1194,10 +1194,10 @@ def test_cache_keys_are_distinct_for_pytz_vs_dateutil(self): assert tslib._p_tz_cache_key(tz_p) != tslib._p_tz_cache_key(tz_d) -class TestTimeZones(tm.TestCase): +class TestTimeZones(object): timezones = ['UTC', 'Asia/Tokyo', 'US/Eastern', 'dateutil/US/Pacific'] - def setUp(self): + def setup_method(self, method): tm._skip_if_no_pytz() def test_replace(self): @@ -1719,7 +1719,7 @@ def test_nat(self): tm.assert_index_equal(idx, DatetimeIndex(expected, tz='US/Eastern')) -class TestTslib(tm.TestCase): +class TestTslib(object): def test_tslib_tz_convert(self): def compare_utc_to_local(tz_didx, utc_didx): diff --git a/pandas/tests/util/__init__.py b/pandas/tests/util/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pandas/tests/reshape/test_hashing.py b/pandas/tests/util/test_hashing.py similarity index 93% rename from pandas/tests/reshape/test_hashing.py rename to pandas/tests/util/test_hashing.py index 85807da33e38d..e1e6e43529a7d 100644 --- a/pandas/tests/reshape/test_hashing.py +++ b/pandas/tests/util/test_hashing.py @@ -5,13 +5,14 @@ import pandas as pd from pandas import DataFrame, Series, Index, MultiIndex -from pandas.util.hashing import hash_array, hash_tuples, hash_pandas_object +from pandas.util import hash_array, hash_pandas_object +from pandas.core.util.hashing import hash_tuples import pandas.util.testing as tm -class TestHashing(tm.TestCase): +class TestHashing(object): - def setUp(self): + def setup_method(self, method): self.df = DataFrame( {'i32': np.array([1, 2, 3] * 3, dtype='int32'), 'f32': np.array([None, 2.5, 3.5] * 3, dtype='float32'), @@ -267,3 +268,18 @@ def test_hash_collisions(self): result = hash_array(np.asarray(L, dtype=object), 'utf8') tm.assert_numpy_array_equal( result, np.concatenate([expected1, expected2], axis=0)) + + +def test_deprecation(): + + with tm.assert_produces_warning(DeprecationWarning, + check_stacklevel=False): + from pandas.tools.hashing import hash_pandas_object + obj = Series(list('abc')) + hash_pandas_object(obj, hash_key='9876543210123456') + + with tm.assert_produces_warning(DeprecationWarning, + check_stacklevel=False): + from pandas.tools.hashing import hash_array + obj = np.array([1, 2, 3]) + hash_array(obj, hash_key='9876543210123456') diff --git a/pandas/tests/test_testing.py b/pandas/tests/util/test_testing.py similarity index 98% rename from pandas/tests/test_testing.py rename to pandas/tests/util/test_testing.py index 2c0cd55205a5a..fe7c3b99987f5 100644 --- a/pandas/tests/test_testing.py +++ b/pandas/tests/util/test_testing.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import pandas as pd -import unittest import pytest import numpy as np import sys @@ -13,7 +12,7 @@ from pandas.compat import is_platform_windows -class TestAssertAlmostEqual(tm.TestCase): +class TestAssertAlmostEqual(object): def _assert_almost_equal_both(self, a, b, **kwargs): assert_almost_equal(a, b, **kwargs) @@ -140,7 +139,7 @@ def test_assert_almost_equal_object(self): self._assert_almost_equal_both(a, b) -class TestUtilTesting(tm.TestCase): +class TestUtilTesting(object): def test_raise_with_traceback(self): with tm.assert_raises_regex(LookupError, "error_text"): @@ -158,7 +157,7 @@ def test_raise_with_traceback(self): raise_with_traceback(e, traceback) -class TestAssertNumpyArrayEqual(tm.TestCase): +class TestAssertNumpyArrayEqual(object): def test_numpy_array_equal_message(self): @@ -340,7 +339,7 @@ def test_assert_almost_equal_iterable_message(self): assert_almost_equal([1, 2], [1, 3]) -class TestAssertIndexEqual(unittest.TestCase): +class TestAssertIndexEqual(object): def test_index_equal_message(self): @@ -487,7 +486,7 @@ def test_index_equal_metadata_message(self): assert_index_equal(idx1, idx2) -class TestAssertSeriesEqual(tm.TestCase): +class TestAssertSeriesEqual(object): def _assert_equal(self, x, y, **kwargs): assert_series_equal(x, y, **kwargs) @@ -581,7 +580,7 @@ def test_series_equal_message(self): check_less_precise=True) -class TestAssertFrameEqual(tm.TestCase): +class TestAssertFrameEqual(object): def _assert_equal(self, x, y, **kwargs): assert_frame_equal(x, y, **kwargs) @@ -680,7 +679,7 @@ def test_frame_equal_message(self): by_blocks=True) -class TestAssertCategoricalEqual(unittest.TestCase): +class TestAssertCategoricalEqual(object): def test_categorical_equal_message(self): @@ -718,7 +717,7 @@ def test_categorical_equal_message(self): tm.assert_categorical_equal(a, b) -class TestRNGContext(unittest.TestCase): +class TestRNGContext(object): def test_RNGContext(self): expected0 = 1.764052345967664 @@ -730,7 +729,7 @@ def test_RNGContext(self): assert np.random.randn() == expected0 -class TestLocale(tm.TestCase): +class TestLocale(object): def test_locale(self): if sys.platform == 'win32': diff --git a/pandas/tests/test_util.py b/pandas/tests/util/test_util.py similarity index 96% rename from pandas/tests/test_util.py rename to pandas/tests/util/test_util.py index 80eb5bb9dfe16..532d596220501 100644 --- a/pandas/tests/test_util.py +++ b/pandas/tests/util/test_util.py @@ -9,10 +9,10 @@ import pytest from pandas.compat import intern from pandas.util._move import move_into_mutable_buffer, BadMove, stolenbuf -from pandas.util.decorators import deprecate_kwarg -from pandas.util.validators import (validate_args, validate_kwargs, - validate_args_and_kwargs, - validate_bool_kwarg) +from pandas.util._decorators import deprecate_kwarg +from pandas.util._validators import (validate_args, validate_kwargs, + validate_args_and_kwargs, + validate_bool_kwarg) import pandas.util.testing as tm @@ -20,9 +20,9 @@ LOCALE_OVERRIDE = os.environ.get('LOCALE_OVERRIDE', None) -class TestDecorators(tm.TestCase): +class TestDecorators(object): - def setUp(self): + def setup_method(self, method): @deprecate_kwarg('old', 'new') def _f1(new=False): return new @@ -89,7 +89,7 @@ def test_rands_array(): assert(len(arr[1, 1]) == 7) -class TestValidateArgs(tm.TestCase): +class TestValidateArgs(object): fname = 'func' def test_bad_min_fname_arg_count(self): @@ -159,7 +159,7 @@ def test_validation(self): validate_args(self.fname, (1, None), 2, compat_args) -class TestValidateKwargs(tm.TestCase): +class TestValidateKwargs(object): fname = 'func' def test_bad_kwarg(self): @@ -225,7 +225,7 @@ def test_validate_bool_kwarg(self): assert validate_bool_kwarg(value, name) == value -class TestValidateKwargsAndArgs(tm.TestCase): +class TestValidateKwargsAndArgs(object): fname = 'func' def test_invalid_total_length_max_length_one(self): @@ -322,7 +322,7 @@ def test_validation(self): compat_args) -class TestMove(tm.TestCase): +class TestMove(object): def test_cannot_create_instance_of_stolenbuffer(self): """Stolen buffers need to be created through the smart constructor @@ -407,11 +407,10 @@ def test_numpy_errstate_is_default(): assert np.geterr() == expected -class TestLocaleUtils(tm.TestCase): +class TestLocaleUtils(object): @classmethod - def setUpClass(cls): - super(TestLocaleUtils, cls).setUpClass() + def setup_class(cls): cls.locales = tm.get_locales() if not cls.locales: @@ -420,8 +419,7 @@ def setUpClass(cls): tm._skip_if_windows() @classmethod - def tearDownClass(cls): - super(TestLocaleUtils, cls).tearDownClass() + def teardown_class(cls): del cls.locales def test_get_locales(self): diff --git a/pandas/tools/hashing.py b/pandas/tools/hashing.py new file mode 100644 index 0000000000000..ba38710b607af --- /dev/null +++ b/pandas/tools/hashing.py @@ -0,0 +1,18 @@ +import warnings +import sys + +m = sys.modules['pandas.tools.hashing'] +for t in ['hash_pandas_object', 'hash_array']: + + def outer(t=t): + + def wrapper(*args, **kwargs): + from pandas import util + warnings.warn("pandas.tools.hashing is deprecated and will be " + "removed in a future version, import " + "from pandas.util", + DeprecationWarning, stacklevel=3) + return getattr(util, t)(*args, **kwargs) + return wrapper + + setattr(m, t, outer(t)) diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index 06d70f1456518..dddf835424f67 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -16,7 +16,7 @@ import pandas.core.algorithms as algos from pandas.core.algorithms import unique from pandas.tseries.offsets import DateOffset -from pandas.util.decorators import cache_readonly, deprecate_kwarg +from pandas.util._decorators import cache_readonly, deprecate_kwarg import pandas.tseries.offsets as offsets from pandas._libs import lib, tslib diff --git a/pandas/util/__init__.py b/pandas/util/__init__.py index e69de29bb2d1d..e86af930fef7c 100644 --- a/pandas/util/__init__.py +++ b/pandas/util/__init__.py @@ -0,0 +1,2 @@ +from pandas.core.util.hashing import hash_pandas_object, hash_array # noqa +from pandas.util._decorators import Appender, Substitution, cache_readonly # noqa diff --git a/pandas/util/decorators.py b/pandas/util/_decorators.py similarity index 100% rename from pandas/util/decorators.py rename to pandas/util/_decorators.py diff --git a/pandas/util/depr_module.py b/pandas/util/_depr_module.py similarity index 100% rename from pandas/util/depr_module.py rename to pandas/util/_depr_module.py diff --git a/pandas/util/doctools.py b/pandas/util/_doctools.py similarity index 100% rename from pandas/util/doctools.py rename to pandas/util/_doctools.py diff --git a/pandas/util/print_versions.py b/pandas/util/_print_versions.py similarity index 100% rename from pandas/util/print_versions.py rename to pandas/util/_print_versions.py diff --git a/pandas/util/validators.py b/pandas/util/_validators.py similarity index 100% rename from pandas/util/validators.py rename to pandas/util/_validators.py diff --git a/pandas/util/testing.py b/pandas/util/testing.py index d0c56e9974a3f..f6b572cdf7179 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -10,7 +10,6 @@ import os import subprocess import locale -import unittest import traceback from datetime import datetime @@ -49,7 +48,7 @@ Index, MultiIndex, Series, DataFrame, Panel, Panel4D) -from pandas.util import libtesting +from pandas._libs import testing as _testing from pandas.io.common import urlopen try: import pytest @@ -86,25 +85,6 @@ def reset_testing_mode(): set_testing_mode() -class TestCase(unittest.TestCase): - """ - The test case class that we originally used when using the - nosetests framework. Under the new pytest framework, we are - moving away from this class. - - Do not create new test classes derived from this one. Rather, - they should inherit from object directly. - """ - - @classmethod - def setUpClass(cls): - pd.set_option('chained_assignment', 'raise') - - @classmethod - def tearDownClass(cls): - pass - - def reset_display_options(): """ Reset the display options for printing and representing objects. @@ -190,7 +170,7 @@ def assert_almost_equal(left, right, check_exact=False, else: obj = 'Input' assert_class_equal(left, right, obj=obj) - return libtesting.assert_almost_equal( + return _testing.assert_almost_equal( left, right, check_dtype=check_dtype, check_less_precise=check_less_precise, @@ -226,7 +206,7 @@ def _check_isinstance(left, right, cls): def assert_dict_equal(left, right, compare_keys=True): _check_isinstance(left, right, dict) - return libtesting.assert_dict_equal(left, right, compare_keys=compare_keys) + return _testing.assert_dict_equal(left, right, compare_keys=compare_keys) def randbool(size=(), p=0.5): @@ -295,36 +275,31 @@ def _skip_if_32bit(): pytest.skip("skipping for 32 bit") -def mplskip(cls): - """Skip a TestCase instance if matplotlib isn't installed""" - - @classmethod - def setUpClass(cls): - try: - import matplotlib as mpl - mpl.use("Agg", warn=False) - except ImportError: - import pytest - pytest.skip("matplotlib not installed") +def _skip_module_if_no_mpl(): + import pytest - cls.setUpClass = setUpClass - return cls + mpl = pytest.importorskip("matplotlib") + mpl.use("Agg", warn=False) def _skip_if_no_mpl(): try: - import matplotlib # noqa + import matplotlib as mpl + mpl.use("Agg", warn=False) except ImportError: import pytest pytest.skip("matplotlib not installed") def _skip_if_mpl_1_5(): - import matplotlib - v = matplotlib.__version__ + import matplotlib as mpl + + v = mpl.__version__ if v > LooseVersion('1.4.3') or v[0] == '0': import pytest pytest.skip("matplotlib 1.5") + else: + mpl.use("Agg", warn=False) def _skip_if_no_scipy(): @@ -948,10 +923,10 @@ def _get_ilevel_values(index, level): .format(obj, np.round(diff, 5)) raise_assert_detail(obj, msg, left, right) else: - libtesting.assert_almost_equal(left.values, right.values, - check_less_precise=check_less_precise, - check_dtype=exact, - obj=obj, lobj=left, robj=right) + _testing.assert_almost_equal(left.values, right.values, + check_less_precise=check_less_precise, + check_dtype=exact, + obj=obj, lobj=left, robj=right) # metadata comparison if check_names: @@ -1284,10 +1259,10 @@ def assert_series_equal(left, right, check_dtype=True, assert_index_equal(l, r, obj='{0}.index'.format(obj)) else: - libtesting.assert_almost_equal(left.get_values(), right.get_values(), - check_less_precise=check_less_precise, - check_dtype=check_dtype, - obj='{0}'.format(obj)) + _testing.assert_almost_equal(left.get_values(), right.get_values(), + check_less_precise=check_less_precise, + check_dtype=check_dtype, + obj='{0}'.format(obj)) # metadata comparison if check_names: @@ -1501,8 +1476,8 @@ def assert_sp_array_equal(left, right, check_dtype=True): check_dtype=check_dtype) # SparseIndex comparison - assert isinstance(left.sp_index, pd.core.sparse.libsparse.SparseIndex) - assert isinstance(right.sp_index, pd.core.sparse.libsparse.SparseIndex) + assert isinstance(left.sp_index, pd._libs.sparse.SparseIndex) + assert isinstance(right.sp_index, pd._libs.sparse.SparseIndex) if not left.sp_index.equals(right.sp_index): raise_assert_detail('SparseArray.index', 'index are not equal', diff --git a/setup.py b/setup.py index 6f3ddbe2ad9d0..d101358fb63dd 100755 --- a/setup.py +++ b/setup.py @@ -116,9 +116,9 @@ def is_platform_mac(): 'join': ['_libs/join_helper.pxi.in', '_libs/join_func_helper.pxi.in'], 'reshape': ['_libs/reshape_helper.pxi.in'], 'hashtable': ['_libs/hashtable_class_helper.pxi.in', - '_libs/hashtable_func_helper.pxi.in'], + '_libs/hashtable_func_helper.pxi.in'], 'index': ['_libs/index_class_helper.pxi.in'], - 'sparse': ['core/sparse/sparse_op_helper.pxi.in'], + 'sparse': ['_libs/sparse_op_helper.pxi.in'], 'interval': ['_libs/intervaltree.pxi.in'] } @@ -337,11 +337,11 @@ class CheckSDist(sdist_class): 'pandas/_libs/algos.pyx', 'pandas/_libs/join.pyx', 'pandas/_libs/interval.pyx', - 'pandas/core/window.pyx', - 'pandas/core/sparse/sparse.pyx', - 'pandas/util/testing.pyx', - 'pandas/tools/hash.pyx', - 'pandas/io/parsers.pyx', + 'pandas/_libs/hashing.pyx', + 'pandas/_libs/testing.pyx', + 'pandas/_libs/window.pyx', + 'pandas/_libs/sparse.pyx', + 'pandas/_libs/parsers.pyx', 'pandas/io/sas/sas.pyx'] def initialize_options(self): @@ -513,24 +513,24 @@ def pxd(name): '_libs.interval': {'pyxfile': '_libs/interval', 'pxdfiles': ['_libs/hashtable'], 'depends': _pxi_dep['interval']}, - 'core.libwindow': {'pyxfile': 'core/window', - 'pxdfiles': ['_libs/src/skiplist', '_libs/src/util'], - 'depends': ['pandas/_libs/src/skiplist.pyx', - 'pandas/_libs/src/skiplist.h']}, - 'io.libparsers': {'pyxfile': 'io/parsers', + '_libs.window': {'pyxfile': '_libs/window', + 'pxdfiles': ['_libs/src/skiplist', '_libs/src/util'], + 'depends': ['pandas/_libs/src/skiplist.pyx', + 'pandas/_libs/src/skiplist.h']}, + '_libs.parsers': {'pyxfile': '_libs/parsers', 'depends': ['pandas/_libs/src/parser/tokenizer.h', 'pandas/_libs/src/parser/io.h', 'pandas/_libs/src/numpy_helper.h'], 'sources': ['pandas/_libs/src/parser/tokenizer.c', 'pandas/_libs/src/parser/io.c']}, - 'core.sparse.libsparse': {'pyxfile': 'core/sparse/sparse', - 'depends': (['pandas/core/sparse/sparse.pyx'] + - _pxi_dep['sparse'])}, - 'util.libtesting': {'pyxfile': 'util/testing', - 'depends': ['pandas/util/testing.pyx']}, - 'util.libhashing': {'pyxfile': 'util/hashing', - 'depends': ['pandas/util/hashing.pyx']}, - 'io.sas.libsas': {'pyxfile': 'io/sas/sas'}, + '_libs.sparse': {'pyxfile': '_libs/sparse', + 'depends': (['pandas/core/sparse/sparse.pyx'] + + _pxi_dep['sparse'])}, + '_libs.testing': {'pyxfile': '_libs/testing', + 'depends': ['pandas/_libs/testing.pyx']}, + '_libs.hashing': {'pyxfile': '_libs/hashing', + 'depends': ['pandas/_libs/hashing.pyx']}, + 'io.sas._sas': {'pyxfile': 'io/sas/sas'}, } extensions = [] @@ -596,7 +596,7 @@ def pxd(name): root, _ = os.path.splitext(ext.sources[0]) ext.sources[0] = root + suffix -ujson_ext = Extension('pandas.io.json.libjson', +ujson_ext = Extension('pandas._libs.json', depends=['pandas/_libs/src/ujson/lib/ultrajson.h', 'pandas/_libs/src/datetime_helper.h', 'pandas/_libs/src/numpy_helper.h'], @@ -645,13 +645,16 @@ def pxd(name): 'pandas.core.reshape', 'pandas.core.sparse', 'pandas.core.tools', + 'pandas.core.util', 'pandas.computation', 'pandas.errors', + 'pandas.formats', 'pandas.io', 'pandas.io.json', 'pandas.io.sas', 'pandas.io.msgpack', 'pandas.io.formats', + 'pandas.io.clipboard', 'pandas._libs', 'pandas.plotting', 'pandas.stats', @@ -679,9 +682,9 @@ def pxd(name): 'pandas.tests.tseries', 'pandas.tests.plotting', 'pandas.tests.tools', + 'pandas.tests.util', 'pandas.tools', 'pandas.tseries', - 'pandas.util.clipboard' ], package_data={'pandas.tests': ['data/*.csv'], 'pandas.tests.indexes': ['data/*.pickle'], From ccc33dd2eb8617a2029dd02372d495d492079291 Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Fri, 5 May 2017 20:55:07 -0400 Subject: [PATCH 2/7] ENH: Provide dict object for to_dict() #16122 --- doc/source/whatsnew/v0.20.1.txt | 1 - doc/source/whatsnew/v0.21.0.txt | 1 + pandas/core/common.py | 6 +++--- pandas/core/frame.py | 2 +- pandas/core/series.py | 4 +--- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/doc/source/whatsnew/v0.20.1.txt b/doc/source/whatsnew/v0.20.1.txt index b6a41dbb4412f..504f8004bc8a6 100644 --- a/doc/source/whatsnew/v0.20.1.txt +++ b/doc/source/whatsnew/v0.20.1.txt @@ -18,7 +18,6 @@ Highlights include: Enhancements ~~~~~~~~~~~~ -- ``Series.to_dict()`` and ``DataFrame.to_dict()`` now support an ``into`` keyword which allows you to specify the ``collections.Mapping`` subclass that you would like returned. The default is ``dict``, which is backwards compatible. (:issue:`16122`) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 36dffc3d3378b..4beab02db26a8 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -26,6 +26,7 @@ New features Other Enhancements ^^^^^^^^^^^^^^^^^^ +- ``Series.to_dict()`` and ``DataFrame.to_dict()`` now support an ``into`` keyword which allows you to specify the ``collections.Mapping`` subclass that you would like returned. The default is ``dict``, which is backwards compatible. (:issue:`16122`) diff --git a/pandas/core/common.py b/pandas/core/common.py index 08cff034782b0..acc99679f6c28 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -483,7 +483,7 @@ def _dict_compat(d): def _standardize_mapping(into): """ - Helper function to standardize the supplied mapping so it can + Helper function to standardize the supplied mapping so it can be passed to the ``Series.to_dict()`` and ``DataFrame.to_dict()`` Parameters @@ -491,14 +491,14 @@ def _standardize_mapping(into): into : instance or subclass of collections.Mapping The argument supplied to ``to_dict``. Must be a class, an initialized collections.defaultdict, or an empty instance - of a collections.Mapping subclass. + of a collections.Mapping subclass. Returns ------- mapping : a collections.Mapping subclass or other constructor a callable object that can accept an iterator to create the desired Mapping. - + """ if not inspect.isclass(into): if len(into) > 0: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f1a87c303d18b..bc92fbdbf51f6 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -889,7 +889,7 @@ def to_dict(self, orient='dict', into=dict): instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized instance. - .. versionadded:: 0.20.1 + .. versionadded:: 0.21.0 Returns ------- diff --git a/pandas/core/series.py b/pandas/core/series.py index 709e4ff08ec90..f1854517ba146 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -9,7 +9,6 @@ import types import warnings from textwrap import dedent -import collections from numpy import nan, ndarray import numpy as np @@ -1086,7 +1085,7 @@ def to_dict(self, into=dict): object. Can be the actual class or an empty instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized - .. versionadded:: 0.20.1 + .. versionadded:: 0.21.0 Returns ------- @@ -1098,7 +1097,6 @@ def to_dict(self, into=dict): into_c = _standardize_mapping(into) return into_c(compat.iteritems(self)) - def to_frame(self, name=None): """ Convert Series to DataFrame From 67c57e82e017e089a11351807315c0270150652a Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Sun, 7 May 2017 20:10:18 -0400 Subject: [PATCH 3/7] ENH: Provide dict object for to_dict() #16122 --- doc/source/whatsnew/v0.20.0.txt | 1 + pandas/core/common.py | 8 +++--- pandas/core/frame.py | 44 +++++++++++++++++++++++++++++++-- pandas/core/series.py | 19 ++++++++++++-- pandas/tests/test_common.py | 14 +++++------ 5 files changed, 72 insertions(+), 14 deletions(-) diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 9d475390175b2..a0bf2f9b3758a 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -515,6 +515,7 @@ Other Enhancements - Options added to allow one to turn on/off using ``bottleneck`` and ``numexpr``, see :ref:`here ` (:issue:`16157`) - ``DataFrame.style.bar()`` now accepts two more options to further customize the bar chart. Bar alignment is set with ``align='left'|'mid'|'zero'``, the default is "left", which is backward compatible; You can now pass a list of ``color=[color_negative, color_positive]``. (:issue:`14757`) + .. _ISO 8601 duration: https://en.wikipedia.org/wiki/ISO_8601#Durations diff --git a/pandas/core/common.py b/pandas/core/common.py index acc99679f6c28..d8242d55a263d 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -481,10 +481,12 @@ def _dict_compat(d): for key, value in iteritems(d)) -def _standardize_mapping(into): +def prep_maping_for_to_dict(into): """ Helper function to standardize the supplied mapping so it can be passed to the ``Series.to_dict()`` and ``DataFrame.to_dict()`` + + .. versionadded:: 0.21.0 Parameters ---------- @@ -504,11 +506,11 @@ def _standardize_mapping(into): if len(into) > 0: raise ValueError( "to_dict() only accepts empty mappings.") - elif type(into) == collections.defaultdict: + elif isinstance(into, collections.defaultdict): return partial( collections.defaultdict, into.default_factory) else: - return _standardize_mapping(type(into)) + return prep_maping_for_to_dict(type(into)) elif not issubclass(into, collections.Mapping): raise TypeError('unsupported type: {}'.format(into)) elif into == collections.defaultdict: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index bc92fbdbf51f6..f6b351c3501a9 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -64,7 +64,7 @@ _values_from_object, _maybe_box_datetimelike, _dict_compat, - _standardize_mapping) + prep_maping_for_to_dict) from pandas.core.generic import NDFrame, _shared_docs from pandas.core.index import Index, MultiIndex, _ensure_index from pandas.core.indexing import (maybe_droplevels, convert_to_index_sliceable, @@ -889,6 +889,7 @@ def to_dict(self, orient='dict', into=dict): instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized instance. + .. versionadded:: 0.21.0 Returns @@ -896,12 +897,51 @@ def to_dict(self, orient='dict', into=dict): result : collections.Mapping like {column -> {index -> value}} If ``into`` is collections.defaultdict, the return value's default_factory will be None. + + Examples + -------- + >>> from pandas import DataFrame + >>> from collections import OrderedDict, defaultdict + >>> df = DataFrame({'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b']) + >>> df + col1 col2 + a 1 0.1 + b 2 0.2 + >>> df.to_dict() + {'col1': {'a': 1, 'b': 2}, 'col2': {'a': 0.5, 'b': 0.75}} + + You can specify the return orientation. + + >>> df.to_dict('series') + {'col1': a 1 + b 2 + Name: col1, dtype: int64, 'col2': a 0.50 + b 0.75 + Name: col2, dtype: float64} + >>> df.to_dict('split') + {'columns': ['col1', 'col2'], + 'data': [[1.0, 0.5], [2.0, 0.75]], + 'index': ['a', 'b']} + >>> df.to_dict('records') + [{'col1': 1.0, 'col2': 0.5}, {'col1': 2.0, 'col2': 0.75}] + >>> df.to_dict('index') + {'a': {'col1': 1.0, 'col2': 0.5}, 'b': {'col1': 2.0, 'col2': 0.75}} + + You can also specify the mapping type. + + >>> df.to_dict(into=OrderedDict) + OrderedDict([('col2', OrderedDict([('a', 0.5), ('b', 0.75)])), + ('col1', OrderedDict([('a', 1), ('b', 2)]))]) + >>> dd = defaultdict(list) + >>> df.to_dict('records', into=dd) + [defaultdict(list, {'col1': 1.0, 'col2': 0.5}), + defaultdict(list, {'col1': 2.0, 'col2': 0.75})] """ if not self.columns.is_unique: warnings.warn("DataFrame columns are not unique, some " "columns will be omitted.", UserWarning) # GH16122 - into_c = _standardize_mapping(into) + into_c = prep_maping_for_to_dict(into) if orient.lower().startswith('d'): return into_c( (k, v.to_dict(into)) for k, v in compat.iteritems(self)) diff --git a/pandas/core/series.py b/pandas/core/series.py index f1854517ba146..ec4f019835423 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -47,7 +47,7 @@ SettingWithCopyError, _maybe_box_datetimelike, _dict_compat, - _standardize_mapping) + prep_maping_for_to_dict) from pandas.core.index import (Index, MultiIndex, InvalidIndexError, Float64Index, _ensure_index) from pandas.core.indexing import check_bool_indexer, maybe_convert_indices @@ -1085,6 +1085,7 @@ def to_dict(self, into=dict): object. Can be the actual class or an empty instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized + .. versionadded:: 0.21.0 Returns @@ -1092,9 +1093,23 @@ def to_dict(self, into=dict): value_dict : collections.Mapping If ``into`` is collections.defaultdict, the return value's default_factory will be None. + + Examples + -------- + >>> from pandas import Series + >>> from collections import OrderedDict, defaultdict + >>> s = Series([1, 2, 3, 4]) + >>> s.to_dict() + {0: 1, 1: 2, 2: 3, 3: 4} + >>> s.to_dict(OrderedDict) + OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) + >>> dd = defaultdict(list) + >>> s.to_dict(dd) + defaultdict(list, {0: 1, 1: 2, 2: 3, 3: 4}) + """ # GH16122 - into_c = _standardize_mapping(into) + into_c = prep_maping_for_to_dict(into) return into_c(compat.iteritems(self)) def to_frame(self, name=None): diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index ccece52154dd3..04d494293f52f 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -199,26 +199,26 @@ def test_dict_compat(): assert (com._dict_compat(data_unchanged) == data_unchanged) -def test_standardize_mapping(): +def test_prep_maping_for_to_dict(): # No non-empty bad = {'bad': 'data'} with pytest.raises(ValueError): - com._standardize_mapping(bad) + com.prep_maping_for_to_dict(bad) # No uninitialized defaultdicts with pytest.raises(TypeError): - com._standardize_mapping(collections.defaultdict) + com.prep_maping_for_to_dict(collections.defaultdict) # No non-mapping subtypes, instance with pytest.raises(TypeError): - com._standardize_mapping([]) + com.prep_maping_for_to_dict([]) # No non-mapping subtypes, class with pytest.raises(TypeError): - com._standardize_mapping(list) + com.prep_maping_for_to_dict(list) # Convert instance to type - assert (com._standardize_mapping({}) == dict) + assert (com.prep_maping_for_to_dict({}) == dict) dd = collections.defaultdict(list) - assert (type(com._standardize_mapping(dd)) == partial) + assert (type(com.prep_maping_for_to_dict(dd)) == partial) From 546816b0852644b6055aab39c3eb578ba22d0255 Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Wed, 10 May 2017 22:01:33 -0400 Subject: [PATCH 4/7] ENH: Provide dict object for to_dict() #16122 --- pandas/core/common.py | 28 ++++++++++------------- pandas/core/frame.py | 32 +++++++++++++++------------ pandas/core/series.py | 11 +++++---- pandas/tests/frame/test_convert_to.py | 10 +++++++++ pandas/tests/test_common.py | 20 ++++++++--------- 5 files changed, 54 insertions(+), 47 deletions(-) diff --git a/pandas/core/common.py b/pandas/core/common.py index d8242d55a263d..f1b39cf7421d4 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -481,19 +481,16 @@ def _dict_compat(d): for key, value in iteritems(d)) -def prep_maping_for_to_dict(into): +def standardize_mapping(into): """ - Helper function to standardize the supplied mapping so it can - be passed to the ``Series.to_dict()`` and ``DataFrame.to_dict()`` - + Helper function to standardize a supplied mapping. .. versionadded:: 0.21.0 Parameters ---------- into : instance or subclass of collections.Mapping - The argument supplied to ``to_dict``. Must be a class, an - initialized collections.defaultdict, or an empty instance - of a collections.Mapping subclass. + Must be a class, an initialized collections.defaultdict, + or an empty instance of a collections.Mapping subclass. Returns ------- @@ -501,23 +498,22 @@ def prep_maping_for_to_dict(into): a callable object that can accept an iterator to create the desired Mapping. + See Also + -------- + DataFrame.to_dict + Series.to_dict """ if not inspect.isclass(into): - if len(into) > 0: - raise ValueError( - "to_dict() only accepts empty mappings.") - elif isinstance(into, collections.defaultdict): + if isinstance(into, collections.defaultdict): return partial( collections.defaultdict, into.default_factory) - else: - return prep_maping_for_to_dict(type(into)) - elif not issubclass(into, collections.Mapping): + into = type(into) + if not issubclass(into, collections.Mapping): raise TypeError('unsupported type: {}'.format(into)) elif into == collections.defaultdict: raise TypeError( 'to_dict() only accepts initialized defaultdicts') - else: - return into + return into def sentinel_factory(): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f6b351c3501a9..13617952e8aa4 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -64,7 +64,7 @@ _values_from_object, _maybe_box_datetimelike, _dict_compat, - prep_maping_for_to_dict) + standardize_mapping) from pandas.core.generic import NDFrame, _shared_docs from pandas.core.index import Index, MultiIndex, _ensure_index from pandas.core.indexing import (maybe_droplevels, convert_to_index_sliceable, @@ -889,7 +889,7 @@ def to_dict(self, orient='dict', into=dict): instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized instance. - + .. versionadded:: 0.21.0 Returns @@ -897,21 +897,22 @@ def to_dict(self, orient='dict', into=dict): result : collections.Mapping like {column -> {index -> value}} If ``into`` is collections.defaultdict, the return value's default_factory will be None. - + Examples -------- >>> from pandas import DataFrame >>> from collections import OrderedDict, defaultdict - >>> df = DataFrame({'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b']) + >>> df = DataFrame( + {'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b']) >>> df col1 col2 a 1 0.1 b 2 0.2 >>> df.to_dict() {'col1': {'a': 1, 'b': 2}, 'col2': {'a': 0.5, 'b': 0.75}} - + You can specify the return orientation. - + >>> df.to_dict('series') {'col1': a 1 b 2 @@ -926,22 +927,25 @@ def to_dict(self, orient='dict', into=dict): [{'col1': 1.0, 'col2': 0.5}, {'col1': 2.0, 'col2': 0.75}] >>> df.to_dict('index') {'a': {'col1': 1.0, 'col2': 0.5}, 'b': {'col1': 2.0, 'col2': 0.75}} - - You can also specify the mapping type. - + + You can also specify the mapping type. + >>> df.to_dict(into=OrderedDict) - OrderedDict([('col2', OrderedDict([('a', 0.5), ('b', 0.75)])), - ('col1', OrderedDict([('a', 1), ('b', 2)]))]) + OrderedDict([('col1', OrderedDict([('a', 1), ('b', 2)])), + ('col2', OrderedDict([('a', 0.5), ('b', 0.75)]))]) + + If you want a `defaultdict`, you need to initialize it: + >>> dd = defaultdict(list) >>> df.to_dict('records', into=dd) - [defaultdict(list, {'col1': 1.0, 'col2': 0.5}), - defaultdict(list, {'col1': 2.0, 'col2': 0.75})] + [defaultdict(, {'col2': 0.5, 'col1': 1.0}), + defaultdict(, {'col2': 0.75, 'col1': 2.0})] """ if not self.columns.is_unique: warnings.warn("DataFrame columns are not unique, some " "columns will be omitted.", UserWarning) # GH16122 - into_c = prep_maping_for_to_dict(into) + into_c = standardize_mapping(into) if orient.lower().startswith('d'): return into_c( (k, v.to_dict(into)) for k, v in compat.iteritems(self)) diff --git a/pandas/core/series.py b/pandas/core/series.py index ec4f019835423..0a08c983bfb05 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -47,7 +47,7 @@ SettingWithCopyError, _maybe_box_datetimelike, _dict_compat, - prep_maping_for_to_dict) + standardize_mapping) from pandas.core.index import (Index, MultiIndex, InvalidIndexError, Float64Index, _ensure_index) from pandas.core.indexing import check_bool_indexer, maybe_convert_indices @@ -1085,7 +1085,7 @@ def to_dict(self, into=dict): object. Can be the actual class or an empty instance of the mapping type you want. If you want a collections.defaultdict, you must pass an initialized - + .. versionadded:: 0.21.0 Returns @@ -1093,7 +1093,7 @@ def to_dict(self, into=dict): value_dict : collections.Mapping If ``into`` is collections.defaultdict, the return value's default_factory will be None. - + Examples -------- >>> from pandas import Series @@ -1105,11 +1105,10 @@ def to_dict(self, into=dict): OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) >>> dd = defaultdict(list) >>> s.to_dict(dd) - defaultdict(list, {0: 1, 1: 2, 2: 3, 3: 4}) - + defaultdict(, {0: 1, 1: 2, 2: 3, 3: 4}) """ # GH16122 - into_c = prep_maping_for_to_dict(into) + into_c = standardize_mapping(into) return into_c(compat.iteritems(self)) def to_frame(self, name=None): diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index 8f4fa1d383100..5eff3a7ff7c79 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -156,6 +156,7 @@ def test_to_dict(self, mapping): 'A': {'1': 1, '2': 2}, 'B': {'1': '1', '2': '2', '3': '3'}, } + # GH16122 recons_data = DataFrame(test_data).to_dict(into=mapping) @@ -196,6 +197,15 @@ def test_to_dict(self, mapping): for k2, v2 in compat.iteritems(v): assert (v2 == recons_data[k2][k]) + df = DataFrame(test_data) + df['duped'] = df[df.columns[0]] + recons_data = df.to_dict("i") + comp_data = test_data.copy() + comp_data['duped'] = comp_data[df.columns[0]] + for k, v in compat.iteritems(comp_data): + for k2, v2 in compat.iteritems(v): + assert (v2 == recons_data[k2][k]) + @pytest.mark.parametrize('tz', ['UTC', 'GMT', 'US/Eastern']) def test_to_records_datetimeindex_with_tz(self, tz): # GH13937 diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index 04d494293f52f..4893f99f7cf0f 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -199,26 +199,24 @@ def test_dict_compat(): assert (com._dict_compat(data_unchanged) == data_unchanged) -def test_prep_maping_for_to_dict(): - # No non-empty - bad = {'bad': 'data'} - with pytest.raises(ValueError): - com.prep_maping_for_to_dict(bad) - +def test_standardize_mapping(): # No uninitialized defaultdicts with pytest.raises(TypeError): - com.prep_maping_for_to_dict(collections.defaultdict) + com.standardize_mapping(collections.defaultdict) # No non-mapping subtypes, instance with pytest.raises(TypeError): - com.prep_maping_for_to_dict([]) + com.standardize_mapping([]) # No non-mapping subtypes, class with pytest.raises(TypeError): - com.prep_maping_for_to_dict(list) + com.standardize_mapping(list) + + fill = {'bad': 'data'} + assert (com.standardize_mapping(fill) == dict) # Convert instance to type - assert (com.prep_maping_for_to_dict({}) == dict) + assert (com.standardize_mapping({}) == dict) dd = collections.defaultdict(list) - assert (type(com.prep_maping_for_to_dict(dd)) == partial) + assert isinstance(com.standardize_mapping(dd), partial) From 086c598e7d30e5d1fc18f21e6245eeb8c45c2948 Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Thu, 11 May 2017 21:35:13 -0400 Subject: [PATCH 5/7] ENH: Provide dict object for to_dict() #16122 --- pandas/core/common.py | 3 ++- pandas/core/frame.py | 3 +-- pandas/core/series.py | 2 +- pandas/tests/frame/test_convert_to.py | 10 ++++++++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/pandas/core/common.py b/pandas/core/common.py index f1b39cf7421d4..0dc6a7a1e9c7b 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -484,13 +484,14 @@ def _dict_compat(d): def standardize_mapping(into): """ Helper function to standardize a supplied mapping. + .. versionadded:: 0.21.0 Parameters ---------- into : instance or subclass of collections.Mapping Must be a class, an initialized collections.defaultdict, - or an empty instance of a collections.Mapping subclass. + or an instance of a collections.Mapping subclass. Returns ------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 13617952e8aa4..1f47ecfd2d01d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -887,8 +887,7 @@ def to_dict(self, orient='dict', into=dict): The collections.Mapping subclass used for all Mappings in the return value. Can be the actual class or an empty instance of the mapping type you want. If you want a - collections.defaultdict, you must pass an initialized - instance. + collections.defaultdict, you must pass it initialized. .. versionadded:: 0.21.0 diff --git a/pandas/core/series.py b/pandas/core/series.py index 0a08c983bfb05..8d6096801cb4a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1084,7 +1084,7 @@ def to_dict(self, into=dict): The collections.Mapping subclass to use as the return object. Can be the actual class or an empty instance of the mapping type you want. If you want a - collections.defaultdict, you must pass an initialized + collections.defaultdict, you must pass it initialized. .. versionadded:: 0.21.0 diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index 5eff3a7ff7c79..34dd138ee1c80 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -206,6 +206,16 @@ def test_to_dict(self, mapping): for k2, v2 in compat.iteritems(v): assert (v2 == recons_data[k2][k]) + @pytest.mark.parametrize('mapping', [ + list, + collections.defaultdict, + []]) + def test_to_dict_errors(self, mapping): + # GH16122 + df = DataFrame(np.random.randn(3, 3)) + with pytest.raises(TypeError): + df.to_dict(into=mapping) + @pytest.mark.parametrize('tz', ['UTC', 'GMT', 'US/Eastern']) def test_to_records_datetimeindex_with_tz(self, tz): # GH13937 From d6c0debfbf95a40929b47c6c62d7199e14435fc9 Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Fri, 12 May 2017 19:11:55 -0400 Subject: [PATCH 6/7] ENH: Provide dict object for to_dict() #16122 --- pandas/core/frame.py | 8 ++------ pandas/core/series.py | 8 ++++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 1f47ecfd2d01d..855d345b766f0 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -894,14 +894,10 @@ def to_dict(self, orient='dict', into=dict): Returns ------- result : collections.Mapping like {column -> {index -> value}} - If ``into`` is collections.defaultdict, the return - value's default_factory will be None. Examples -------- - >>> from pandas import DataFrame - >>> from collections import OrderedDict, defaultdict - >>> df = DataFrame( + >>> df = pd.DataFrame( {'col1': [1, 2], 'col2': [0.5, 0.75]}, index=['a', 'b']) >>> df col1 col2 @@ -928,7 +924,7 @@ def to_dict(self, orient='dict', into=dict): {'a': {'col1': 1.0, 'col2': 0.5}, 'b': {'col1': 2.0, 'col2': 0.75}} You can also specify the mapping type. - + >>> from collections import OrderedDict, defaultdict >>> df.to_dict(into=OrderedDict) OrderedDict([('col1', OrderedDict([('a', 1), ('b', 2)])), ('col2', OrderedDict([('a', 0.5), ('b', 0.75)]))]) diff --git a/pandas/core/series.py b/pandas/core/series.py index 8d6096801cb4a..2f71ebaa9f3cc 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1077,7 +1077,8 @@ def tolist(self): def to_dict(self, into=dict): """ - Convert Series to {label -> value} dict or dict-like object + Convert Series to {label -> value} dict or dict-like object. + Parameters ---------- into : class, default dict @@ -1096,11 +1097,10 @@ def to_dict(self, into=dict): Examples -------- - >>> from pandas import Series - >>> from collections import OrderedDict, defaultdict - >>> s = Series([1, 2, 3, 4]) + >>> s = pd.Series([1, 2, 3, 4]) >>> s.to_dict() {0: 1, 1: 2, 2: 3, 3: 4} + >>> from collections import OrderedDict, defaultdict >>> s.to_dict(OrderedDict) OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) >>> dd = defaultdict(list) From 8469977d6e582aeeeff5a523ade0e14fba937ecd Mon Sep 17 00:00:00 2001 From: Dan Kenefick Date: Mon, 15 May 2017 21:01:41 -0400 Subject: [PATCH 7/7] ENH: Provide dict object for to_dict() #16122 --- pandas/core/frame.py | 1 + pandas/core/series.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 0347d7b73d42b..3b0cc5619a1cd 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -924,6 +924,7 @@ def to_dict(self, orient='dict', into=dict): {'a': {'col1': 1.0, 'col2': 0.5}, 'b': {'col1': 2.0, 'col2': 0.75}} You can also specify the mapping type. + >>> from collections import OrderedDict, defaultdict >>> df.to_dict(into=OrderedDict) OrderedDict([('col1', OrderedDict([('a', 1), ('b', 2)])), diff --git a/pandas/core/series.py b/pandas/core/series.py index 2f71ebaa9f3cc..129f291e5f843 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1092,8 +1092,6 @@ def to_dict(self, into=dict): Returns ------- value_dict : collections.Mapping - If ``into`` is collections.defaultdict, the return - value's default_factory will be None. Examples --------