Repository: pandas-dev/pandas-stubs (language: python)

Issue:
Issue with `concat` and passing a `Union` due to presence of checking for `Iterable[None]`
You are right, the example doesn't work, my bad. This example does work though, and the same question still applies.

```python
data: pd.DataFrame | pd.Series = pd.Series()

pd.concat([pd.DataFrame(), data])
```

returns

```
error: List item 0 has incompatible type "DataFrame"; expected "None"  [list-item]
error: List item 1 has incompatible type "DataFrame | Series[Any]"; expected "None"  [list-item]
```

_Originally posted by @tvdboom in https://github.com/pandas-dev/pandas-stubs/discussions/878#discussioncomment-8594364_


Discussion / hints:
The above code triggers issues with `pyright` and `mypy`.  Interestingly, if we remove the first overload for `pd.concat` that looks for `Iterable[None]`, then the above code type checks correctly.

Going to see what @twoertwein thinks - he put that in there.

I assumed you can only concat DataFrame and Series along axis=1. seems you can also do it for axis=0:

```py
>>> pd.concat([pd.DataFrame([[0, 1], [2, 3]]), pd.Series([4,5])])
   0    1
0  0  1.0
1  2  3.0
0  4  NaN
1  5  NaN
```

Fix patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a0e7af32..7cd5ce04 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,7 +3,7 @@ ci:
     autofix_prs: false
 repos:
 -   repo: https://github.com/python/black
-    rev: 24.1.1
+    rev: 24.2.0
     hooks:
     -   id: black
 -   repo: https://github.com/PyCQA/isort
@@ -11,7 +11,7 @@ repos:
     hooks:
     -   id: isort
 -   repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.2.1
+    rev: v0.3.0
     hooks:
     -   id: ruff
         args: [
diff --git a/pandas-stubs/core/reshape/concat.pyi b/pandas-stubs/core/reshape/concat.pyi
index 54de1be3..7ee1913b 100644
--- a/pandas-stubs/core/reshape/concat.pyi
+++ b/pandas-stubs/core/reshape/concat.pyi
@@ -16,7 +16,6 @@ from typing_extensions import Never
 
 from pandas._typing import (
     Axis,
-    AxisColumn,
     AxisIndex,
     HashableT1,
     HashableT2,
@@ -53,7 +52,7 @@ def concat(  # type: ignore[overload-overlap] # pyright: ignore[reportOverlappin
     copy: bool = ...,
 ) -> DataFrame: ...
 @overload
-def concat(
+def concat(  # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload]
     objs: Iterable[Series | None] | Mapping[HashableT1, Series | None],
     *,
     axis: AxisIndex = ...,
@@ -73,7 +72,7 @@ def concat(
         | Mapping[HashableT1, Series | DataFrame | None]
     ),
     *,
-    axis: AxisColumn,
+    axis: Axis = ...,
     join: Literal["inner", "outer"] = ...,
     ignore_index: bool = ...,
     keys: Iterable[HashableT2] = ...,


Test patch:
diff --git a/tests/test_pandas.py b/tests/test_pandas.py
index 71551bbd..fddce825 100644
--- a/tests/test_pandas.py
+++ b/tests/test_pandas.py
@@ -62,6 +62,7 @@ def test_types_concat_none() -> None:
     check(
         assert_type(pd.concat([None, series, df], axis=1), pd.DataFrame), pd.DataFrame
     )
+    check(assert_type(pd.concat([None, series, df]), pd.DataFrame), pd.DataFrame)
 
     check(assert_type(pd.concat({"a": None, "b": series}), pd.Series), pd.Series)
     check(assert_type(pd.concat({"a": None, "b": df}), pd.DataFrame), pd.DataFrame)
@@ -69,6 +70,10 @@ def test_types_concat_none() -> None:
         assert_type(pd.concat({"a": None, "b": series, "c": df}, axis=1), pd.DataFrame),
         pd.DataFrame,
     )
+    check(
+        assert_type(pd.concat({"a": None, "b": series, "c": df}), pd.DataFrame),
+        pd.DataFrame,
+    )
 
     if TYPE_CHECKING_INVALID_USAGE:
         # using assert_type as otherwise the second call would not be type-checked
@@ -77,8 +82,8 @@ def test_types_concat_none() -> None:
 
 
 def test_types_concat() -> None:
-    s: pd.Series = pd.Series([0, 1, -10])
-    s2: pd.Series = pd.Series([7, -5, 10])
+    s = pd.Series([0, 1, -10])
+    s2 = pd.Series([7, -5, 10])
 
     check(assert_type(pd.concat([s, s2]), pd.Series), pd.Series)
     check(assert_type(pd.concat([s, s2], axis=1), pd.DataFrame), pd.DataFrame)
@@ -166,6 +171,9 @@ def test_types_concat() -> None:
     adict = {"a": df, 2: df2}
     check(assert_type(pd.concat(adict), pd.DataFrame), pd.DataFrame)
 
+    data: pd.DataFrame | pd.Series = pd.Series()
+    check(assert_type(pd.concat([pd.DataFrame(), data]), pd.DataFrame), pd.DataFrame)
+
 
 def test_concat_args() -> None:
     df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})