diff --git a/pandas/__init__.py b/pandas/__init__.py index 1c4151372273b..01ff2e1e1f181 100644 --- a/pandas/__init__.py +++ b/pandas/__init__.py @@ -1,4 +1,5 @@ # flake8: noqa +from __future__ import annotations __docformat__ = "restructuredtext" @@ -185,7 +186,7 @@ __deprecated_num_index_names = ["Float64Index", "Int64Index", "UInt64Index"] -def __dir__(): +def __dir__() -> list[str]: # GH43028 # Int64Index etc. are deprecated, but we still want them to be available in the dir. # Remove in Pandas 2.0, when we remove Int64Index etc. from the code base. diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 756c3b2d4b2b6..eacbf1b016432 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -60,6 +60,7 @@ Callable, Generic, Iterable, + Iterator, NamedTuple, cast, ) @@ -435,13 +436,13 @@ def __init__(self, *args) -> None: self.ops = list(zip(args[::2], args[1::2])) - def __enter__(self): + def __enter__(self) -> None: self.undo = [(pat, _get_option(pat, silent=True)) for pat, val in self.ops] for pat, val in self.ops: _set_option(pat, val, silent=True) - def __exit__(self, *args): + def __exit__(self, *args) -> None: if self.undo: for pat, val in self.undo: _set_option(pat, val, silent=True) @@ -733,7 +734,7 @@ def pp(name: str, ks: Iterable[str]) -> list[str]: @contextmanager -def config_prefix(prefix): +def config_prefix(prefix) -> Iterator[None]: """ contextmanager for multiple invocations of API with a common prefix diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index 9d3e84dc964d6..0fcea111716ec 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -238,7 +238,7 @@ _testing_mode_warnings = (DeprecationWarning, ResourceWarning) -def set_testing_mode(): +def set_testing_mode() -> None: # set the testing mode filters testing_mode = os.environ.get("PANDAS_TESTING_MODE", "None") if "deprecate" in testing_mode: @@ -246,7 +246,7 @@ def set_testing_mode(): warnings.simplefilter("always", category) -def reset_testing_mode(): +def reset_testing_mode() -> None: # reset the testing mode filters testing_mode = os.environ.get("PANDAS_TESTING_MODE", "None") if "deprecate" in testing_mode: @@ -257,7 +257,7 @@ def reset_testing_mode(): set_testing_mode() -def reset_display_options(): +def reset_display_options() -> None: """ Reset the display options for printing and representing objects. """ @@ -333,16 +333,16 @@ def to_array(obj): # Others -def getCols(k): +def getCols(k) -> str: return string.ascii_uppercase[:k] # make index -def makeStringIndex(k=10, name=None): +def makeStringIndex(k=10, name=None) -> Index: return Index(rands_array(nchars=10, size=k), name=name) -def makeCategoricalIndex(k=10, n=3, name=None, **kwargs): +def makeCategoricalIndex(k=10, n=3, name=None, **kwargs) -> CategoricalIndex: """make a length k index or n categories""" x = rands_array(nchars=4, size=n, replace=False) return CategoricalIndex( @@ -350,13 +350,13 @@ def makeCategoricalIndex(k=10, n=3, name=None, **kwargs): ) -def makeIntervalIndex(k=10, name=None, **kwargs): +def makeIntervalIndex(k=10, name=None, **kwargs) -> IntervalIndex: """make a length k IntervalIndex""" x = np.linspace(0, 100, num=(k + 1)) return IntervalIndex.from_breaks(x, name=name, **kwargs) -def makeBoolIndex(k=10, name=None): +def makeBoolIndex(k=10, name=None) -> Index: if k == 1: return Index([True], name=name) elif k == 2: @@ -364,7 +364,7 @@ def makeBoolIndex(k=10, name=None): return Index([False, True] + [False] * (k - 2), name=name) -def makeNumericIndex(k=10, name=None, *, dtype): +def makeNumericIndex(k=10, name=None, *, dtype) -> NumericIndex: dtype = pandas_dtype(dtype) assert isinstance(dtype, np.dtype) @@ -382,21 +382,21 @@ def makeNumericIndex(k=10, name=None, *, dtype): return NumericIndex(values, dtype=dtype, name=name) -def makeIntIndex(k=10, name=None): +def makeIntIndex(k=10, name=None) -> Int64Index: base_idx = makeNumericIndex(k, name=name, dtype="int64") return Int64Index(base_idx) -def makeUIntIndex(k=10, name=None): +def makeUIntIndex(k=10, name=None) -> UInt64Index: base_idx = makeNumericIndex(k, name=name, dtype="uint64") return UInt64Index(base_idx) -def makeRangeIndex(k=10, name=None, **kwargs): +def makeRangeIndex(k=10, name=None, **kwargs) -> RangeIndex: return RangeIndex(0, k, 1, name=name, **kwargs) -def makeFloatIndex(k=10, name=None): +def makeFloatIndex(k=10, name=None) -> Float64Index: base_idx = makeNumericIndex(k, name=name, dtype="float64") return Float64Index(base_idx) @@ -456,34 +456,34 @@ def all_timeseries_index_generator(k: int = 10) -> Iterable[Index]: # make series -def make_rand_series(name=None, dtype=np.float64): +def make_rand_series(name=None, dtype=np.float64) -> Series: index = makeStringIndex(_N) data = np.random.randn(_N) data = data.astype(dtype, copy=False) return Series(data, index=index, name=name) -def makeFloatSeries(name=None): +def makeFloatSeries(name=None) -> Series: return make_rand_series(name=name) -def makeStringSeries(name=None): +def makeStringSeries(name=None) -> Series: return make_rand_series(name=name) -def makeObjectSeries(name=None): +def makeObjectSeries(name=None) -> Series: data = makeStringIndex(_N) data = Index(data, dtype=object) index = makeStringIndex(_N) return Series(data, index=index, name=name) -def getSeriesData(): +def getSeriesData() -> dict[str, Series]: index = makeStringIndex(_N) return {c: Series(np.random.randn(_N), index=index) for c in getCols(_K)} -def makeTimeSeries(nper=None, freq="B", name=None): +def makeTimeSeries(nper=None, freq="B", name=None) -> Series: if nper is None: nper = _N return Series( @@ -491,22 +491,22 @@ def makeTimeSeries(nper=None, freq="B", name=None): ) -def makePeriodSeries(nper=None, name=None): +def makePeriodSeries(nper=None, name=None) -> Series: if nper is None: nper = _N return Series(np.random.randn(nper), index=makePeriodIndex(nper), name=name) -def getTimeSeriesData(nper=None, freq="B"): +def getTimeSeriesData(nper=None, freq="B") -> dict[str, Series]: return {c: makeTimeSeries(nper, freq) for c in getCols(_K)} -def getPeriodData(nper=None): +def getPeriodData(nper=None) -> dict[str, Series]: return {c: makePeriodSeries(nper) for c in getCols(_K)} # make frame -def makeTimeDataFrame(nper=None, freq="B"): +def makeTimeDataFrame(nper=None, freq="B") -> DataFrame: data = getTimeSeriesData(nper, freq) return DataFrame(data) @@ -533,14 +533,19 @@ def makeMixedDataFrame(): return DataFrame(getMixedTypeDict()[1]) -def makePeriodFrame(nper=None): +def makePeriodFrame(nper=None) -> DataFrame: data = getPeriodData(nper) return DataFrame(data) def makeCustomIndex( - nentries, nlevels, prefix="#", names=False, ndupe_l=None, idx_type=None -): + nentries, + nlevels, + prefix="#", + names: bool | str | list[str] | None = False, + ndupe_l=None, + idx_type=None, +) -> Index: """ Create an index/multindex with given dimensions, levels, names, etc' @@ -637,7 +642,8 @@ def keyfunc(x): # convert tuples to index if nentries == 1: # we have a single level of tuples, i.e. a regular Index - index = Index(tuples[0], name=names[0]) + name = None if names is None else names[0] + index = Index(tuples[0], name=name) elif nlevels == 1: name = None if names is None else names[0] index = Index((x[0] for x in tuples), name=name) @@ -659,7 +665,7 @@ def makeCustomDataframe( dtype=None, c_idx_type=None, r_idx_type=None, -): +) -> DataFrame: """ Create a DataFrame using supplied parameters. @@ -780,7 +786,7 @@ def _gen_unique_rand(rng, _extra_size): return i.tolist(), j.tolist() -def makeMissingDataframe(density=0.9, random_state=None): +def makeMissingDataframe(density=0.9, random_state=None) -> DataFrame: df = makeDataFrame() i, j = _create_missing_idx(*df.shape, density=density, random_state=random_state) df.values[i, j] = np.nan @@ -854,7 +860,7 @@ def skipna_wrapper(x): return skipna_wrapper -def convert_rows_list_to_csv_str(rows_list: list[str]): +def convert_rows_list_to_csv_str(rows_list: list[str]) -> str: """ Convert list of CSV rows to single CSV-formatted string for current OS. diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 46f1545a67fab..d1acdff8d2fd7 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -250,7 +250,7 @@ def wrapper(*args, **kwargs): return wrapper -def can_connect(url, error_classes=None): +def can_connect(url, error_classes=None) -> bool: """ Try to connect to the given url. True if succeeds, False if OSError raised @@ -424,7 +424,7 @@ def write_to_compressed(compression, path, data, dest="test"): # Plotting -def close(fignum=None): +def close(fignum=None) -> None: from matplotlib.pyplot import ( close as _close, get_fignums, diff --git a/pandas/_testing/_random.py b/pandas/_testing/_random.py index cce6bf8da7d3e..880fffea21bd1 100644 --- a/pandas/_testing/_random.py +++ b/pandas/_testing/_random.py @@ -14,7 +14,7 @@ def randbool(size=(), p: float = 0.5): ) -def rands_array(nchars, size, dtype="O", replace=True): +def rands_array(nchars, size, dtype="O", replace=True) -> np.ndarray: """ Generate an array of byte strings. """ @@ -26,7 +26,7 @@ def rands_array(nchars, size, dtype="O", replace=True): return retval.astype(dtype) -def rands(nchars): +def rands(nchars) -> str: """ Generate one random byte string. diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index 90ee600c1967d..5e8b553b352c8 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -68,7 +68,7 @@ def assert_almost_equal( rtol: float = 1.0e-5, atol: float = 1.0e-8, **kwargs, -): +) -> None: """ Check that the left and right objects are approximately equal. @@ -239,7 +239,7 @@ def _check_isinstance(left, right, cls): ) -def assert_dict_equal(left, right, compare_keys: bool = True): +def assert_dict_equal(left, right, compare_keys: bool = True) -> None: _check_isinstance(left, right, dict) _testing.assert_dict_equal(left, right, compare_keys=compare_keys) @@ -428,7 +428,7 @@ def _get_ilevel_values(index, level): assert_categorical_equal(left._values, right._values, obj=f"{obj} category") -def assert_class_equal(left, right, exact: bool | str = True, obj="Input"): +def assert_class_equal(left, right, exact: bool | str = True, obj="Input") -> None: """ Checks classes are equal. """ @@ -455,7 +455,7 @@ def repr_class(x): raise_assert_detail(obj, msg, repr_class(left), repr_class(right)) -def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"): +def assert_attr_equal(attr: str, left, right, obj: str = "Attributes") -> None: """ Check attributes are equal. Both objects must have attribute. @@ -474,11 +474,9 @@ def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"): left_attr = getattr(left, attr) right_attr = getattr(right, attr) - if left_attr is right_attr: - return True - elif is_matching_na(left_attr, right_attr): + if left_attr is right_attr or is_matching_na(left_attr, right_attr): # e.g. both np.nan, both NaT, both pd.NA, ... - return True + return None try: result = left_attr == right_attr @@ -490,14 +488,13 @@ def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"): elif not isinstance(result, bool): result = result.all() - if result: - return True - else: + if not result: msg = f'Attribute "{attr}" are different' raise_assert_detail(obj, msg, left_attr, right_attr) + return None -def assert_is_valid_plot_return_object(objs): +def assert_is_valid_plot_return_object(objs) -> None: import matplotlib.pyplot as plt if isinstance(objs, (Series, np.ndarray)): @@ -516,7 +513,7 @@ def assert_is_valid_plot_return_object(objs): assert isinstance(objs, (plt.Artist, tuple, dict)), msg -def assert_is_sorted(seq): +def assert_is_sorted(seq) -> None: """Assert that the sequence is sorted.""" if isinstance(seq, (Index, Series)): seq = seq.values @@ -526,7 +523,7 @@ def assert_is_sorted(seq): def assert_categorical_equal( left, right, check_dtype=True, check_category_order=True, obj="Categorical" -): +) -> None: """ Test that Categoricals are equivalent. @@ -581,7 +578,9 @@ def assert_categorical_equal( assert_attr_equal("ordered", left, right, obj=obj) -def assert_interval_array_equal(left, right, exact="equiv", obj="IntervalArray"): +def assert_interval_array_equal( + left, right, exact="equiv", obj="IntervalArray" +) -> None: """ Test that two IntervalArrays are equivalent. @@ -610,14 +609,16 @@ def assert_interval_array_equal(left, right, exact="equiv", obj="IntervalArray") assert_attr_equal("inclusive", left, right, obj=obj) -def assert_period_array_equal(left, right, obj="PeriodArray"): +def assert_period_array_equal(left, right, obj="PeriodArray") -> None: _check_isinstance(left, right, PeriodArray) assert_numpy_array_equal(left._data, right._data, obj=f"{obj}._data") assert_attr_equal("freq", left, right, obj=obj) -def assert_datetime_array_equal(left, right, obj="DatetimeArray", check_freq=True): +def assert_datetime_array_equal( + left, right, obj="DatetimeArray", check_freq=True +) -> None: __tracebackhide__ = True _check_isinstance(left, right, DatetimeArray) @@ -627,7 +628,9 @@ def assert_datetime_array_equal(left, right, obj="DatetimeArray", check_freq=Tru assert_attr_equal("tz", left, right, obj=obj) -def assert_timedelta_array_equal(left, right, obj="TimedeltaArray", check_freq=True): +def assert_timedelta_array_equal( + left, right, obj="TimedeltaArray", check_freq=True +) -> None: __tracebackhide__ = True _check_isinstance(left, right, TimedeltaArray) assert_numpy_array_equal(left._data, right._data, obj=f"{obj}._data") @@ -682,7 +685,7 @@ def assert_numpy_array_equal( check_same=None, obj="numpy array", index_values=None, -): +) -> None: """ Check that 'np.ndarray' is equivalent. @@ -762,7 +765,7 @@ def assert_extension_array_equal( check_exact=False, rtol: float = 1.0e-5, atol: float = 1.0e-8, -): +) -> None: """ Check that left and right ExtensionArrays are equal. @@ -878,7 +881,7 @@ def assert_series_equal( *, check_index=True, check_like=False, -): +) -> None: """ Check that left and right Series are equal. @@ -1145,7 +1148,7 @@ def assert_frame_equal( rtol=1.0e-5, atol=1.0e-8, obj="DataFrame", -): +) -> None: """ Check that left and right DataFrame are equal. @@ -1352,7 +1355,7 @@ def assert_frame_equal( ) -def assert_equal(left, right, **kwargs): +def assert_equal(left, right, **kwargs) -> None: """ Wrapper for tm.assert_*_equal to dispatch to the appropriate test function. @@ -1393,7 +1396,7 @@ def assert_equal(left, right, **kwargs): assert_almost_equal(left, right) -def assert_sp_array_equal(left, right): +def assert_sp_array_equal(left, right) -> None: """ Check that the left and right SparseArray are equal. @@ -1426,12 +1429,12 @@ def assert_sp_array_equal(left, right): assert_numpy_array_equal(left.to_dense(), right.to_dense()) -def assert_contains_all(iterable, dic): +def assert_contains_all(iterable, dic) -> None: for k in iterable: assert k in dic, f"Did not contain item: {repr(k)}" -def assert_copy(iter1, iter2, **eql_kwargs): +def assert_copy(iter1, iter2, **eql_kwargs) -> None: """ iter1, iter2: iterables that produce elements comparable with assert_almost_equal @@ -1463,7 +1466,7 @@ def is_extension_array_dtype_and_needs_i8_conversion(left_dtype, right_dtype) -> return is_extension_array_dtype(left_dtype) and needs_i8_conversion(right_dtype) -def assert_indexing_slices_equivalent(ser: Series, l_slc: slice, i_slc: slice): +def assert_indexing_slices_equivalent(ser: Series, l_slc: slice, i_slc: slice) -> None: """ Check that ser.iloc[i_slc] matches ser.loc[l_slc] and, if applicable, ser[l_slc]. @@ -1477,7 +1480,7 @@ def assert_indexing_slices_equivalent(ser: Series, l_slc: slice, i_slc: slice): assert_series_equal(ser[l_slc], expected) -def assert_metadata_equivalent(left, right): +def assert_metadata_equivalent(left, right) -> None: """ Check that ._metadata attributes are equivalent. """ diff --git a/pandas/_testing/contexts.py b/pandas/_testing/contexts.py index 7df9afd68b432..e64adb06bea7a 100644 --- a/pandas/_testing/contexts.py +++ b/pandas/_testing/contexts.py @@ -8,6 +8,7 @@ from typing import ( IO, Any, + Iterator, ) import uuid @@ -19,7 +20,7 @@ @contextmanager -def decompress_file(path, compression): +def decompress_file(path, compression) -> Iterator[IO[bytes]]: """ Open a compressed file and return a file object. @@ -40,7 +41,7 @@ def decompress_file(path, compression): @contextmanager -def set_timezone(tz: str): +def set_timezone(tz: str) -> Iterator[None]: """ Context manager for temporarily setting a timezone. @@ -126,7 +127,7 @@ def ensure_clean(filename=None, return_filelike: bool = False, **kwargs: Any): @contextmanager -def ensure_clean_dir(): +def ensure_clean_dir() -> Iterator[str]: """ Get a temporary directory path and agrees to remove on close. @@ -145,7 +146,7 @@ def ensure_clean_dir(): @contextmanager -def ensure_safe_environment_variables(): +def ensure_safe_environment_variables() -> Iterator[None]: """ Get a context manager to safely set environment variables @@ -161,7 +162,7 @@ def ensure_safe_environment_variables(): @contextmanager -def with_csv_dialect(name, **kwargs): +def with_csv_dialect(name, **kwargs) -> Iterator[None]: """ Context manager to temporarily register a CSV dialect for parsing CSV. @@ -195,7 +196,7 @@ def with_csv_dialect(name, **kwargs): @contextmanager -def use_numexpr(use, min_elements=None): +def use_numexpr(use, min_elements=None) -> Iterator[None]: from pandas.core.computation import expressions as expr if min_elements is None: @@ -231,11 +232,11 @@ class RNGContext: def __init__(self, seed) -> None: self.seed = seed - def __enter__(self): + def __enter__(self) -> None: self.start_state = np.random.get_state() np.random.seed(self.seed) - def __exit__(self, exc_type, exc_value, traceback): + def __exit__(self, exc_type, exc_value, traceback) -> None: np.random.set_state(self.start_state) diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index bb4787f07b2f0..2ab710a5762d3 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -7,9 +7,12 @@ Other items: * platform checker """ +from __future__ import annotations + import os import platform import sys +from typing import TYPE_CHECKING from pandas._typing import F from pandas.compat.numpy import ( @@ -26,6 +29,9 @@ pa_version_under7p0, ) +if TYPE_CHECKING: + import lzma + PY39 = sys.version_info >= (3, 9) PY310 = sys.version_info >= (3, 10) PYPY = platform.python_implementation() == "PyPy" @@ -117,7 +123,7 @@ def is_ci_environment() -> bool: return os.environ.get("PANDAS_CI", "0") == "1" -def get_lzma_file(): +def get_lzma_file() -> type[lzma.LZMAFile]: """ Importing the `LZMAFile` class from the `lzma` module. diff --git a/pandas/compat/pickle_compat.py b/pandas/compat/pickle_compat.py index 2333324a7e22d..c8db82500d0d6 100644 --- a/pandas/compat/pickle_compat.py +++ b/pandas/compat/pickle_compat.py @@ -7,7 +7,10 @@ import copy import io import pickle as pkl -from typing import TYPE_CHECKING +from typing import ( + TYPE_CHECKING, + Iterator, +) import warnings import numpy as np @@ -291,7 +294,7 @@ def loads( @contextlib.contextmanager -def patch_pickle(): +def patch_pickle() -> Iterator[None]: """ Temporarily patch pickle to use our unpickler. """ diff --git a/pandas/conftest.py b/pandas/conftest.py index dfe8c5f1778d3..eb17aac99a904 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -29,6 +29,10 @@ from decimal import Decimal import operator import os +from typing import ( + Callable, + Literal, +) from dateutil.tz import ( tzlocal, @@ -90,7 +94,7 @@ # pytest -def pytest_addoption(parser): +def pytest_addoption(parser) -> None: parser.addoption("--skip-slow", action="store_true", help="skip slow tests") parser.addoption("--skip-network", action="store_true", help="skip network tests") parser.addoption("--skip-db", action="store_true", help="skip db tests") @@ -231,7 +235,7 @@ def pytest_collection_modifyitems(items, config): @pytest.fixture -def add_doctest_imports(doctest_namespace): +def add_doctest_imports(doctest_namespace) -> None: """ Make `np` and `pd` names available for doctests. """ @@ -243,7 +247,7 @@ def add_doctest_imports(doctest_namespace): # Autouse fixtures # ---------------------------------------------------------------- @pytest.fixture(autouse=True) -def configure_tests(): +def configure_tests() -> None: """ Configure settings for all tests and test modules. """ @@ -530,7 +534,7 @@ def multiindex_year_month_day_dataframe_random_data(): @pytest.fixture -def lexsorted_two_level_string_multiindex(): +def lexsorted_two_level_string_multiindex() -> MultiIndex: """ 2-level MultiIndex, lexsorted, with string names. """ @@ -542,7 +546,9 @@ def lexsorted_two_level_string_multiindex(): @pytest.fixture -def multiindex_dataframe_random_data(lexsorted_two_level_string_multiindex): +def multiindex_dataframe_random_data( + lexsorted_two_level_string_multiindex, +) -> DataFrame: """DataFrame with 2 level MultiIndex with random data""" index = lexsorted_two_level_string_multiindex return DataFrame( @@ -715,7 +721,7 @@ def index_with_missing(request): # Series' # ---------------------------------------------------------------- @pytest.fixture -def string_series(): +def string_series() -> Series: """ Fixture for Series of floats with Index of unique strings """ @@ -725,7 +731,7 @@ def string_series(): @pytest.fixture -def object_series(): +def object_series() -> Series: """ Fixture for Series of dtype object with Index of unique strings """ @@ -735,7 +741,7 @@ def object_series(): @pytest.fixture -def datetime_series(): +def datetime_series() -> Series: """ Fixture for Series of floats with DatetimeIndex """ @@ -758,7 +764,7 @@ def _create_series(index): @pytest.fixture -def series_with_simple_index(index): +def series_with_simple_index(index) -> Series: """ Fixture for tests on series with changing types of indices. """ @@ -766,7 +772,7 @@ def series_with_simple_index(index): @pytest.fixture -def series_with_multilevel_index(): +def series_with_multilevel_index() -> Series: """ Fixture with a Series with a 2-level MultiIndex. """ @@ -804,7 +810,7 @@ def index_or_series_obj(request): # DataFrames # ---------------------------------------------------------------- @pytest.fixture -def int_frame(): +def int_frame() -> DataFrame: """ Fixture for DataFrame of ints with index of unique strings @@ -833,7 +839,7 @@ def int_frame(): @pytest.fixture -def datetime_frame(): +def datetime_frame() -> DataFrame: """ Fixture for DataFrame of floats with DatetimeIndex @@ -862,7 +868,7 @@ def datetime_frame(): @pytest.fixture -def float_frame(): +def float_frame() -> DataFrame: """ Fixture for DataFrame of floats with index of unique strings @@ -891,7 +897,7 @@ def float_frame(): @pytest.fixture -def mixed_type_frame(): +def mixed_type_frame() -> DataFrame: """ Fixture for DataFrame of float/int/string columns with RangeIndex Columns are ['a', 'b', 'c', 'float32', 'int32']. @@ -909,7 +915,7 @@ def mixed_type_frame(): @pytest.fixture -def rand_series_with_duplicate_datetimeindex(): +def rand_series_with_duplicate_datetimeindex() -> Series: """ Fixture for Series with a DatetimeIndex that has duplicates. """ @@ -1151,7 +1157,7 @@ def strict_data_files(pytestconfig): @pytest.fixture -def datapath(strict_data_files): +def datapath(strict_data_files: str) -> Callable[..., str]: """ Get the path to a data file. @@ -1186,7 +1192,7 @@ def deco(*args): @pytest.fixture -def iris(datapath): +def iris(datapath) -> DataFrame: """ The iris dataset as a DataFrame. """ @@ -1376,7 +1382,7 @@ def timedelta64_dtype(request): @pytest.fixture -def fixed_now_ts(): +def fixed_now_ts() -> Timestamp: """ Fixture emits fixed Timestamp.now() """ @@ -1845,7 +1851,7 @@ def using_array_manager(): @pytest.fixture -def using_copy_on_write(): +def using_copy_on_write() -> Literal[False]: """ Fixture to check if Copy-on-Write is enabled. """ diff --git a/pandas/io/common.py b/pandas/io/common.py index ef8b466145daa..d911499aa848e 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -821,7 +821,10 @@ def get_handle( # XZ Compression elif compression == "xz": - handle = get_lzma_file()(handle, ioargs.mode) + # error: Argument 1 to "LZMAFile" has incompatible type "Union[str, + # BaseBuffer]"; expected "Optional[Union[Union[str, bytes, PathLike[str], + # PathLike[bytes]], IO[bytes]]]" + handle = get_lzma_file()(handle, ioargs.mode) # type: ignore[arg-type] # Zstd Compression elif compression == "zstd": diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index bfdf3eb6992ca..6350f402ac0e5 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -16,7 +16,9 @@ def check(self, namespace, expected, ignored=None): # ignored ones # compare vs the expected - result = sorted(f for f in dir(namespace) if not f.startswith("__")) + 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)) diff --git a/pandas/tests/util/test_assert_attr_equal.py b/pandas/tests/util/test_assert_attr_equal.py index 115ef58e085cc..bbbb0bf2172b1 100644 --- a/pandas/tests/util/test_assert_attr_equal.py +++ b/pandas/tests/util/test_assert_attr_equal.py @@ -10,7 +10,7 @@ def test_assert_attr_equal(nulls_fixture): obj = SimpleNamespace() obj.na_value = nulls_fixture - assert tm.assert_attr_equal("na_value", obj, obj) + tm.assert_attr_equal("na_value", obj, obj) def test_assert_attr_equal_different_nulls(nulls_fixture, nulls_fixture2): @@ -21,13 +21,13 @@ def test_assert_attr_equal_different_nulls(nulls_fixture, nulls_fixture2): obj2.na_value = nulls_fixture2 if nulls_fixture is nulls_fixture2: - assert tm.assert_attr_equal("na_value", obj, obj2) + tm.assert_attr_equal("na_value", obj, obj2) elif is_float(nulls_fixture) and is_float(nulls_fixture2): # we consider float("nan") and np.float64("nan") to be equivalent - assert tm.assert_attr_equal("na_value", obj, obj2) + tm.assert_attr_equal("na_value", obj, obj2) elif type(nulls_fixture) is type(nulls_fixture2): # e.g. Decimal("NaN") - assert tm.assert_attr_equal("na_value", obj, obj2) + tm.assert_attr_equal("na_value", obj, obj2) else: with pytest.raises(AssertionError, match='"na_value" are different'): tm.assert_attr_equal("na_value", obj, obj2) diff --git a/pyright_reportGeneralTypeIssues.json b/pyright_reportGeneralTypeIssues.json index 541ae4b198166..98da481a6d80f 100644 --- a/pyright_reportGeneralTypeIssues.json +++ b/pyright_reportGeneralTypeIssues.json @@ -16,6 +16,7 @@ "pandas/util/version", # and all files that currently don't pass "pandas/_config/config.py", + "pandas/_testing/__init__.py", "pandas/core/algorithms.py", "pandas/core/apply.py", "pandas/core/array_algos/take.py",