Repository: pandas-dev/pandas

Issue:
line_width failure
Two examples where line_width display option requirement is not met:

``` python
In [1]: import pandas as pd

In [2]: pd.__version__
Out[2]: '0.11.0.dev-250c8e0'

In [3]: len(repr(pd.DataFrame(123456, range(5), range(15))).split('\n')[1])
Out[3]: 92

In [4]: pd.options.display.max_columns = 100

In [5]: len(repr(pd.DataFrame(0, range(5), range(35))).split('\n')[1])
Out[5]: 104
```



Discussion:
https://github.com/pydata/pandas/blob/master/pandas/core/frame.py#L619
max_columns is compared against the number of frame columns, not terminal columns ("width").

max "terminal columns" is controlled by terminal_width, which is only known when
working in a textual terminal.

This is a `df.to_string()` issue, the code you are referring too is not in play here.

``` python
In [33]: df = pd.DataFrame(0, range(5), range(35))

In [34]: s = df.to_string(line_width=80)

In [35]: print s
   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  \
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
3   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
4   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

   25  26  27  28  29  30  31  32  33  34  
0   0   0   0   0   0   0   0   0   0   0  
1   0   0   0   0   0   0   0   0   0   0  
2   0   0   0   0   0   0   0   0   0   0  
3   0   0   0   0   0   0   0   0   0   0  
4   0   0   0   0   0   0   0   0   0   0  

In [36]: lines = s.split('\n')

In [37]: len(lines[1])
Out[37]: 104

In [38]: max(len(line) for line in lines)
Out[38]: 104
```


Resolving patch:
diff --git a/pandas/core/format.py b/pandas/core/format.py
--- a/pandas/core/format.py
+++ b/pandas/core/format.py
@@ -317,10 +317,11 @@ def to_string(self, force_unicode=None):
 
     def _join_multiline(self, *strcols):
         lwidth = self.line_width
+        adjoin_width = 1
         strcols = list(strcols)
         if self.index:
             idx = strcols.pop(0)
-            lwidth -= np.array([len(x) for x in idx]).max()
+            lwidth -= np.array([len(x) for x in idx]).max() + adjoin_width
 
         col_widths = [np.array([len(x) for x in col]).max()
                       if len(col) > 0 else 0
@@ -339,7 +340,7 @@ def _join_multiline(self, *strcols):
                 else:
                     row.append([' '] * len(self.frame))
 
-            str_lst.append(adjoin(1, *row))
+            str_lst.append(adjoin(adjoin_width, *row))
             st = ed
         return '\n\n'.join(str_lst)
 
@@ -1765,14 +1766,21 @@ def _put_lines(buf, lines):
     buf.write('\n'.join(lines))
 
 
-def _binify(cols, width):
+def _binify(cols, line_width):
+    adjoin_width = 1
     bins = []
     curr_width = 0
+    i_last_column = len(cols) - 1
     for i, w in enumerate(cols):
-        curr_width += w
-        if curr_width + 2 > width and i > 0:
+        w_adjoined = w + adjoin_width
+        curr_width += w_adjoined
+        if i_last_column == i:
+            wrap = curr_width + 1 > line_width and i > 0
+        else:
+            wrap = curr_width + 2 > line_width and i > 0
+        if wrap:
             bins.append(i)
-            curr_width = w
+            curr_width = w_adjoined
 
     bins.append(len(cols))
     return bins


Test patch:
diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py
--- a/pandas/tests/test_format.py
+++ b/pandas/tests/test_format.py
@@ -909,6 +909,11 @@ def test_to_string_format_na(self):
                     '4   4     bar')
         self.assertEqual(result, expected)
 
+    def test_to_string_line_width(self):
+        df = pd.DataFrame(123, range(10, 15), range(30))
+        s = df.to_string(line_width=80)
+        self.assertEqual(max(len(l) for l in s.split('\n')), 80)
+
     def test_to_html(self):
         # big mixed
         biggie = DataFrame({'A': randn(200),