You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			384 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			384 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
from __future__ import annotations
 | 
						|
 | 
						|
import pytest
 | 
						|
 | 
						|
import pandas as pd
 | 
						|
from pandas import api
 | 
						|
import pandas._testing as tm
 | 
						|
from pandas.api import (
 | 
						|
    extensions as api_extensions,
 | 
						|
    indexers as api_indexers,
 | 
						|
    interchange as api_interchange,
 | 
						|
    types as api_types,
 | 
						|
    typing as api_typing,
 | 
						|
)
 | 
						|
 | 
						|
 | 
						|
class Base:
 | 
						|
    def check(self, namespace, expected, ignored=None):
 | 
						|
        # see which names are in the namespace, minus optional
 | 
						|
        # ignored ones
 | 
						|
        # compare vs the expected
 | 
						|
 | 
						|
        result = sorted(
 | 
						|
            f for f in dir(namespace) if not f.startswith("__") and f != "annotations"
 | 
						|
        )
 | 
						|
        if ignored is not None:
 | 
						|
            result = sorted(set(result) - set(ignored))
 | 
						|
 | 
						|
        expected = sorted(expected)
 | 
						|
        tm.assert_almost_equal(result, expected)
 | 
						|
 | 
						|
 | 
						|
class TestPDApi(Base):
 | 
						|
    # these are optionally imported based on testing
 | 
						|
    # & need to be ignored
 | 
						|
    ignored = ["tests", "locale", "conftest", "_version_meson"]
 | 
						|
 | 
						|
    # top-level sub-packages
 | 
						|
    public_lib = [
 | 
						|
        "api",
 | 
						|
        "arrays",
 | 
						|
        "options",
 | 
						|
        "test",
 | 
						|
        "testing",
 | 
						|
        "errors",
 | 
						|
        "plotting",
 | 
						|
        "io",
 | 
						|
        "tseries",
 | 
						|
    ]
 | 
						|
    private_lib = ["compat", "core", "pandas", "util", "_built_with_meson"]
 | 
						|
 | 
						|
    # misc
 | 
						|
    misc = ["IndexSlice", "NaT", "NA"]
 | 
						|
 | 
						|
    # top-level classes
 | 
						|
    classes = [
 | 
						|
        "ArrowDtype",
 | 
						|
        "Categorical",
 | 
						|
        "CategoricalIndex",
 | 
						|
        "DataFrame",
 | 
						|
        "DateOffset",
 | 
						|
        "DatetimeIndex",
 | 
						|
        "ExcelFile",
 | 
						|
        "ExcelWriter",
 | 
						|
        "Flags",
 | 
						|
        "Grouper",
 | 
						|
        "HDFStore",
 | 
						|
        "Index",
 | 
						|
        "MultiIndex",
 | 
						|
        "Period",
 | 
						|
        "PeriodIndex",
 | 
						|
        "RangeIndex",
 | 
						|
        "Series",
 | 
						|
        "SparseDtype",
 | 
						|
        "StringDtype",
 | 
						|
        "Timedelta",
 | 
						|
        "TimedeltaIndex",
 | 
						|
        "Timestamp",
 | 
						|
        "Interval",
 | 
						|
        "IntervalIndex",
 | 
						|
        "CategoricalDtype",
 | 
						|
        "PeriodDtype",
 | 
						|
        "IntervalDtype",
 | 
						|
        "DatetimeTZDtype",
 | 
						|
        "BooleanDtype",
 | 
						|
        "Int8Dtype",
 | 
						|
        "Int16Dtype",
 | 
						|
        "Int32Dtype",
 | 
						|
        "Int64Dtype",
 | 
						|
        "UInt8Dtype",
 | 
						|
        "UInt16Dtype",
 | 
						|
        "UInt32Dtype",
 | 
						|
        "UInt64Dtype",
 | 
						|
        "Float32Dtype",
 | 
						|
        "Float64Dtype",
 | 
						|
        "NamedAgg",
 | 
						|
    ]
 | 
						|
 | 
						|
    # these are already deprecated; awaiting removal
 | 
						|
    deprecated_classes: list[str] = []
 | 
						|
 | 
						|
    # external modules exposed in pandas namespace
 | 
						|
    modules: list[str] = []
 | 
						|
 | 
						|
    # top-level functions
 | 
						|
    funcs = [
 | 
						|
        "array",
 | 
						|
        "bdate_range",
 | 
						|
        "concat",
 | 
						|
        "crosstab",
 | 
						|
        "cut",
 | 
						|
        "date_range",
 | 
						|
        "interval_range",
 | 
						|
        "eval",
 | 
						|
        "factorize",
 | 
						|
        "get_dummies",
 | 
						|
        "from_dummies",
 | 
						|
        "infer_freq",
 | 
						|
        "isna",
 | 
						|
        "isnull",
 | 
						|
        "lreshape",
 | 
						|
        "melt",
 | 
						|
        "notna",
 | 
						|
        "notnull",
 | 
						|
        "offsets",
 | 
						|
        "merge",
 | 
						|
        "merge_ordered",
 | 
						|
        "merge_asof",
 | 
						|
        "period_range",
 | 
						|
        "pivot",
 | 
						|
        "pivot_table",
 | 
						|
        "qcut",
 | 
						|
        "show_versions",
 | 
						|
        "timedelta_range",
 | 
						|
        "unique",
 | 
						|
        "value_counts",
 | 
						|
        "wide_to_long",
 | 
						|
    ]
 | 
						|
 | 
						|
    # top-level option funcs
 | 
						|
    funcs_option = [
 | 
						|
        "reset_option",
 | 
						|
        "describe_option",
 | 
						|
        "get_option",
 | 
						|
        "option_context",
 | 
						|
        "set_option",
 | 
						|
        "set_eng_float_format",
 | 
						|
    ]
 | 
						|
 | 
						|
    # top-level read_* funcs
 | 
						|
    funcs_read = [
 | 
						|
        "read_clipboard",
 | 
						|
        "read_csv",
 | 
						|
        "read_excel",
 | 
						|
        "read_fwf",
 | 
						|
        "read_gbq",
 | 
						|
        "read_hdf",
 | 
						|
        "read_html",
 | 
						|
        "read_xml",
 | 
						|
        "read_json",
 | 
						|
        "read_pickle",
 | 
						|
        "read_sas",
 | 
						|
        "read_sql",
 | 
						|
        "read_sql_query",
 | 
						|
        "read_sql_table",
 | 
						|
        "read_stata",
 | 
						|
        "read_table",
 | 
						|
        "read_feather",
 | 
						|
        "read_parquet",
 | 
						|
        "read_orc",
 | 
						|
        "read_spss",
 | 
						|
    ]
 | 
						|
 | 
						|
    # top-level json funcs
 | 
						|
    funcs_json = ["json_normalize"]
 | 
						|
 | 
						|
    # top-level to_* funcs
 | 
						|
    funcs_to = ["to_datetime", "to_numeric", "to_pickle", "to_timedelta"]
 | 
						|
 | 
						|
    # top-level to deprecate in the future
 | 
						|
    deprecated_funcs_in_future: list[str] = []
 | 
						|
 | 
						|
    # these are already deprecated; awaiting removal
 | 
						|
    deprecated_funcs: list[str] = []
 | 
						|
 | 
						|
    # private modules in pandas namespace
 | 
						|
    private_modules = [
 | 
						|
        "_config",
 | 
						|
        "_libs",
 | 
						|
        "_is_numpy_dev",
 | 
						|
        "_pandas_datetime_CAPI",
 | 
						|
        "_pandas_parser_CAPI",
 | 
						|
        "_testing",
 | 
						|
        "_typing",
 | 
						|
    ]
 | 
						|
    if not pd._built_with_meson:
 | 
						|
        private_modules.append("_version")
 | 
						|
 | 
						|
    def test_api(self):
 | 
						|
        checkthese = (
 | 
						|
            self.public_lib
 | 
						|
            + self.private_lib
 | 
						|
            + self.misc
 | 
						|
            + self.modules
 | 
						|
            + self.classes
 | 
						|
            + self.funcs
 | 
						|
            + self.funcs_option
 | 
						|
            + self.funcs_read
 | 
						|
            + self.funcs_json
 | 
						|
            + self.funcs_to
 | 
						|
            + self.private_modules
 | 
						|
        )
 | 
						|
        self.check(namespace=pd, expected=checkthese, ignored=self.ignored)
 | 
						|
 | 
						|
    def test_api_all(self):
 | 
						|
        expected = set(
 | 
						|
            self.public_lib
 | 
						|
            + self.misc
 | 
						|
            + self.modules
 | 
						|
            + self.classes
 | 
						|
            + self.funcs
 | 
						|
            + self.funcs_option
 | 
						|
            + self.funcs_read
 | 
						|
            + self.funcs_json
 | 
						|
            + self.funcs_to
 | 
						|
        ) - set(self.deprecated_classes)
 | 
						|
        actual = set(pd.__all__)
 | 
						|
 | 
						|
        extraneous = actual - expected
 | 
						|
        assert not extraneous
 | 
						|
 | 
						|
        missing = expected - actual
 | 
						|
        assert not missing
 | 
						|
 | 
						|
    def test_depr(self):
 | 
						|
        deprecated_list = (
 | 
						|
            self.deprecated_classes
 | 
						|
            + self.deprecated_funcs
 | 
						|
            + self.deprecated_funcs_in_future
 | 
						|
        )
 | 
						|
        for depr in deprecated_list:
 | 
						|
            with tm.assert_produces_warning(FutureWarning):
 | 
						|
                _ = getattr(pd, depr)
 | 
						|
 | 
						|
 | 
						|
