Repository: pandas-dev/pandas

Issue:
DOC: "justify" parameter in to_html
The Travis docs for <a href="https://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.to_html.html">to_html</a> states that the only accepted parameters for `justify` are `left` and `right`.

However, I stumbled upon the fact that you can also pass in `center`, and it will work just fine (i.e. the cell elements and headers are centered), as evidenced by the code:

https://github.com/pandas-dev/pandas/blob/fa557f7391589f351b1260f46b3b3db22492f50b/pandas/io/formats/format.py#L1215-L1217

@TomAugspurger : Should we continue to allow only `left` and `right` or should we expand to accept `center` ?  I'm personally up for the latter but wanted to get consensus first.


Discussion:
Presumably all these work? https://developer.mozilla.org/en-US/docs/Web/CSS/text-align

+1 for anything that’s valid html / css
@TomAugspurger : I believe that's only a subset according to `pandas` 😉 

~~~python
df = DataFrame()
print(df.to_html(justify="augspurger"))  # your name is also valid

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: augspurger;">
      <th></th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>
~~~
Looks like we need to do some validation on the `justify` parameter.

Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -1685,6 +1685,10 @@ def to_html(self, buf=None, columns=None, col_space=None, header=True,
             .. versionadded:: 0.19.0
         """
 
+        if (justify is not None and
+                justify not in fmt._VALID_JUSTIFY_PARAMETERS):
+            raise ValueError("Invalid value for justify parameter")
+
         formatter = fmt.DataFrameFormatter(self, buf=buf, columns=columns,
                                            col_space=col_space, na_rep=na_rep,
                                            formatters=formatters,
diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py
--- a/pandas/io/formats/format.py
+++ b/pandas/io/formats/format.py
@@ -79,9 +79,15 @@
     line_width : int, optional
         Width to wrap a line in characters, default no wrap"""
 
+_VALID_JUSTIFY_PARAMETERS = ("left", "right", "center", "justify",
+                             "justify-all", "start", "end", "inherit",
+                             "match-parent", "initial", "unset")
+
 justify_docstring = """
-    justify : {'left', 'right'}, default None
-        Left or right-justify the column labels. If None uses the option from
+    justify : {'left', 'right', 'center', 'justify',
+               'justify-all', 'start', 'end', 'inherit',
+               'match-parent', 'initial', 'unset'}, default None
+        How to justify the column labels. If None uses the option from
         the print configuration (controlled by set_option), 'right' out
         of the box."""
 


Test patch:
diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py
--- a/pandas/tests/io/formats/test_to_html.py
+++ b/pandas/tests/io/formats/test_to_html.py
@@ -1557,15 +1557,16 @@ def test_to_html_multiindex(self):
 
         assert result == expected
 
-    def test_to_html_justify(self):
+    @pytest.mark.parametrize("justify", fmt._VALID_JUSTIFY_PARAMETERS)
+    def test_to_html_justify(self, justify):
         df = DataFrame({'A': [6, 30000, 2],
                         'B': [1, 2, 70000],
                         'C': [223442, 0, 1]},
                        columns=['A', 'B', 'C'])
-        result = df.to_html(justify='left')
+        result = df.to_html(justify=justify)
         expected = ('<table border="1" class="dataframe">\n'
                     '  <thead>\n'
-                    '    <tr style="text-align: left;">\n'
+                    '    <tr style="text-align: {justify};">\n'
                     '      <th></th>\n'
                     '      <th>A</th>\n'
                     '      <th>B</th>\n'
@@ -1592,41 +1593,18 @@ def test_to_html_justify(self):
                     '      <td>1</td>\n'
                     '    </tr>\n'
                     '  </tbody>\n'
-                    '</table>')
+                    '</table>'.format(justify=justify))
         assert result == expected
 
-        result = df.to_html(justify='right')
-        expected = ('<table border="1" class="dataframe">\n'
-                    '  <thead>\n'
-                    '    <tr style="text-align: right;">\n'
-                    '      <th></th>\n'
-                    '      <th>A</th>\n'
-                    '      <th>B</th>\n'
-                    '      <th>C</th>\n'
-                    '    </tr>\n'
-                    '  </thead>\n'
-                    '  <tbody>\n'
-                    '    <tr>\n'
-                    '      <th>0</th>\n'
-                    '      <td>6</td>\n'
-                    '      <td>1</td>\n'
-                    '      <td>223442</td>\n'
-                    '    </tr>\n'
-                    '    <tr>\n'
-                    '      <th>1</th>\n'
-                    '      <td>30000</td>\n'
-                    '      <td>2</td>\n'
-                    '      <td>0</td>\n'
-                    '    </tr>\n'
-                    '    <tr>\n'
-                    '      <th>2</th>\n'
-                    '      <td>2</td>\n'
-                    '      <td>70000</td>\n'
-                    '      <td>1</td>\n'
-                    '    </tr>\n'
-                    '  </tbody>\n'
-                    '</table>')
-        assert result == expected
+    @pytest.mark.parametrize("justify", ["super-right", "small-left",
+                                         "noinherit", "tiny", "pandas"])
+    def test_to_html_invalid_justify(self, justify):
+        # see gh-17527
+        df = DataFrame()
+        msg = "Invalid value for justify parameter"
+
+        with tm.assert_raises_regex(ValueError, msg):
+            df.to_html(justify=justify)
 
     def test_to_html_index(self):
         index = ['foo', 'bar', 'baz']