Repository: sunpy/sunpy

Issue:
Cannot pass sortby keyword argument through to MapSequence from Map
`MapSequence` accepts a `sortby` keyword argument that can be used to optionally sort the maps in the sequence in different ways. However, if you try to pass this kwarg in through `Map`, eg.

```python
sunpy.map.Map(file_list, sequence=True, sortby=None)
```

you get the following exception,

```python-traceback
TypeError: __init__() got an unexpected keyword argument 'sortby'
```

Presumably, this is because `Map` does not properly deal with the `sortby` kwarg before it can be passed to `MapSequence`.

Discussion:
nabobalis: Was there no previous test with sortby or derotate for mapsequence? 
devanshshukla99: mapsequence has one test for `derotate`, which passes;
the exception occurs when supplying kwargs to `MapSequence` through `Map`
devanshshukla99: > This isn't the right fix - we still want to hand keyword arguments to `NDData`. I think the correct fix is to
> 
> 1. Pop the the `sortby` argument from `kwargs` (`sortby = kwargs.pop('sortby', None)`)
> 2. Pass `sortby` into `MapSequence`, if a `MapSequence` has been requested

Makes sense.

But wouldn't it be better to pop out all kwargs for `NDData` into a seperate var `nd_kwargs`?
dstansby: > > This isn't the right fix - we still want to hand keyword arguments to `NDData`. I think the correct fix is to
> > 
> > 1. Pop the the `sortby` argument from `kwargs` (`sortby = kwargs.pop('sortby', None)`)
> > 2. Pass `sortby` into `MapSequence`, if a `MapSequence` has been requested
> 
> Makes sense.
> 
> But wouldn't it be better to pop out all kwargs for `NDData` into a seperate var `nd_kwargs`? This would make sure any other kwarg, for example (looks distant but anyway) `filetype`, are also supported.

Yes, it would be good to do that. The clever way would be to use  [`inspect.signature`](https://docs.python.org/3/library/inspect.html#inspect.signature) to work out what the keyword arguments are for `NDData`, and pop them from the kwargs given to `Map`.

Patch:
diff --git a/changelog/5392.bugfix.rst b/changelog/5392.bugfix.rst
new file mode 100644
index 000000000..b981f8e10
--- /dev/null
+++ b/changelog/5392.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed a bug where `~sunpy.map.GenericMap` used to break with keyword arguments.
diff --git a/sunpy/map/mapbase.py b/sunpy/map/mapbase.py
index 09c68fd49..5a47fb89f 100644
--- a/sunpy/map/mapbase.py
+++ b/sunpy/map/mapbase.py
@@ -3,6 +3,7 @@ Map is a generic Map class from which all other Map classes inherit from.
 """
 import copy
 import html
+import inspect
 import numbers
 import textwrap
 import webbrowser
@@ -215,7 +216,9 @@ class GenericMap(NDData):
             warn_user("This file contains more than 2 dimensions. "
                       "Data will be truncated to the first two dimensions.")
 
-        super().__init__(data, meta=MetaDict(header), **kwargs)
+        params = list(inspect.signature(NDData).parameters)
+        nddata_kwargs = {x: kwargs.pop(x) for x in params & kwargs.keys()}
+        super().__init__(data, meta=MetaDict(header), **nddata_kwargs)
 
         # Correct possibly missing meta keywords
         self._fix_date()


Test patch:
diff --git a/sunpy/map/tests/test_map_factory.py b/sunpy/map/tests/test_map_factory.py
index 64a023c71..fd5dc56a0 100644
--- a/sunpy/map/tests/test_map_factory.py
+++ b/sunpy/map/tests/test_map_factory.py
@@ -60,6 +60,11 @@ class TestMap:
         sequence = sunpy.map.Map(a_list_of_many, sequence=True)
         assert isinstance(sequence, sunpy.map.MapSequence)
 
+    def test_mapsequence_sortby(self):
+        # Test making a MapSequence with sortby kwarg
+        sequence = sunpy.map.Map(a_list_of_many, sequence=True, sortby=None)
+        assert isinstance(sequence, sunpy.map.MapSequence)
+
     def test_composite(self):
         # Test making a CompositeMap
         comp = sunpy.map.Map(AIA_171_IMAGE, RHESSI_IMAGE, composite=True)