class TestApi(Base):
 | 
						|
    allowed_api_dirs = [
 | 
						|
        "types",
 | 
						|
        "extensions",
 | 
						|
        "indexers",
 | 
						|
        "interchange",
 | 
						|
        "typing",
 | 
						|
    ]
 | 
						|
    allowed_typing = [
 | 
						|
        "DataFrameGroupBy",
 | 
						|
        "DatetimeIndexResamplerGroupby",
 | 
						|
        "Expanding",
 | 
						|
        "ExpandingGroupby",
 | 
						|
        "ExponentialMovingWindow",
 | 
						|
        "ExponentialMovingWindowGroupby",
 | 
						|
        "JsonReader",
 | 
						|
        "NaTType",
 | 
						|
        "NAType",
 | 
						|
        "PeriodIndexResamplerGroupby",
 | 
						|
        "Resampler",
 | 
						|
        "Rolling",
 | 
						|
        "RollingGroupby",
 | 
						|
        "SeriesGroupBy",
 | 
						|
        "StataReader",
 | 
						|
        "TimedeltaIndexResamplerGroupby",
 | 
						|
        "TimeGrouper",
 | 
						|
        "Window",
 | 
						|
    ]
 | 
						|
    allowed_api_types = [
 | 
						|
        "is_any_real_numeric_dtype",
 | 
						|
        "is_array_like",
 | 
						|
        "is_bool",
 | 
						|
        "is_bool_dtype",
 | 
						|
        "is_categorical_dtype",
 | 
						|
        "is_complex",
 | 
						|
        "is_complex_dtype",
 | 
						|
        "is_datetime64_any_dtype",
 | 
						|
        "is_datetime64_dtype",
 | 
						|
        "is_datetime64_ns_dtype",
 | 
						|
        "is_datetime64tz_dtype",
 | 
						|
        "is_dict_like",
 | 
						|
        "is_dtype_equal",
 | 
						|
        "is_extension_array_dtype",
 | 
						|
        "is_file_like",
 | 
						|
        "is_float",
 | 
						|
        "is_float_dtype",
 | 
						|
        "is_hashable",
 | 
						|
        "is_int64_dtype",
 | 
						|
        "is_integer",
 | 
						|
        "is_integer_dtype",
 | 
						|
        "is_interval",
 | 
						|
        "is_interval_dtype",
 | 
						|
        "is_iterator",
 | 
						|
        "is_list_like",
 | 
						|
        "is_named_tuple",
 | 
						|
        "is_number",
 | 
						|
        "is_numeric_dtype",
 | 
						|
        "is_object_dtype",
 | 
						|
        "is_period_dtype",
 | 
						|
        "is_re",
 | 
						|
        "is_re_compilable",
 | 
						|
        "is_scalar",
 | 
						|
        "is_signed_integer_dtype",
 | 
						|
        "is_sparse",
 | 
						|
        "is_string_dtype",
 | 
						|
        "is_timedelta64_dtype",
 | 
						|
        "is_timedelta64_ns_dtype",
 | 
						|
        "is_unsigned_integer_dtype",
 | 
						|
        "pandas_dtype",
 | 
						|
        "infer_dtype",
 | 
						|
        "union_categoricals",
 | 
						|
        "CategoricalDtype",
 | 
						|
        "DatetimeTZDtype",
 | 
						|
        "IntervalDtype",
 | 
						|
        "PeriodDtype",
 | 
						|
    ]
 | 
						|
    allowed_api_interchange = ["from_dataframe", "DataFrame"]
 | 
						|
    allowed_api_indexers = [
 | 
						|
        "check_array_indexer",
 | 
						|
        "BaseIndexer",
 | 
						|
        "FixedForwardWindowIndexer",
 | 
						|
        "VariableOffsetWindowIndexer",
 | 
						|
    ]
 | 
						|
    allowed_api_extensions = [
 | 
						|
        "no_default",
 | 
						|
        "ExtensionDtype",
 | 
						|
        "register_extension_dtype",
 | 
						|
        "register_dataframe_accessor",
 | 
						|
        "register_index_accessor",
 | 
						|
        "register_series_accessor",
 | 
						|
        "take",
 | 
						|
        "ExtensionArray",
 | 
						|
        "ExtensionScalarOpsMixin",
 | 
						|
    ]
 | 
						|
 | 
						|
    def test_api(self):
 | 
						|
        self.check(api, self.allowed_api_dirs)
 | 
						|
 | 
						|
    def test_api_typing(self):
 | 
						|
        self.check(api_typing, self.allowed_typing)
 | 
						|
 | 
						|
    def test_api_types(self):
 | 
						|
        self.check(api_types, self.allowed_api_types)
 | 
						|
 | 
						|
    def test_api_interchange(self):
 | 
						|
        self.check(api_interchange, self.allowed_api_interchange)
 | 
						|
 | 
						|
    def test_api_indexers(self):
 | 
						|
        self.check(api_indexers, self.allowed_api_indexers)
 | 
						|
 | 
						|
    def test_api_extensions(self):
 | 
						|
        self.check(api_extensions, self.allowed_api_extensions)
 | 
						|
 | 
						|
 | 
						|
class TestTesting(Base):
 | 
						|
    funcs = [
 | 
						|
        "assert_frame_equal",
 | 
						|
        "assert_series_equal",
 | 
						|
        "assert_index_equal",
 | 
						|
        "assert_extension_array_equal",
 | 
						|
    ]
 | 
						|
 | 
						|
    def test_testing(self):
 | 
						|
        from pandas import testing
 | 
						|
 | 
						|
        self.check(testing, self.funcs)
 | 
						|
 | 
						|
    def test_util_in_top_level(self):
 | 
						|
        with pytest.raises(AttributeError, match="foo"):
 | 
						|
            pd.util.foo
 | 
						|
 | 
						|
 | 
						|
def test_pandas_array_alias():
 | 
						|
    msg = "PandasArray has been renamed NumpyExtensionArray"
 | 
						|
    with tm.assert_produces_warning(FutureWarning, match=msg):
 | 
						|
        res = pd.arrays.PandasArray
 | 
						|
 | 
						|
    assert res is pd.arrays.NumpyExtensionArray
 |