diff --git a/doc/source/whatsnew/v1.5.3.rst b/doc/source/whatsnew/v1.5.3.rst index cb99495b837b2..a0c38f1f81538 100644 --- a/doc/source/whatsnew/v1.5.3.rst +++ b/doc/source/whatsnew/v1.5.3.rst @@ -28,6 +28,7 @@ Bug fixes ~~~~~~~~~ - Bug in :meth:`.Styler.to_excel` leading to error when unrecognized ``border-style`` (e.g. ``"hair"``) provided to Excel writers (:issue:`48649`) - Bug when chaining several :meth:`.Styler.concat` calls, only the last styler was concatenated (:issue:`49207`) +- Fixed bug when instantiating a :class:`DataFrame` subclass inheriting from ``typing.Generic`` that triggered a ``UserWarning`` on python 3.11 (:issue:`49649`) - .. --------------------------------------------------------------------------- diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx index 439136d17fed2..d2c2697c05812 100644 --- a/pandas/_libs/lib.pyx +++ b/pandas/_libs/lib.pyx @@ -1,7 +1,10 @@ from collections import abc from decimal import Decimal from enum import Enum -from typing import Literal +from typing import ( + Literal, + _GenericAlias, +) import warnings cimport cython @@ -1136,7 +1139,8 @@ cdef inline bint c_is_list_like(object obj, bint allow_sets) except -1: # equiv: `isinstance(obj, abc.Iterable)` getattr(obj, "__iter__", None) is not None and not isinstance(obj, type) # we do not count strings/unicode/bytes as list-like - and not isinstance(obj, (str, bytes)) + # exclude Generic types that have __iter__ + and not isinstance(obj, (str, bytes, _GenericAlias)) # exclude zero-dimensional duck-arrays, effectively scalars and not (hasattr(obj, "ndim") and obj.ndim == 0) # exclude sets if allow_sets is False diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index f08d6b8c9feb8..948d14c1bd1f9 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -18,6 +18,10 @@ from numbers import Number import re import sys +from typing import ( + Generic, + TypeVar, +) import numpy as np import pytest @@ -228,6 +232,22 @@ def __getitem__(self, item): assert not inference.is_list_like(NotListLike()) +def test_is_list_like_generic(): + # GH 49649 + # is_list_like was yielding false positives for Generic classes in python 3.11 + T = TypeVar("T") + + class MyDataFrame(DataFrame, Generic[T]): + ... + + tstc = MyDataFrame[int] + tst = MyDataFrame[int]({"x": [1, 2, 3]}) + + assert not inference.is_list_like(tstc) + assert isinstance(tst, DataFrame) + assert inference.is_list_like(tst) + + def test_is_sequence(): is_seq = inference.is_sequence assert is_seq((1, 2))