Repository: pandas-dev/pandas
Pull request: BUG accept and deprecate negative integer for max_colwidth
- [x] closes #31532
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
BUG display.max_colwidth do not accept -1 for unlimited width
#### Code Sample, a copy-pastable example if possible

```python
import pandas as pd
pd.set_option("display.max_colwidth", -1)
```
#### Problem description

There is a regression with `"display.max_colwidth"`. In the past, it was only accepting integer. The way to no limit the size was to pass `-1`. In pandas 1,0, this option becomes more consistent and not limiting the width should be set with `None`. However, the support for negative integer was removed.

Thus, one would need to either set to `-1` or `None` depending on the pandas version. It would be best to support both options. Potentially, support for negative integer could be removed with a deprecation cycle.

Hints from issue discussion:
>  It would be best to support both options. Potentially, support for negative integer could be removed with a deprecation cycle.

@jorisvandenbossche Is this what we're going for then - add support for `-1` back in, but raise a FutureWarning alerting the user that it'll no longer work in a future version?

It reminds me of the `header` argument in `read_csv`, whereby `header=-1` used to work in 0.24, then in 0.25 it didn't (see #27779) and so we now raise
```
ValueError: Passing negative integer to header is invalid. For no header, use header=None instead
```

Perhaps the current ValueError message could just have an extra line specifically instructing to use `None` instead of `-1`, in the case that `-1` is passed?

Commit message: add whats new

Patch to review:
diff --git a/doc/source/whatsnew/v1.0.1.rst b/doc/source/whatsnew/v1.0.1.rst
index 801d97b777e00..32355349ff2ef 100644
--- a/doc/source/whatsnew/v1.0.1.rst
+++ b/doc/source/whatsnew/v1.0.1.rst
@@ -128,7 +128,7 @@ ExtensionArray
 
 Other
 ^^^^^
--
+- Fixed a regression where setting ``display.max_colwidth`` was not accepting negative integer. In addition, this behavior has been deprecated in favor of using ``None`` (:issue:`31532`)
 -
 
 .. ---------------------------------------------------------------------------
diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py
index 3776c6f816d96..d5966a959dcd1 100644
--- a/pandas/core/config_init.py
+++ b/pandas/core/config_init.py
@@ -9,6 +9,7 @@
 module is imported, register them here rather than in the module.
 
 """
+import warnings
 import pandas._config.config as cf
 from pandas._config.config import (
     is_bool,
@@ -341,8 +342,25 @@ def is_terminal() -> bool:
         validator=is_instance_factory([type(None), int]),
     )
     cf.register_option("max_categories", 8, pc_max_categories_doc, validator=is_int)
+
+    def _deprecate_negative_int_max_colwidth(key):
+        value = cf.get_option(key)
+        if value is not None and value < 0:
+            warnings.warn(
+                "Passing a negative integer is deprecated in version 1.0 and "
+                "will not be supported from version 1.2. Instead, use None to "
+                "not limit the column width.",
+                FutureWarning,
+            )
+
     cf.register_option(
-        "max_colwidth", 50, max_colwidth_doc, validator=is_nonnegative_int
+        # FIXME: change `validator=is_int` to `validator=is_nonnegative_int`
+        # in version 1.2
+        "max_colwidth",
+        50,
+        max_colwidth_doc,
+        validator=is_int,
+        cb=_deprecate_negative_int_max_colwidth,
     )
     if is_terminal():
         max_cols = 0  # automatically determine optimal number of columns
diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py
index 7650561d3072d..02df53958c750 100644
--- a/pandas/tests/io/formats/test_format.py
+++ b/pandas/tests/io/formats/test_format.py
@@ -239,6 +239,18 @@ def test_repr_truncation(self):
         with option_context("display.max_colwidth", max_len + 2):
             assert "..." not in repr(df)
 
+    def test_repr_deprecation_negative_int(self):
+        # FIXME: remove in version 1.2 after deprecation cycle
+        # Non-regression test for:
+        # https://github.com/pandas-dev/pandas/issues/31532
+        with pytest.warns(FutureWarning) as records:
+            set_option("display.max_colwidth", -1)
+        assert len(records) == 1
+        assert (
+            "Instead, use None to not limit the column width."
+            in records[0].message.args[0]
+        )
+
     def test_repr_chop_threshold(self):
         df = DataFrame([[0.1, 0.5], [0.5, -0.1]])
         pd.reset_option("display.chop_threshold")  # default None


Code review comments:
diff_hunk: @@ -239,6 +239,18 @@ def test_repr_truncation(self):
         with option_context("display.max_colwidth", max_len + 2):
             assert "..." not in repr(df)
 
+    def test_repr_deprecation_negative_int(self):
+        # FIXME: remove in version 1.2 after deprecation cycle
+        # Non-regression test for:
+        # https://github.com/pandas-dev/pandas/issues/31532
+        with pytest.warns(FutureWarning) as records:
path: pandas/tests/io/formats/test_format.py
text: @user1:
Thanks!

Could you please use
```
with tm.assert_produces_warning(
```
instead? See [testing warnings](https://pandas.pydata.org/pandas-docs/stable/development/contributing.html#testing-warnings)