Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions python/pyspark/sql/tests/pandas/test_pandas_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ def test_map_in_pandas(self):
expected = df.collect()
self.assertEqual(actual, expected)

# test returning list of DataFrames
df = self.spark.range(10, numPartitions=3)
actual = df.mapInPandas(lambda it: [pdf for pdf in it], "id long").collect()
expected = df.collect()
self.assertEqual(actual, expected)

def test_multiple_columns(self):
data = [(1, "foo"), (2, None), (3, "bar"), (4, "bar")]
df = self.spark.createDataFrame(data, "a int, b string")
Expand Down Expand Up @@ -186,6 +180,10 @@ def no_iter(_):
def bad_iter_elem(_):
return iter([1])

def list_not_iter(iterator):
# Iterable but not an Iterator: violates the Iterator[pandas.DataFrame] contract.
return [pdf for pdf in iterator]

with self.assertRaisesRegex(
PythonException,
"Return type of the user-defined function should be iterator of pandas.DataFrame, "
Expand All @@ -200,6 +198,13 @@ def bad_iter_elem(_):
):
(self.spark.range(10, numPartitions=3).mapInPandas(bad_iter_elem, "a int").count())

with self.assertRaisesRegex(
PythonException,
"Return type of the user-defined function should be iterator of pandas.DataFrame, "
"but is list",
):
(self.spark.range(10, numPartitions=3).mapInPandas(list_not_iter, "a int").count())

def test_dataframes_with_other_column_names(self):
with self.quiet():
self.check_dataframes_with_other_column_names()
Expand Down
5 changes: 1 addition & 4 deletions python/pyspark/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2698,11 +2698,8 @@ def dataframe_iter():
df_for_struct=True,
)[0]

# mapInPandas accepts any iterable (e.g. a list), not just an
# iterator, so the standard verify_return_type (which requires an
# Iterator) is intentionally not reused here.
result = map_udf(dataframe_iter())
if not isinstance(result, Iterator) and not hasattr(result, "__iter__"):
if not isinstance(result, Iterator):
raise PySparkTypeError(
errorClass="UDF_RETURN_TYPE",
messageParameters={
Expand Down