Repository: lightkurve/lightkurve

Issue:
TargetPixelFile.meta should have a friendly __repr__ and __str__
<!-- Fill in the information below before opening an issue. -->

#### Problem description

One would entering `TargetPixelFile.meta` on ipython / jupyter would display the key - value pairs in the meta, the typical behavior of dictionary like objects. 

Right now it only displays a meaningless internal class representation.


#### Example
Load any `TargetPixelFile` and inspect its `meta` in Jupyter:

![image](https://user-images.githubusercontent.com/250644/117190075-ce6d4f00-ad93-11eb-8c1c-e571d0e6b7b2.png)

-  lightkurve version (e.g. 1.0b6): 2.0.9


Discussion:

Patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
index e8b19226..5c5feec9 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -19,6 +19,7 @@ extensions = [
     'sphinx.ext.autosummary',
     'sphinx.ext.mathjax',
     'sphinx.ext.intersphinx',
+    'sphinx.ext.viewcode',
     'nbsphinx',
     'numpydoc',
     'sphinxcontrib.rawfiles']
diff --git a/src/lightkurve/targetpixelfile.py b/src/lightkurve/targetpixelfile.py
index c73e6d3f..8ea983c4 100644
--- a/src/lightkurve/targetpixelfile.py
+++ b/src/lightkurve/targetpixelfile.py
@@ -66,7 +66,11 @@ class HduToMetaMapping(collections.abc.Mapping):
     """Provides a read-only view of HDU header in `astropy.timeseries.TimeSeries.meta` format"""
 
     def __init__(self, hdu):
-        self._dict = {}
+        # use OrderedDict rather than simple dict for 2 reasons:
+        # 1. more friendly __repr__ and __str__
+        # 2. make the behavior between a TPF and a LC is more consistent.
+        #    (LightCurve.meta is an OrderedDict)
+        self._dict = collections.OrderedDict()
         self._dict.update(hdu.header)
 
     def __getitem__(self, key):
@@ -78,6 +82,12 @@ class HduToMetaMapping(collections.abc.Mapping):
     def __iter__(self):
         return iter(self._dict)
 
+    def __repr__(self):
+        return self._dict.__repr__()
+
+    def __str__(self):
+        return self._dict.__str__()
+
 
 class TargetPixelFile(object):
     """Abstract class representing FITS files which contain time series imaging data.


Test patch:
diff --git a/tests/test_targetpixelfile.py b/tests/test_targetpixelfile.py
index f7e5df0a..cfd22fa0 100644
--- a/tests/test_targetpixelfile.py
+++ b/tests/test_targetpixelfile.py
@@ -1,3 +1,4 @@
+import collections
 import os
 import tempfile
 import warnings
@@ -842,6 +843,11 @@ def test_tpf_meta():
         tpf.meta["CHANNEL"] = 44
     with pytest.raises(TypeError):
         tpf.meta["KEY-NEW"] = 44
+    # needed for current internal HduToMetaMapping-based meta, ensuring it has
+    # a friendly __repr__() and __str__()
+    expected = collections.OrderedDict(tpf.meta).__repr__()
+    assert tpf.meta.__repr__() == expected
+    assert tpf.meta.__str__() == expected
 
 
 def test_estimate_background():