Repository: dask/dask

Issue:
`make_people` should work with `processes` scheduler
**What happened**: I wanted to

```python
import dask
dask.datasets.make_people().compute()
```

But this failed with `TypeError: cannot pickle 'generator' object` because
- The default scheduler is `processes` which pickles the data
- `make_people` [uses a generator under the hood](https://github.com/dask/dask/blob/c5633c21e754df6b2c13195f1e2688e347c48963/dask/datasets.py#L79), which cannot be pickled
It also seems that [none of the tests](https://github.com/dask/dask/blob/da2458250d4fcd8f1a99458778de536a667224a2/dask/tests/test_datasets.py) catch this, since none of them actually require sending the data over (the first uses `take` and second `.count.compute()`)

Full traceback below

**What you expected to happen**: I would expect `make_people` to work with all schedulers. 

**Environment**:

- Dask version: 2021.08.1
- Python version: Python 3.9.5
- Operating System: Ubuntu 18.04.5
- Install method (conda, pip, source): conda

**Traceback**
```python
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_11002/356034757.py in <module>
      1 import dask
----> 2 dask.datasets.make_people().compute()

~/miniconda3/lib/python3.9/site-packages/dask/base.py in compute(self, **kwargs)
    284         dask.base.compute
    285         """
--> 286         (result,) = compute(self, traverse=False, **kwargs)
    287         return result
    288 

~/miniconda3/lib/python3.9/site-packages/dask/base.py in compute(*args, **kwargs)
    566         postcomputes.append(x.__dask_postcompute__())
    567 
--> 568     results = schedule(dsk, keys, **kwargs)
    569     return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])
    570 

~/miniconda3/lib/python3.9/site-packages/dask/multiprocessing.py in get(dsk, keys, num_workers, func_loads, func_dumps, optimize_graph, pool, chunksize, **kwargs)
    217     try:
    218         # Run
--> 219         result = get_async(
    220             pool.submit,
    221             pool._max_workers,

~/miniconda3/lib/python3.9/site-packages/dask/local.py in get_async(submit, num_workers, dsk, result, cache, get_id, rerun_exceptions_locally, pack_exception, raise_exception, callbacks, dumps, loads, chunksize, **kwargs)
    515                             _execute_task(task, data)  # Re-execute locally
    516                         else:
--> 517                             raise_exception(exc, tb)
    518                     res, worker_id = loads(res_info)
    519                     state["cache"][key] = res

~/miniconda3/lib/python3.9/site-packages/dask/local.py in reraise(exc, tb)
    323     if exc.__traceback__ is not tb:
    324         raise exc.with_traceback(tb)
--> 325     raise exc
    326 
    327 

~/miniconda3/lib/python3.9/site-packages/dask/local.py in execute_task()
    223         result = _execute_task(task, data)
    224         id = get_id()
--> 225         result = dumps((result, id))
    226         failed = False
    227     except BaseException as e:

~/miniconda3/lib/python3.9/site-packages/cloudpickle/cloudpickle_fast.py in dumps()
     71                 file, protocol=protocol, buffer_callback=buffer_callback
     72             )
---> 73             cp.dump(obj)
     74             return file.getvalue()
     75 

~/miniconda3/lib/python3.9/site-packages/cloudpickle/cloudpickle_fast.py in dump()
    561     def dump(self, obj):
    562         try:
--> 563             return Pickler.dump(self, obj)
    564         except RuntimeError as e:
    565             if "recursion" in e.args[0]:

TypeError: cannot pickle 'generator' object
```

**Solution**:

A possible solution would be to simply return a list in `_generate_mimesis`, e.g.

```python
return [schema.create(iterations=1)[0] for i in range(records_per_partition)]
```

I would be happy to submit a PR with this (+ a test to catch this), or with another solution, if you steer me in the right direction.


Discussion:
Thanks for reporting @DahnJ. Switching to a function seems like a reasonable thing to do. 

Resolving patch:
diff --git a/dask/datasets.py b/dask/datasets.py
--- a/dask/datasets.py
+++ b/dask/datasets.py
@@ -75,8 +75,7 @@ def _generate_mimesis(field, schema_description, records_per_partition, seed):
 
     field = Field(seed=seed, **field)
     schema = Schema(schema=lambda: schema_description(field))
-    for i in range(records_per_partition):
-        yield schema.create(iterations=1)[0]
+    return [schema.create(iterations=1)[0] for i in range(records_per_partition)]
 
 
 def _make_mimesis(field, schema, npartitions, records_per_partition, seed=None):


Test patch:
diff --git a/dask/tests/test_datasets.py b/dask/tests/test_datasets.py
--- a/dask/tests/test_datasets.py
+++ b/dask/tests/test_datasets.py
@@ -18,6 +18,15 @@ def test_full_dataset():
     assert b.count().compute() == 20
 
 
+def test_make_dataset_with_processes():
+    pytest.importorskip("mimesis")
+    b = dask.datasets.make_people(npartitions=2)
+    try:
+        b.compute(scheduler="processes")
+    except TypeError:
+        pytest.fail("Failed to execute make_people using processes")
+
+
 def test_no_mimesis():
     try:
         import mimesis  # noqa: F401