This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: open(): use keyword only for arguments other than file and mode
Type: Stage:
Components: Library (Lib) Versions: Python 3.1
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, gvanrossum, vstinner
Priority: low Keywords: needs review, patch

Created on 2008-10-14 11:02 by vstinner, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
explicit_open.patch vstinner, 2008-10-14 11:01 Use keyword-only for open()
explicit_open-fixtests.patch vstinner, 2008-10-14 11:02 Fix unit tests and some library for use the new open() API (explicit buffering argument)
Messages (7)
msg74727 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2008-10-14 11:01
In the C library, fopen() have two arguments: filename and the mode, 
and open() has three arguments: filename, mode and flags. In Python, 
open() has 7 arguments:
 - file
 - mode
 - buffering
 - encoding
 - errors
 - newline
 - closefd

Most programs only use the two first arguments, but buffering is 
sometimes set. Eg. open(filename, "r") or open(filename, "wb", 0).

I think that only the file and mode arguments are easy to understand, 
the others have to be specified using their name. Eg. 
open(filename, "wb", buffering=0) or open(filename, "r", 
encoding="GBK").

I wrote a patch to use keyword only arguments, and another to fix some 
libraries and the unit tests.

explicit_open.patch needs review. I don't know the best way to create 
a dictionary. Py_BuildValue() may be used to write a smaller patch.

--

open(file, mode, *, buffering, ...) may be replaced by open(file, 
mode, buffering, *, ...) to keep compatibility with Python2, but I 
read somewhere that Python3 breaks the compatibility and a 2to3 fixer 
can be used to fix open().
msg74732 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-10-14 11:45
It's true that the order of arguments is difficult to remember
correctly. However I think this deserves Guido's approval.

About the implementation:
To build the kw dict, did you consider using Py_BuildValue?
Something like:
   kw = Py_BuildValue("{si ss ss}",
           "buffering", buffering, 
           "encoding", encoding,
           "errors", errors,
           ...);
is simpler to write, if you consider error handling.
msg74736 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2008-10-14 12:11
socket.makefile() already uses keyword only argument, but buffering is 
not a keyword only argument:
    def makefile(self, mode="r", buffering=None, *,
                 encoding=None, newline=None):
msg74740 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-10-14 12:27
Do you suggest that 'buffering' should be allowed as positional argument?

This would help with migration from 2.x, where open() accepts 3
positional arguments:
  open(...)
      open(name[, mode[, buffering]]) -> file object
And no need to 'fix' the tests.
msg74741 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2008-10-14 12:41
> Do you suggest that 'buffering' should be allowed 
> as positional argument?

No, I would prefer to keep also two positional arguments: file and 
mode. I hate open(filename, 'r', s): I don't know what is s, the 
buffering or the encoding? And I think that beginner would also be 
distribed by this third argument. Sometimes, it's easy to understand 
the 3 arguments of a function, like re.match("[a-z]", t, 
re.IGNORECASE). But for open(), I would prefer explicit arguments.

And so socket.makefile() should also be "fixed" to keep only 2 
positional arguments.

It's my opinion and if you really want to keep compatibility with 
Python2, keep the 3 positional arguments.
msg74746 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-10-14 14:49
This is certainly out of scope for 3.0.  Remember, for 3.0 we're trying
to get a release out of the door, not cram in new features, no matter
how small.

Beyond 3.0, I'm still rather reluctant -- I expect most users will be
wise and use keyword args anyway; I'm not sure what we buy by forcing this.

I'd be okay with documenting the recommendation to always use keyword
args for any argument added in 3.0 or later (which would leave buffering
a positional argument -- I don't even know its name since it has been a
positional argument since the 1.0 days).
msg83841 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2009-03-20 01:21
Guido> Beyond 3.0, I'm still rather reluctant

Ok ok, let's close this bad idea.
History
Date User Action Args
2022-04-11 14:56:40adminsetgithub: 48371
2009-03-20 01:21:10vstinnersetstatus: open -> closed
keywords: patch, patch, needs review
resolution: rejected
messages: + msg83841
2008-10-14 14:49:23gvanrossumsetpriority: low
keywords: patch, patch, needs review
messages: + msg74746
versions: + Python 3.1, - Python 3.0
2008-10-14 12:41:42vstinnersetkeywords: patch, patch, needs review
messages: + msg74741
2008-10-14 12:27:10amaury.forgeotdarcsetkeywords: patch, patch, needs review
messages: + msg74740
2008-10-14 12:11:22vstinnersetkeywords: patch, patch, needs review
messages: + msg74736
2008-10-14 11:45:19amaury.forgeotdarcsetkeywords: patch, patch, needs review
nosy: + amaury.forgeotdarc, gvanrossum
messages: + msg74732
2008-10-14 11:02:27vstinnersetkeywords: patch, patch, needs review
files: + explicit_open-fixtests.patch
2008-10-14 11:02:01vstinnercreate