Repository: HypothesisWorks/hypothesis (Python)

Issue:
Some type annotations for `hypothesis.extra.pandas` are missing
Describe the bug
`pyright` raises an error for `hypothesis.extra.pandas.column`: `No parameter named "name" (reportCallIssue)`.

Code or Screenshots

```python
from hypothesis.extra.pandas import column

foo = column(name="bar")
``` 

Discussed here: https://github.com/microsoft/pyright/issues/7367

Solution proposed was to add type annotations to the field definitions `column`.

```python
@attr.s(slots=True)
class column:
    ...
    name: str | None = attr.ib(default=None)
```


Discussion: I'd be happy to review a PR for this if you'd like to contribute one!  Otherwise, someone will probably volunteer in the next few weeks 🙂 



Fix (patch):
diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst
new file mode 100644
index 0000000000..538c781a65
--- /dev/null
+++ b/hypothesis-python/RELEASE.rst
@@ -0,0 +1,3 @@
+RELEASE_TYPE: patch
+
+This patch implements type annotations for :func:`~hypothesis.extra.pandas.column`.
diff --git a/hypothesis-python/docs/strategies.rst b/hypothesis-python/docs/strategies.rst
index 8670b08625..81d829dd28 100644
--- a/hypothesis-python/docs/strategies.rst
+++ b/hypothesis-python/docs/strategies.rst
@@ -224,8 +224,7 @@ See :issue:`3086` for details, e.g. if you're interested in writing your own bac
 what that should eventually look like, and we're likely to make regular breaking
 changes for some time to come)
 
-Using the prototype :pypi:`crosshair-tool` backend `via this plugin
-<https://github.com/pschanely/hypothesis-crosshair>`__,
+Using the prototype :pypi:`crosshair-tool` backend via :pypi:`hypothesis-crosshair`,
 a solver-backed test might look something like:
 
 .. code-block:: python
@@ -233,7 +232,7 @@ a solver-backed test might look something like:
     from hypothesis import given, settings, strategies as st
 
 
-    @settings(backend="crosshair")
+    @settings(backend="crosshair")  # pip install hypothesis[crosshair]
     @given(st.integers())
     def test_needs_solver(x):
         assert x != 123456789
diff --git a/hypothesis-python/src/hypothesis/extra/pandas/impl.py b/hypothesis-python/src/hypothesis/extra/pandas/impl.py
index 7b53a8be42..84cd8d9c91 100644
--- a/hypothesis-python/src/hypothesis/extra/pandas/impl.py
+++ b/hypothesis-python/src/hypothesis/extra/pandas/impl.py
@@ -11,7 +11,7 @@
 from collections import OrderedDict, abc
 from copy import copy
 from datetime import datetime, timedelta
-from typing import Any, List, Optional, Sequence, Set, Union
+from typing import Any, Generic, List, Optional, Sequence, Set, Union, overload
 
 import attr
 import numpy as np
@@ -357,8 +357,8 @@ def result(draw):
     return result()
 
 
-@attr.s(slots=True)
-class column:
+@attr.s(slots=True, init=False)
+class column(Generic[Ex]):
     """Data object for describing a column in a DataFrame.
 
     Arguments:
@@ -375,11 +375,68 @@ class column:
     * unique: If all values in this column should be distinct.
     """
 
-    name = attr.ib(default=None)
-    elements = attr.ib(default=None)
-    dtype = attr.ib(default=None, repr=get_pretty_function_description)
-    fill = attr.ib(default=None)
-    unique = attr.ib(default=False)
+    name: Optional[Union[str, int]] = attr.ib(default=None)
+    elements: Optional[st.SearchStrategy[Ex]] = attr.ib(default=None)
+    dtype: Any = attr.ib(default=None, repr=get_pretty_function_description)
+    fill: Optional[st.SearchStrategy[Ex]] = attr.ib(default=None)
+    unique: bool = attr.ib(default=False)
+
+    @overload
+    def __init__(
+        self: "column[Any]",
+        name: Optional[Union[str, int]] = ...,
+        elements: None = ...,
+        dtype: Any = ...,
+        fill: None = ...,
+        unique: bool = ...,  # noqa: FBT001
+    ) -> None: ...
+
+    @overload
+    def __init__(
+        self: "column[Ex]",
+        name: Optional[Union[str, int]] = ...,
+        elements: Optional[st.SearchStrategy[Ex]] = ...,
+        dtype: Any = ...,
+        fill: Optional[st.SearchStrategy[Ex]] = ...,
+        unique: bool = ...,  # noqa: FBT001
+    ) -> None: ...
+
+    def __init__(
+        self,
+        name: Optional[Union[str, int]] = None,
+        elements: Optional[st.SearchStrategy[Ex]] = None,
+        dtype: Any = None,
+        fill: Optional[st.SearchStrategy[Ex]] = None,
+        unique: bool = False,  # noqa: FBT001,FBT002
+    ) -> None:
+        super().__init__()
+        self.name = name
+        self.elements = elements
+        self.dtype = dtype
+        self.fill = fill
+        self.unique = unique
+
+
+@overload
+def columns(
+    names_or_number: Union[int, Sequence[str]],
+    *,
+    dtype: Any = ...,
+    elements: None = ...,
+    fill: None = ...,
+    unique: bool = ...,
+) -> List[column[Any]]: ...
+
+
+@overload
+def columns(
+    names_or_number: Union[int, Sequence[str]],
+    *,
+    dtype: Any = ...,
+    elements: Optional[st.SearchStrategy[Ex]] = ...,
+    fill: Optional[st.SearchStrategy[Ex]] = ...,
+    unique: bool = ...,
+) -> List[column[Ex]]: ...
 
 
 def columns(
@@ -389,7 +446,7 @@ def columns(
     elements: Optional[st.SearchStrategy[Ex]] = None,
     fill: Optional[st.SearchStrategy[Ex]] = None,
     unique: bool = False,
-) -> List[column]:
+) -> List[column[Ex]]:
     """A convenience function for producing a list of :class:`column` objects
     of the same general shape.