diff options
-rw-r--r-- | Doc/library/binascii.rst | 2 | ||||
-rw-r--r-- | Doc/library/os.rst | 31 | ||||
-rw-r--r-- | Doc/library/zlib.rst | 8 | ||||
-rw-r--r-- | Lib/test/test_binascii.py | 3 | ||||
-rw-r--r-- | Lib/test/test_os.py | 23 | ||||
-rw-r--r-- | Lib/test/test_popen.py | 4 | ||||
-rw-r--r-- | Lib/test/test_posix.py | 8 | ||||
-rw-r--r-- | Lib/test/test_zlib.py | 8 | ||||
-rw-r--r-- | Modules/clinic/posixmodule.c.h | 6 | ||||
-rw-r--r-- | Modules/posixmodule.c | 15 |
10 files changed, 75 insertions, 33 deletions
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 3f7df74..e3f134b 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -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 diff --git a/Doc/library/os.rst b/Doc/library/os.rst index d4032e0..25888e4 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -857,9 +857,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 :exc:`InterruptedError` exception (see :pep:`475` for the rationale). -.. 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 @@ -1690,10 +1690,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``, @@ -2389,9 +2389,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 @@ -2461,20 +2461,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. @@ -3023,9 +3023,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 diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index b178fe1..aea0e79 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -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``. diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 4e67887..8367afe 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -178,6 +178,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}) @@ -185,6 +187,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") diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index d91f58c..f675259 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -85,7 +85,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 @@ -209,6 +209,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): @@ -2313,6 +2326,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 diff --git a/Lib/test/test_popen.py b/Lib/test/test_popen.py index 8958db0..da01a87 100644 --- a/Lib/test/test_popen.py +++ b/Lib/test/test_popen.py @@ -57,5 +57,9 @@ 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 + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 77e5b0c4..2a59c38 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -442,6 +442,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): diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index bd935ed..7cd1d7c 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -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 diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 98eeae4..9ef702a 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1487,10 +1487,10 @@ PyDoc_STRVAR(os_utime__doc__, "\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" @@ -5788,4 +5788,4 @@ exit: #ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF #define OS_SET_HANDLE_INHERITABLE_METHODDEF #endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ -/*[clinic end generated code: output=f3f92b2d2e2c3fe3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=95824c52fd034654 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d8bb060..5697495 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4679,7 +4679,7 @@ os.utime dir_fd: dir_fd(requires='futimensat') = None follow_symlinks: bool=True -# "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. @@ -4689,10 +4689,10 @@ On some platforms, path may also be specified as an open file descriptor. If times is not None, it must be a tuple (atime, mtime); atime and mtime should be expressed as float seconds since the epoch. -If ns is not None, it must be a tuple (atime_ns, mtime_ns); +If ns is specified, it must be a tuple (atime_ns, mtime_ns); atime_ns and mtime_ns should be expressed as integer nanoseconds since the epoch. -If both times and ns are None, utime uses the current time. +If times is None and ns is unspecified, utime uses the current time. Specifying tuples for both times and ns is an error. If dir_fd is not None, it should be a file descriptor open to a directory, @@ -4710,7 +4710,7 @@ dir_fd and follow_symlinks may not be available on your platform. static PyObject * os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=31f3434e560ba2f0 input=1f18c17d5941aa82]*/ +/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/ { #ifdef MS_WINDOWS HANDLE hFile; @@ -8235,10 +8235,10 @@ os_write_impl(PyModuleDef *module, int fd, Py_buffer *data) #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."); /* AC 3.5: don't bother converting, has optional group*/ static PyObject * @@ -8258,6 +8258,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}; |