Skip to content

socket.makefile does not handle line buffering #75245

Closed

Description

@kchen
mannequin
BPO 31062
Nosy @giampaolo, @vxgmichel
PRs
  • gh-75245: Allow socket.makefile to handle line buffering properly #12370
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2017-07-27.21:11:45.908>
    labels = ['3.7', '3.8', 'type-bug', 'library']
    title = 'socket.makefile does not handle line buffering'
    updated_at = <Date 2019-03-17.15:51:57.119>
    user = 'https://bugs.python.org/kchen'

    bugs.python.org fields:

    activity = <Date 2019-03-17.15:51:57.119>
    actor = 'cheryl.sabella'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2017-07-27.21:11:45.908>
    creator = 'kchen'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 31062
    keywords = ['patch']
    message_count = 2.0
    messages = ['299351', '338088']
    nosy_count = 3.0
    nosy_names = ['giampaolo.rodola', 'kchen', 'vxgmichel']
    pr_nums = ['12370']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue31062'
    versions = ['Python 3.7', 'Python 3.8']

    Activity

    1. kchen commented on Jul 27, 2017

      kchenmannequin
      MannequinAuthor

      File objects generated with socket.makefile and that attempt to use line buffering appear to not actually use line buffering, at least for writing. In this example, the string does not appear to be written until the flush call.

      First, set up a socket:
      $ nc -l -U /tmp/foo

      Then:

      Python 3.6.2 (default, Jul 26 2017, 01:41:27) 
      [GCC 4.8.4] on linux
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import socket
      >>> s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
      >>> s.connect("/tmp/foo")
      >>> f = s.makefile("rw", buffering=1)
      >>> f.write("asdf\n")
      5
      >>> f.flush()

      The following patch appears to fix the problem:

      --- socket.py.orig	2017-07-25 21:41:39.974554944 -0400
      +++ socket.py	2017-07-27 17:02:58.223353418 -0400
      @@ -253,7 +253,11 @@
                   buffer = io.BufferedWriter(raw, buffering)
               if binary:
                   return buffer
      -        text = io.TextIOWrapper(buffer, encoding, errors, newline)
      +        line_buffering = False
      +        if buffering == 1:
      +            line_buffering = True
      +        text = io.TextIOWrapper(buffer, encoding, errors, newline,
      +                                line_buffering)
               text.mode = mode
               return text
    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Jul 27, 2017
    3. vxgmichel commented on Mar 16, 2019

      vxgmichelmannequin
      Mannequin

      I ran into this issue too so I went ahead and created a pull request (#12370).

    4. transferred this issue fromon Apr 10, 2022
    5. added
      type-featureA feature request or enhancement
      3.16new features, bugs and security fixes
      and removed on Aug 12, 2026
    6. serhiy-storchaka commented on Aug 12, 2026

      @serhiy-storchaka
      Member

      This worked in Python 2, where makefile() returned socket._fileobject, which implemented buffering itself: bufsize=1 meant line buffering for writing and default buffering for reading, in any mode, because there was no text and binary distinction at that level. It was lost when makefile() was reimplemented on top of the io module, where line buffering only exists in TextIOWrapper.

      #12370 passes line_buffering to TextIOWrapper, so buffering=1 works again in text mode. In binary mode it now emits a RuntimeWarning and uses the default buffer size, as open() does; previously it silently created a 1-byte buffer.

      LineBufferedFileObjectClassTestCase is a leftover from Python 2: it sets bufsize = 1, but uses binary mode, where line buffering has never worked in Python 3. It is replaced with a test in text mode.

    7. added a commit that references this issue on Aug 12, 2026
    8. added a commit that references this issue on Aug 14, 2026
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.16new features, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-socketRelated to the socket, socketserver and selectors modulestype-bugAn unexpected behavior, bug, or errortype-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions