Repository: pyjanitor-devs/pyjanitor

Issue:
[BUG] Extend `fill_empty`'s `column_names` type range
# Brief Description

<!-- Please provide a brief description of your bug. Do NOT paste the stack trace here. -->

https://github.com/pyjanitor-devs/pyjanitor/blob/3fab49e8c89f1a5e4ca7a6e4fdbbe8e2f7b89c66/janitor/functions/fill.py#L148-L152

Quickly fix this, could add `pd.Index`.

And a little bit more thinking, using `Iterable` is better?
Because `check_column`'s `column_names` also support `Iterable`.
And `pd.Index`'s instance is also `Iterable`.
So it would be `@dispatch(pd.DataFrame, Iterable)`

The `Iterable` is not `typing.Iterable` is `collections.abc.Iterable`.
Or else using `typing.Iterable` would get another error.

# Minimally Reproducible Code

<!-- If you provide minimal code that reproduces the problem, this makes it easier for us to debug what's going on.

Minimal code should be trivially copy/pastable into a Python interpreter in its entirety. Be sure to include imports.
-->

```python
>>> import pandas as pd
>>> import janitor  # noqa

>>> df = pd.DataFrame({"attr":[None, None]})
>>> df.fill_empty(df.columns, 0)
Traceback (most recent call last):
  File "C:\Software\miniforge3\envs\work\lib\site-packages\multipledispatch\dispatcher.py", line 269, in __call__
    func = self._cache[types]
KeyError: (<class 'pandas.core.frame.DataFrame'>, <class 'pandas.core.indexes.base.Index'>)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Software\miniforge3\envs\work\lib\site-packages\pandas_flavor\register.py", line 29, in __call__
    return method(self._obj, *args, **kwargs)
  File "C:\Software\miniforge3\envs\work\lib\site-packages\janitor\utils.py", line 231, in wrapper
    return func(*args, **kwargs)
  File "C:\Software\miniforge3\envs\work\lib\site-packages\janitor\functions\fill.py", line 199, in fill_empty
    return _fill_empty(df, column_names, value=value)
  File "C:\Software\miniforge3\envs\work\lib\site-packages\multipledispatch\dispatcher.py", line 273, in __call__
    raise NotImplementedError(
NotImplementedError: Could not find signature for _fill_empty: <DataFrame, Index>
```


Discussion:
@Zeroto521 Thanks for reporting! Would you like to submit a PR fix for this? 😄 

Resolving patch:
diff --git a/janitor/functions/fill.py b/janitor/functions/fill.py
--- a/janitor/functions/fill.py
+++ b/janitor/functions/fill.py
@@ -1,3 +1,4 @@
+from collections.abc import Iterable as abcIterable
 from enum import Enum
 from operator import methodcaller
 from typing import Hashable, Iterable, Union
@@ -145,7 +146,7 @@ def fill_empty(
     return _fill_empty(df, column_names, value=value)
 
 
-@dispatch(pd.DataFrame, (list, tuple))
+@dispatch(pd.DataFrame, abcIterable)
 def _fill_empty(df, column_names, value=None):
     """Fill empty function for the case that column_names is list or tuple."""
     fill_mapping = {c: value for c in column_names}


Test patch:
diff --git a/tests/functions/test_fill_empty.py b/tests/functions/test_fill_empty.py
--- a/tests/functions/test_fill_empty.py
+++ b/tests/functions/test_fill_empty.py
@@ -1,4 +1,5 @@
 import pytest
+import pandas as pd
 
 
 @pytest.mark.functions
@@ -11,3 +12,22 @@ def test_fill_empty(null_df):
 def test_fill_empty_column_string(null_df):
     df = null_df.fill_empty(column_names="2", value=3)
     assert set(df.loc[:, "2"]) == set([3])
+
+
+@pytest.mark.functions
+@pytest.mark.parametrize(
+    "column_names",
+    [
+        (0, 1, "2", "3"),  # tuple
+        [0, 1, "2", "3"],  # list
+        {0, 1, "2", "3"},  # set
+        ({0: 0, 1: 1, "2": "2", "3": "3"}).keys(),  # dict key
+        ({0: 0, 1: 1, "2": "2", "3": "3"}).values(),  # dict value
+        pd.Index([0, 1, "2", "3"]),  # Index
+    ],
+)
+def test_column_names_iterable_type(null_df, column_names):
+    result = null_df.fill_empty(column_names=column_names, value=3)
+    excepted = null_df.fillna(3)
+
+    assert result.equals(excepted)