#13152: Allow to specify a custom tabsize for expanding tabs in textwrap

Patch by John Feuerstein.
diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst
index a814962..a74789c 100644
--- a/Doc/library/textwrap.rst
+++ b/Doc/library/textwrap.rst
@@ -107,6 +107,15 @@
       expanded to spaces using the :meth:`expandtabs` method of *text*.
 
 
+   .. attribute:: tabsize
+
+      (default: ``8``) If :attr:`expand_tabs` is true, then all tab characters
+      in *text* will be expanded to zero or more spaces, depending on the
+      current column and the given tab size.
+
+      .. versionadded:: 3.3
+
+
    .. attribute:: replace_whitespace
 
       (default: ``True``) If true, each whitespace character (as defined by
diff --git a/Lib/test/test_textwrap.py b/Lib/test/test_textwrap.py
index 905dd4c..bbd0882 100644
--- a/Lib/test/test_textwrap.py
+++ b/Lib/test/test_textwrap.py
@@ -91,6 +91,14 @@
         result = wrapper.fill(text)
         self.check(result, '\n'.join(expect))
 
+        text = "\tTest\tdefault\t\ttabsize."
+        expect = ["        Test    default         tabsize."]
+        self.check_wrap(text, 80, expect)
+
+        text = "\tTest\tcustom\t\ttabsize."
+        expect = ["    Test    custom      tabsize."]
+        self.check_wrap(text, 80, expect, tabsize=4)
+
     def test_fix_sentence_endings(self):
         wrapper = TextWrapper(60, fix_sentence_endings=True)
 
diff --git a/Lib/textwrap.py b/Lib/textwrap.py
index 0aeba3f..66ccf2b 100644
--- a/Lib/textwrap.py
+++ b/Lib/textwrap.py
@@ -39,8 +39,11 @@
         of wrapped output; also counts towards each line's width.
       expand_tabs (default: true)
         Expand tabs in input text to spaces before further processing.
-        Each tab will become 1 .. 8 spaces, depending on its position in
-        its line.  If false, each tab is treated as a single character.
+        Each tab will become 0 .. 'tabsize' spaces, depending on its position
+        in its line.  If false, each tab is treated as a single character.
+      tabsize (default: 8)
+        Expand tabs in input text to 0 .. 'tabsize' spaces, unless
+        'expand_tabs' is false.
       replace_whitespace (default: true)
         Replace all whitespace characters in the input text by spaces
         after tab expansion.  Note that if expand_tabs is false and
@@ -100,7 +103,8 @@
                  fix_sentence_endings=False,
                  break_long_words=True,
                  drop_whitespace=True,
-                 break_on_hyphens=True):
+                 break_on_hyphens=True,
+                 tabsize=8):
         self.width = width
         self.initial_indent = initial_indent
         self.subsequent_indent = subsequent_indent
@@ -110,6 +114,7 @@
         self.break_long_words = break_long_words
         self.drop_whitespace = drop_whitespace
         self.break_on_hyphens = break_on_hyphens
+        self.tabsize = tabsize
 
 
     # -- Private methods -----------------------------------------------
@@ -123,7 +128,7 @@
         becomes " foo    bar  baz".
         """
         if self.expand_tabs:
-            text = text.expandtabs()
+            text = text.expandtabs(self.tabsize)
         if self.replace_whitespace:
             text = text.translate(self.unicode_whitespace_trans)
         return text
diff --git a/Misc/NEWS b/Misc/NEWS
index 013c8f1..2fb2bb0 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -38,6 +38,9 @@
 Library
 -------
 
+- Issue #13152: Allow to specify a custom tabsize for expanding tabs in
+  textwrap. Patch by John Feuerstein.
+
 - Issue #14721: Send the correct 'Content-length: 0' header when the body is an
   empty string ''. Initial Patch contributed by Arve Knudsen.