Issue #23738: Document and test actual keyword parameter names

Also fix signature because os.utime(..., ns=None) is not allowed.
This commit is contained in:
Martin Panter 2015-09-09 01:01:13 +00:00
parent 5558d4f2f8
commit bf19d16950
9 changed files with 73 additions and 31 deletions

View File

@ -59,7 +59,7 @@ The :mod:`binascii` module defines the following functions:
should be at most 57 to adhere to the base64 standard.
.. function:: a2b_qp(string, header=False)
.. function:: a2b_qp(data, header=False)
Convert a block of quoted-printable data back to binary and return the binary
data. More than one line may be passed at a time. If the optional argument

View File

@ -863,9 +863,9 @@ as internal buffering of data.
:data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`.
.. function:: open(file, flags, mode=0o777, *, dir_fd=None)
.. function:: open(path, flags, mode=0o777, *, dir_fd=None)
Open the file *file* and set various flags according to *flags* and possibly
Open the file *path* and set various flags according to *flags* and possibly
its mode according to *mode*. When computing *mode*, the current umask value
is first masked out. Return the file descriptor for the newly opened file.
The new file descriptor is :ref:`non-inheritable <fd_inheritance>`.
@ -1071,10 +1071,10 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window
:meth:`~file.read` or :meth:`~file.readline` methods.
.. function:: sendfile(out, in, offset, nbytes)
sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)
.. function:: sendfile(out, in, offset, count)
sendfile(out, in, offset, count, headers=None, trailers=None, flags=0)
Copy *nbytes* bytes from file descriptor *in* to file descriptor *out*
Copy *count* bytes from file descriptor *in* to file descriptor *out*
starting at *offset*.
Return the number of bytes sent. When EOF is reached return 0.
@ -1088,7 +1088,7 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window
*trailers* are arbitrary sequences of buffers that are written before and
after the data from *in* is written. It returns the same as the first case.
On Mac OS X and FreeBSD, a value of 0 for *nbytes* specifies to send until
On Mac OS X and FreeBSD, a value of 0 for *count* specifies to send until
the end of *in* is reached.
All platforms support sockets as *out* file descriptor, and some platforms
@ -1683,10 +1683,10 @@ features:
The *dir_fd* argument.
.. function:: mknod(filename, mode=0o600, device=0, *, dir_fd=None)
.. function:: mknod(path, mode=0o600, device=0, *, dir_fd=None)
Create a filesystem node (file, device special file or named pipe) named
*filename*. *mode* specifies both the permissions to use and the type of node
*path*. *mode* specifies both the permissions to use and the type of node
to be created, being combined (bitwise OR) with one of ``stat.S_IFREG``,
``stat.S_IFCHR``, ``stat.S_IFBLK``, and ``stat.S_IFIFO`` (those constants are
available in :mod:`stat`). For ``stat.S_IFCHR`` and ``stat.S_IFBLK``,
@ -2210,9 +2210,9 @@ features:
.. versionadded:: 3.3
.. function:: symlink(source, link_name, target_is_directory=False, *, dir_fd=None)
.. function:: symlink(src, dst, target_is_directory=False, *, dir_fd=None)
Create a symbolic link pointing to *source* named *link_name*.
Create a symbolic link pointing to *src* named *dst*.
On Windows, a symlink represents either a file or a directory, and does not
morph to the target dynamically. If the target is present, the type of the
@ -2282,20 +2282,20 @@ features:
The *dir_fd* parameter.
.. function:: utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)
.. function:: utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)
Set the access and modified times of the file specified by *path*.
:func:`utime` takes two optional parameters, *times* and *ns*.
These specify the times set on *path* and are used as follows:
- If *ns* is not ``None``,
- If *ns* is specified,
it must be a 2-tuple of the form ``(atime_ns, mtime_ns)``
where each member is an int expressing nanoseconds.
- If *times* is not ``None``,
it must be a 2-tuple of the form ``(atime, mtime)``
where each member is an int or float expressing seconds.
- If *times* and *ns* are both ``None``,
- If *times* is ``None`` and *ns* is unspecified,
this is equivalent to specifying ``ns=(atime_ns, mtime_ns)``
where both times are the current time.
@ -2846,9 +2846,10 @@ written in Python, such as a mail server's external command delivery program.
Availability: Unix.
.. function:: popen(command, mode='r', buffering=-1)
.. function:: popen(cmd, mode='r', buffering=-1)
Open a pipe to or from *command*. The return value is an open file object
Open a pipe to or from command *cmd*.
The return value is an open file object
connected to the pipe, which can be read or written depending on whether *mode*
is ``'r'`` (default) or ``'w'``. The *buffering* argument has the same meaning as
the corresponding argument to the built-in :func:`open` function. The

View File

@ -58,7 +58,7 @@ The available exception and functions in this module are:
Raises the :exc:`error` exception if any error occurs.
.. function:: compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8, strategy=Z_DEFAULT_STRATEGY[, zdict])
.. function:: compressobj(level=-1, method=DEFLATED, wbits=15, memLevel=8, strategy=Z_DEFAULT_STRATEGY[, zdict])
Returns a compression object, to be used for compressing data streams that won't
fit into memory at once.
@ -75,9 +75,9 @@ The available exception and functions in this module are:
should be an integer from ``8`` to ``15``. Higher values give better
compression, but use more memory.
*memlevel* controls the amount of memory used for internal compression state.
Valid values range from ``1`` to ``9``. Higher values using more memory,
but are faster and produce smaller output.
The *memLevel* argument controls the amount of memory used for the
internal compression state. Valid values range from ``1`` to ``9``.
Higher values use more memory, but are faster and produce smaller output.
*strategy* is used to tune the compression algorithm. Possible values are
``Z_DEFAULT_STRATEGY``, ``Z_FILTERED``, and ``Z_HUFFMAN_ONLY``.

View File

@ -179,6 +179,8 @@ class BinASCIITest(unittest.TestCase):
self.assertEqual(binascii.unhexlify(self.type2test(t)), u)
def test_qp(self):
binascii.a2b_qp(data=b"", header=False) # Keyword arguments allowed
# A test for SF bug 534347 (segfaults without the proper fix)
try:
binascii.a2b_qp(b"", **{1:1})
@ -186,6 +188,7 @@ class BinASCIITest(unittest.TestCase):
pass
else:
self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError")
self.assertEqual(binascii.a2b_qp(b"= "), b"= ")
self.assertEqual(binascii.a2b_qp(b"=="), b"=")
self.assertEqual(binascii.a2b_qp(b"=AX"), b"=AX")

View File

@ -58,7 +58,7 @@ HAVE_WHEEL_GROUP = sys.platform.startswith('freebsd') and os.getgid() == 0
# Tests creating TESTFN
class FileTests(unittest.TestCase):
def setUp(self):
if os.path.exists(support.TESTFN):
if os.path.lexists(support.TESTFN):
os.unlink(support.TESTFN)
tearDown = setUp
@ -162,6 +162,19 @@ class FileTests(unittest.TestCase):
with open(TESTFN2, 'r') as f:
self.assertEqual(f.read(), "1")
def test_open_keywords(self):
f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777,
dir_fd=None)
os.close(f)
def test_symlink_keywords(self):
symlink = support.get_attribute(os, "symlink")
try:
symlink(src='target', dst=support.TESTFN,
target_is_directory=False, dir_fd=None)
except (NotImplementedError, OSError):
pass # No OS support or unprivileged user
# Test attributes on return values from os.*stat* family.
class StatAttributeTests(unittest.TestCase):
@ -2151,6 +2164,14 @@ class TestSendfile(unittest.TestCase):
os.sendfile(self.sockno, self.fileno, -1, 4096)
self.assertEqual(cm.exception.errno, errno.EINVAL)
def test_keywords(self):
# Keyword arguments should be supported
os.sendfile(out=self.sockno, offset=0, count=4096,
**{'in': self.fileno})
if self.SUPPORT_HEADERS_TRAILERS:
os.sendfile(self.sockno, self.fileno, offset=0, count=4096,
headers=None, trailers=None, flags=0)
# --- headers / trailers tests
@requires_headers_trailers

View File

@ -57,6 +57,10 @@ class PopenTest(unittest.TestCase):
with os.popen("echo hello") as f:
self.assertEqual(list(f), ["hello\n"])
def test_keywords(self):
with os.popen(cmd="exit 0", mode="w", buffering=-1):
pass
def test_main():
support.run_unittest(PopenTest)

View File

@ -443,6 +443,14 @@ class PosixTester(unittest.TestCase):
else:
self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
# Keyword arguments are also supported
support.unlink(support.TESTFN)
try:
posix.mknod(path=support.TESTFN, mode=mode, device=0,
dir_fd=None)
except OSError as e:
self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
@unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
@unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
def test_makedev(self):

View File

@ -222,9 +222,9 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
level = 2
method = zlib.DEFLATED
wbits = -12
memlevel = 9
memLevel = 9
strategy = zlib.Z_FILTERED
co = zlib.compressobj(level, method, wbits, memlevel, strategy)
co = zlib.compressobj(level, method, wbits, memLevel, strategy)
x1 = co.compress(HAMLET_SCENE)
x2 = co.flush()
dco = zlib.decompressobj(wbits)
@ -232,6 +232,10 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
y2 = dco.flush()
self.assertEqual(HAMLET_SCENE, y1 + y2)
# keyword arguments should also be supported
zlib.compressobj(level=level, method=method, wbits=wbits,
memLevel=memLevel, strategy=strategy, zdict=b"")
def test_compressincremental(self):
# compress object in steps, decompress object as one-shot
data = HAMLET_SCENE * 128

View File

@ -4695,7 +4695,7 @@ posix_uname(PyObject *self, PyObject *noargs)
PyDoc_STRVAR(posix_utime__doc__,
"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
"utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Set the access and modified time of path.\n\
\n\
path may always be specified as a string.\n\
@ -4704,10 +4704,10 @@ On some platforms, path may also be specified as an open file descriptor.\n\
\n\
If times is not None, it must be a tuple (atime, mtime);\n\
atime and mtime should be expressed as float seconds since the epoch.\n\
If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n\
atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
since the epoch.\n\
If both times and ns are None, utime uses the current time.\n\
If times is None and ns is unspecified, utime uses the current time.\n\
Specifying tuples for both times and ns is an error.\n\
\n\
If dir_fd is not None, it should be a file descriptor open to a directory,\n\
@ -8245,10 +8245,10 @@ posix_write(PyObject *self, PyObject *args)
#ifdef HAVE_SENDFILE
PyDoc_STRVAR(posix_sendfile__doc__,
"sendfile(out, in, offset, nbytes) -> byteswritten\n\
sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
"sendfile(out, in, offset, count) -> byteswritten\n\
sendfile(out, in, offset, count, headers=None, trailers=None, flags=0)\n\
-> byteswritten\n\
Copy nbytes bytes from file descriptor in to file descriptor out.");
Copy count bytes from file descriptor in to file descriptor out.");
static PyObject *
posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
@ -8266,6 +8266,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
off_t sbytes;
struct sf_hdtr sf;
int flags = 0;
/* Beware that "in" clashes with Python's own "in" operator keyword */
static char *keywords[] = {"out", "in",
"offset", "count",
"headers", "trailers", "flags", NULL};
@ -8655,9 +8656,9 @@ exit:
#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
PyDoc_STRVAR(posix_mknod__doc__,
"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
"mknod(path, mode=0o600, device=0, *, dir_fd=None)\n\n\
Create a filesystem node (file, device special file or named pipe)\n\
named filename. mode specifies both the permissions to use and the\n\
named path. mode specifies both the permissions to use and the\n\
type of node to be created, being combined (bitwise OR) with one of\n\
S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
device defines the newly created device special file (probably using\n\