Repository: HypothesisWorks/hypothesis

Issue:
Names for `extra.pandas.series` / `exta.pandas.indexes`
`pandas.Series` and `pandas.Index` both have optional name fields. It would be useful to be able to specify these in strategies - as static values rather than strategies


Discussion:

Resolving patch:
diff --git a/hypothesis-python/src/hypothesis/extra/pandas/impl.py b/hypothesis-python/src/hypothesis/extra/pandas/impl.py
--- a/hypothesis-python/src/hypothesis/extra/pandas/impl.py
+++ b/hypothesis-python/src/hypothesis/extra/pandas/impl.py
@@ -115,13 +115,14 @@ def convert_element(value):
 
 
 class ValueIndexStrategy(st.SearchStrategy):
-    def __init__(self, elements, dtype, min_size, max_size, unique):
+    def __init__(self, elements, dtype, min_size, max_size, unique, name):
         super().__init__()
         self.elements = elements
         self.dtype = dtype
         self.min_size = min_size
         self.max_size = max_size
         self.unique = unique
+        self.name = name
 
     def do_draw(self, data):
         result = []
@@ -147,7 +148,9 @@ def do_draw(self, data):
         dtype = infer_dtype_if_necessary(
             dtype=self.dtype, values=result, elements=self.elements, draw=data.draw
         )
-        return pandas.Index(result, dtype=dtype, tupleize_cols=False)
+        return pandas.Index(
+            result, dtype=dtype, tupleize_cols=False, name=data.draw(self.name)
+        )
 
 
 DEFAULT_MAX_SIZE = 10
@@ -185,6 +188,7 @@ def indexes(
     min_size: int = 0,
     max_size: Optional[int] = None,
     unique: bool = True,
+    name: st.SearchStrategy[Optional[str]] = st.none(),
 ) -> st.SearchStrategy[pandas.Index]:
     """Provides a strategy for producing a :class:`pandas.Index`.
 
@@ -204,6 +208,8 @@ def indexes(
       should pass a max_size explicitly.
     * unique specifies whether all of the elements in the resulting index
       should be distinct.
+    * name is a strategy for strings or ``None``, which will be passed to
+      the :class:`pandas.Index` constructor.
     """
     check_valid_size(min_size, "min_size")
     check_valid_size(max_size, "max_size")
@@ -214,7 +220,7 @@ def indexes(
 
     if max_size is None:
         max_size = min_size + DEFAULT_MAX_SIZE
-    return ValueIndexStrategy(elements, dtype, min_size, max_size, unique)
+    return ValueIndexStrategy(elements, dtype, min_size, max_size, unique, name)
 
 
 @defines_strategy()
@@ -225,6 +231,7 @@ def series(
     index: Optional[st.SearchStrategy[Union[Sequence, pandas.Index]]] = None,
     fill: Optional[st.SearchStrategy[Ex]] = None,
     unique: bool = False,
+    name: st.SearchStrategy[Optional[str]] = st.none(),
 ) -> st.SearchStrategy[pandas.Series]:
     """Provides a strategy for producing a :class:`pandas.Series`.
 
@@ -251,6 +258,9 @@ def series(
       :func:`~hypothesis.extra.pandas.range_indexes` function to produce
       values for this argument.
 
+    * name: is a strategy for strings or ``None``, which will be passed to
+      the :class:`pandas.Series` constructor.
+
     Usage:
 
     .. code-block:: pycon
@@ -295,7 +305,7 @@ def result(draw):
                     )
                 )
 
-            return pandas.Series(result_data, index=index, dtype=dtype)
+            return pandas.Series(result_data, index=index, dtype=dtype, name=draw(name))
         else:
             return pandas.Series(
                 (),
@@ -303,6 +313,7 @@ def result(draw):
                 dtype=dtype
                 if dtype is not None
                 else draw(dtype_for_elements_strategy(elements)),
+                name=draw(name),
             )
 
     return result()


Test patch:
diff --git a/hypothesis-python/tests/pandas/test_indexes.py b/hypothesis-python/tests/pandas/test_indexes.py
--- a/hypothesis-python/tests/pandas/test_indexes.py
+++ b/hypothesis-python/tests/pandas/test_indexes.py
@@ -46,6 +46,11 @@ def test_unique_indexes_of_many_small_values(ix):
     assert len(set(ix)) == len(ix)
 
 
+@given(pdst.indexes(dtype="int8", name=st.just("test_name")))
+def test_name_passed_on(s):
+    assert s.name == "test_name"
+
+
 # Sizes that fit into an int64 without overflow
 range_sizes = st.integers(0, 2**63 - 1)
 
diff --git a/hypothesis-python/tests/pandas/test_series.py b/hypothesis-python/tests/pandas/test_series.py
--- a/hypothesis-python/tests/pandas/test_series.py
+++ b/hypothesis-python/tests/pandas/test_series.py
@@ -56,3 +56,8 @@ def test_will_use_a_provided_elements_strategy(s):
 @given(pdst.series(dtype="int8", unique=True))
 def test_unique_series_are_unique(s):
     assert len(s) == len(set(s))
+
+
+@given(pdst.series(dtype="int8", name=st.just("test_name")))
+def test_name_passed_on(s):
+    assert s.name == "test_name"