From webhook-mailer at python.org Tue May 1 00:06:03 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 01 May 2018 04:06:03 -0000 Subject: [Python-checkins] bpo-31908: Fix output of cover files for trace module command-line tool. (GH-4205) Message-ID: https://github.com/python/cpython/commit/e4eeb6eff12947a55df5eabee36e537cadefbbac commit: e4eeb6eff12947a55df5eabee36e537cadefbbac branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-04-30T21:06:00-07:00 summary: bpo-31908: Fix output of cover files for trace module command-line tool. (GH-4205) Previously emitted cover files only when --missing option was used. (cherry picked from commit 47ab15470d72367694d7758004067313ae022f0e) Co-authored-by: Michael Selik files: A Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst M Lib/test/test_trace.py M Lib/trace.py diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index e04ca01c4299..55a8bcea3e54 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -2,6 +2,7 @@ import sys from test.support import TESTFN, rmtree, unlink, captured_stdout from test.support.script_helper import assert_python_ok, assert_python_failure +import textwrap import unittest import trace @@ -365,6 +366,46 @@ def test_ignored(self): # Matched before. self.assertTrue(ignore.names(jn('bar', 'baz.py'), 'baz')) +# Created for Issue 31908 -- CLI utility not writing cover files +class TestCoverageCommandLineOutput(unittest.TestCase): + + codefile = 'tmp.py' + coverfile = 'tmp.cover' + + def setUp(self): + with open(self.codefile, 'w') as f: + f.write(textwrap.dedent('''\ + x = 42 + if []: + print('unreachable') + ''')) + + def tearDown(self): + unlink(self.codefile) + unlink(self.coverfile) + + def test_cover_files_written_no_highlight(self): + argv = '-m trace --count'.split() + [self.codefile] + status, stdout, stderr = assert_python_ok(*argv) + self.assertTrue(os.path.exists(self.coverfile)) + with open(self.coverfile) as f: + self.assertEqual(f.read(), + " 1: x = 42\n" + " 1: if []:\n" + " print('unreachable')\n" + ) + + def test_cover_files_written_with_highlight(self): + argv = '-m trace --count --missing'.split() + [self.codefile] + status, stdout, stderr = assert_python_ok(*argv) + self.assertTrue(os.path.exists(self.coverfile)) + with open(self.coverfile) as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + 1: x = 42 + 1: if []: + >>>>>> print('unreachable') + ''')) + class TestCommandLine(unittest.TestCase): def test_failures(self): diff --git a/Lib/trace.py b/Lib/trace.py index ade76166bdd2..16c3494689dd 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -73,9 +73,6 @@ def _unsettrace(): PRAGMA_NOCOVER = "#pragma NO COVER" -# Simple rx to find lines with no code. -rx_blank = re.compile(r'^\s*(#.*)?$') - class _Ignore: def __init__(self, modules=None, dirs=None): self._mods = set() if not modules else set(modules) @@ -278,16 +275,15 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): lnotab = _find_executable_linenos(filename) else: lnotab = {} - if lnotab: - source = linecache.getlines(filename) - coverpath = os.path.join(dir, modulename + ".cover") - with open(filename, 'rb') as fp: - encoding, _ = tokenize.detect_encoding(fp.readline) - n_hits, n_lines = self.write_results_file(coverpath, source, - lnotab, count, encoding) - if summary and n_lines: - percent = int(100 * n_hits / n_lines) - sums[modulename] = n_lines, percent, modulename, filename + source = linecache.getlines(filename) + coverpath = os.path.join(dir, modulename + ".cover") + with open(filename, 'rb') as fp: + encoding, _ = tokenize.detect_encoding(fp.readline) + n_hits, n_lines = self.write_results_file(coverpath, source, + lnotab, count, encoding) + if summary and n_lines: + percent = int(100 * n_hits / n_lines) + sums[modulename] = n_lines, percent, modulename, filename if summary and sums: @@ -306,6 +302,7 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None): """Return a coverage results file in path.""" + # ``lnotab`` is a dict of executable lines, or a line number "table" try: outfile = open(path, "w", encoding=encoding) @@ -324,17 +321,13 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None): outfile.write("%5d: " % lines_hit[lineno]) n_hits += 1 n_lines += 1 - elif rx_blank.match(line): - outfile.write(" ") - else: - # lines preceded by no marks weren't hit - # Highlight them if so indicated, unless the line contains + elif lineno in lnotab and not PRAGMA_NOCOVER in line: + # Highlight never-executed lines, unless the line contains # #pragma: NO COVER - if lineno in lnotab and not PRAGMA_NOCOVER in line: - outfile.write(">>>>>> ") - n_lines += 1 - else: - outfile.write(" ") + outfile.write(">>>>>> ") + n_lines += 1 + else: + outfile.write(" ") outfile.write(line.expandtabs(8)) return n_hits, n_lines diff --git a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst new file mode 100644 index 000000000000..700bc690764f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst @@ -0,0 +1,3 @@ +Fix output of cover files for ``trace`` module command-line tool. +Previously emitted cover files only when ``--missing`` option was used. +Patch by Michael Selik. \ No newline at end of file From webhook-mailer at python.org Tue May 1 01:03:32 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 01 May 2018 05:03:32 -0000 Subject: [Python-checkins] bpo-31908: Fix output of cover files for trace module command-line tool. (GH-4205) Message-ID: https://github.com/python/cpython/commit/a607f8b9982ac95bb59f8f61e0a50fc5ae29dc14 commit: a607f8b9982ac95bb59f8f61e0a50fc5ae29dc14 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-04-30T22:03:29-07:00 summary: bpo-31908: Fix output of cover files for trace module command-line tool. (GH-4205) Previously emitted cover files only when --missing option was used. (cherry picked from commit 47ab15470d72367694d7758004067313ae022f0e) Co-authored-by: Michael Selik files: A Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst M Lib/test/test_trace.py M Lib/trace.py diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index e04ca01c4299..55a8bcea3e54 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -2,6 +2,7 @@ import sys from test.support import TESTFN, rmtree, unlink, captured_stdout from test.support.script_helper import assert_python_ok, assert_python_failure +import textwrap import unittest import trace @@ -365,6 +366,46 @@ def test_ignored(self): # Matched before. self.assertTrue(ignore.names(jn('bar', 'baz.py'), 'baz')) +# Created for Issue 31908 -- CLI utility not writing cover files +class TestCoverageCommandLineOutput(unittest.TestCase): + + codefile = 'tmp.py' + coverfile = 'tmp.cover' + + def setUp(self): + with open(self.codefile, 'w') as f: + f.write(textwrap.dedent('''\ + x = 42 + if []: + print('unreachable') + ''')) + + def tearDown(self): + unlink(self.codefile) + unlink(self.coverfile) + + def test_cover_files_written_no_highlight(self): + argv = '-m trace --count'.split() + [self.codefile] + status, stdout, stderr = assert_python_ok(*argv) + self.assertTrue(os.path.exists(self.coverfile)) + with open(self.coverfile) as f: + self.assertEqual(f.read(), + " 1: x = 42\n" + " 1: if []:\n" + " print('unreachable')\n" + ) + + def test_cover_files_written_with_highlight(self): + argv = '-m trace --count --missing'.split() + [self.codefile] + status, stdout, stderr = assert_python_ok(*argv) + self.assertTrue(os.path.exists(self.coverfile)) + with open(self.coverfile) as f: + self.assertEqual(f.read(), textwrap.dedent('''\ + 1: x = 42 + 1: if []: + >>>>>> print('unreachable') + ''')) + class TestCommandLine(unittest.TestCase): def test_failures(self): diff --git a/Lib/trace.py b/Lib/trace.py index 9ba9486bd024..d171577e3991 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -79,9 +79,6 @@ def _unsettrace(): PRAGMA_NOCOVER = "#pragma NO COVER" -# Simple rx to find lines with no code. -rx_blank = re.compile(r'^\s*(#.*)?$') - class _Ignore: def __init__(self, modules=None, dirs=None): self._mods = set() if not modules else set(modules) @@ -284,16 +281,15 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): lnotab = _find_executable_linenos(filename) else: lnotab = {} - if lnotab: - source = linecache.getlines(filename) - coverpath = os.path.join(dir, modulename + ".cover") - with open(filename, 'rb') as fp: - encoding, _ = tokenize.detect_encoding(fp.readline) - n_hits, n_lines = self.write_results_file(coverpath, source, - lnotab, count, encoding) - if summary and n_lines: - percent = int(100 * n_hits / n_lines) - sums[modulename] = n_lines, percent, modulename, filename + source = linecache.getlines(filename) + coverpath = os.path.join(dir, modulename + ".cover") + with open(filename, 'rb') as fp: + encoding, _ = tokenize.detect_encoding(fp.readline) + n_hits, n_lines = self.write_results_file(coverpath, source, + lnotab, count, encoding) + if summary and n_lines: + percent = int(100 * n_hits / n_lines) + sums[modulename] = n_lines, percent, modulename, filename if summary and sums: @@ -312,6 +308,7 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None): """Return a coverage results file in path.""" + # ``lnotab`` is a dict of executable lines, or a line number "table" try: outfile = open(path, "w", encoding=encoding) @@ -330,17 +327,13 @@ def write_results_file(self, path, lines, lnotab, lines_hit, encoding=None): outfile.write("%5d: " % lines_hit[lineno]) n_hits += 1 n_lines += 1 - elif rx_blank.match(line): - outfile.write(" ") - else: - # lines preceded by no marks weren't hit - # Highlight them if so indicated, unless the line contains + elif lineno in lnotab and not PRAGMA_NOCOVER in line: + # Highlight never-executed lines, unless the line contains # #pragma: NO COVER - if lineno in lnotab and not PRAGMA_NOCOVER in line: - outfile.write(">>>>>> ") - n_lines += 1 - else: - outfile.write(" ") + outfile.write(">>>>>> ") + n_lines += 1 + else: + outfile.write(" ") outfile.write(line.expandtabs(8)) return n_hits, n_lines diff --git a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst new file mode 100644 index 000000000000..700bc690764f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst @@ -0,0 +1,3 @@ +Fix output of cover files for ``trace`` module command-line tool. +Previously emitted cover files only when ``--missing`` option was used. +Patch by Michael Selik. \ No newline at end of file From solipsis at pitrou.net Tue May 1 05:18:51 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 01 May 2018 09:18:51 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=6 Message-ID: <20180501091851.1.86CD088A051D1AC8@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [2, 0, 0] memory blocks, sum=2 test_multiprocessing_forkserver leaked [-1, 2, -1] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogL8_3jG', '--timeout', '7200'] From webhook-mailer at python.org Tue May 1 05:46:46 2018 From: webhook-mailer at python.org (Julien Palard) Date: Tue, 01 May 2018 09:46:46 -0000 Subject: [Python-checkins] Add What's New for Korean documentation translation. (GH-6645) Message-ID: https://github.com/python/cpython/commit/335a602666d3b94352c194fe002430dda3c0ab2b commit: 335a602666d3b94352c194fe002430dda3c0ab2b branch: master author: Julien Palard committer: GitHub date: 2018-05-01T11:46:43+02:00 summary: Add What's New for Korean documentation translation. (GH-6645) files: M Doc/whatsnew/3.7.rst diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 3ce20fafd376..408fed4572fa 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -1354,7 +1354,7 @@ PEP 545: Python Documentation Translations ------------------------------------------ :pep:`545` describes the process to translate Python documentation, -and two translations have been added: +and three translations have been added: - Japanese: https://docs.python.org/ja/ and associated GitHub repository: https://github.com/python/python-docs-ja @@ -1362,5 +1362,8 @@ and two translations have been added: - French: https://docs.python.org/fr/ and associated GitHub repository: https://github.com/python/python-docs-fr +- Korean: https://docs.python.org/ko/ and associated GitHub + repository: https://github.com/python/python-docs-ko + (Contributed by Julien Palard, Inada Naoki, and Victor Stinner in :issue:`26546`.) From webhook-mailer at python.org Tue May 1 05:47:20 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 01 May 2018 09:47:20 -0000 Subject: [Python-checkins] bpo-33378: Add Korean to the language switcher. (GH-6627) Message-ID: https://github.com/python/cpython/commit/dc5c92fcb2aafd7f133f9f6986d8d05ac6e5160f commit: dc5c92fcb2aafd7f133f9f6986d8d05ac6e5160f branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-01T02:47:17-07:00 summary: bpo-33378: Add Korean to the language switcher. (GH-6627) (cherry picked from commit 577948329976985ea9bef23d9a6c3dd7108211bf) Co-authored-by: Dong-hee Na files: A Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst M Doc/tools/static/switchers.js diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js index 8e0c5ea0092a..3dea08e523bf 100644 --- a/Doc/tools/static/switchers.js +++ b/Doc/tools/static/switchers.js @@ -21,6 +21,7 @@ 'en': 'English', 'fr': 'French', 'ja': 'Japanese', + 'ko': 'Korean', }; function build_version_select(current_version, current_release) { diff --git a/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst b/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst new file mode 100644 index 000000000000..43214d10b7c5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst @@ -0,0 +1 @@ +Add Korean language switcher for https://docs.python.org/3/ From webhook-mailer at python.org Tue May 1 06:02:29 2018 From: webhook-mailer at python.org (Julien Palard) Date: Tue, 01 May 2018 10:02:29 -0000 Subject: [Python-checkins] bpo-20709: os.utime(path_to_directory): wrong documentation for Windows. (GH-5469) Message-ID: https://github.com/python/cpython/commit/7508a54c77e85235e07e344cf9440e5b4695e9cc commit: 7508a54c77e85235e07e344cf9440e5b4695e9cc branch: master author: St?phane Wirtel committer: Julien Palard date: 2018-05-01T12:02:26+02:00 summary: bpo-20709: os.utime(path_to_directory): wrong documentation for Windows. (GH-5469) Remove the paragraph where we explain that os.utime() does not support a directory as path under Windows. Patch by Jan-Philip Gehrcke Co-authored-by: Jan-Philip Gehrcke files: A Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 2f3b31edd5d7..2e81459a2504 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2768,14 +2768,12 @@ features: It is an error to specify tuples for both *times* and *ns*. - Whether a directory can be given for *path* - depends on whether the operating system implements directories as files - (for example, Windows does not). Note that the exact times you set here may - not be returned by a subsequent :func:`~os.stat` call, depending on the - resolution with which your operating system records access and modification - times; see :func:`~os.stat`. The best way to preserve exact times is to - use the *st_atime_ns* and *st_mtime_ns* fields from the :func:`os.stat` - result object with the *ns* parameter to `utime`. + Note that the exact times you set here may not be returned by a subsequent + :func:`~os.stat` call, depending on the resolution with which your operating + system records access and modification times; see :func:`~os.stat`. The best + way to preserve exact times is to use the *st_atime_ns* and *st_mtime_ns* + fields from the :func:`os.stat` result object with the *ns* parameter to + `utime`. This function can support :ref:`specifying a file descriptor `, :ref:`paths relative to directory descriptors ` and :ref:`not diff --git a/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst b/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst new file mode 100644 index 000000000000..b14c0f54eb3b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-02-01-10-57-24.bpo-20709.1flcnc.rst @@ -0,0 +1,2 @@ +Remove the paragraph where we explain that os.utime() does not support a +directory as path under Windows. Patch by Jan-Philip Gehrcke From webhook-mailer at python.org Tue May 1 09:45:07 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 01 May 2018 13:45:07 -0000 Subject: [Python-checkins] bpo-20104: Improve error handling and fix a reference leak in os.posix_spawn(). (#6332) Message-ID: https://github.com/python/cpython/commit/ef347535f289baad22c0601e12a36b2dcd155c3a commit: ef347535f289baad22c0601e12a36b2dcd155c3a branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-01T16:45:04+03:00 summary: bpo-20104: Improve error handling and fix a reference leak in os.posix_spawn(). (#6332) files: A Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst M Doc/library/os.rst M Lib/test/test_posix.py M Modules/clinic/posixmodule.c.h M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 2e81459a2504..4b4e93106692 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3365,25 +3365,41 @@ written in Python, such as a mail server's external command delivery program. .. function:: posix_spawn(path, argv, env, file_actions=None) - Wraps the posix_spawn() C library API for use from Python. + Wraps the :c:func:`posix_spawn` C library API for use from Python. - Most users should use :class:`subprocess.run` instead of posix_spawn. + Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`. The *path*, *args*, and *env* arguments are similar to :func:`execve`. The *file_actions* argument may be a sequence of tuples describing actions to take on specific file descriptors in the child process between the C - library implementation's fork and exec steps. The first item in each tuple - must be one of the three type indicator listed below describing the - remaining tuple elements: + library implementation's :c:func:`fork` and :c:func:`exec` steps. + The first item in each tuple must be one of the three type indicator + listed below describing the remaining tuple elements: - (os.POSIX_SPAWN_OPEN, fd, path, open flags, mode) - (os.POSIX_SPAWN_CLOSE, fd) - (os.POSIX_SPAWN_DUP2, fd, new_fd) + .. data:: POSIX_SPAWN_OPEN - These tuples correspond to the C library posix_spawn_file_actions_addopen, - posix_spawn_file_actions_addclose, and posix_spawn_file_actions_adddup2 API - calls used to prepare for the posix_spawn call itself. + (``os.POSIX_SPAWN_OPEN``, *fd*, *path*, *flags*, *mode*) + + Performs ``os.dup2(os.open(path, flags, mode), fd)``. + + .. data:: POSIX_SPAWN_CLOSE + + (``os.POSIX_SPAWN_CLOSE``, *fd*) + + Performs ``os.close(fd)``. + + .. data:: POSIX_SPAWN_DUP2 + + (``os.POSIX_SPAWN_DUP2``, *fd*, *new_fd*) + + Performs ``os.dup2(fd, new_fd)``. + + These tuples correspond to the C library + :c:func:`posix_spawn_file_actions_addopen`, + :c:func:`posix_spawn_file_actions_addclose`, and + :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare + for the :c:func:`posix_spawn` call itself. .. versionadded:: 3.7 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 8ada0e3ab3c7..b94da3f45a2c 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -177,22 +177,6 @@ def test_fexecve(self): os.close(fp) - @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") - def test_posix_spawn(self): - pid = posix.posix_spawn(sys.executable, [sys.executable, "-c", "pass"], os.environ,[]) - self.assertEqual(os.waitpid(pid,0),(pid,0)) - - - @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") - def test_posix_spawn_file_actions(self): - file_actions = [] - file_actions.append((0,3,os.path.realpath(__file__),0,0)) - file_actions.append((os.POSIX_SPAWN_CLOSE,2)) - file_actions.append((os.POSIX_SPAWN_DUP2,1,4)) - pid = posix.posix_spawn(sys.executable, [sys.executable, "-c", "pass"], os.environ, file_actions) - self.assertEqual(os.waitpid(pid,0),(pid,0)) - - @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()") @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") def test_waitid(self): @@ -1437,9 +1421,168 @@ def test_setgroups(self): posix.setgroups(groups) self.assertListEqual(groups, posix.getgroups()) + + at unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") +class TestPosixSpawn(unittest.TestCase): + def test_returns_pid(self): + pidfile = support.TESTFN + self.addCleanup(support.unlink, pidfile) + script = f"""if 1: + import os + with open({pidfile!r}, "w") as pidfile: + pidfile.write(str(os.getpid())) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(pidfile) as f: + self.assertEqual(f.read(), str(pid)) + + def test_no_such_executable(self): + no_such_executable = 'no_such_executable' + try: + pid = posix.posix_spawn(no_such_executable, + [no_such_executable], + os.environ) + except FileNotFoundError as exc: + self.assertEqual(exc.filename, no_such_executable) + else: + pid2, status = os.waitpid(pid, 0) + self.assertEqual(pid2, pid) + self.assertNotEqual(status, 0) + + def test_specify_environment(self): + envfile = support.TESTFN + self.addCleanup(support.unlink, envfile) + script = f"""if 1: + import os + with open({envfile!r}, "w") as envfile: + envfile.write(os.environ['foo']) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + {'foo': 'bar'}) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(envfile) as f: + self.assertEqual(f.read(), 'bar') + + def test_empty_file_actions(self): + pid = posix.posix_spawn( + sys.executable, + [sys.executable, '-c', 'pass'], + os.environ, + [] + ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_multiple_file_actions(self): + file_actions = [ + (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0), + (os.POSIX_SPAWN_CLOSE, 0), + (os.POSIX_SPAWN_DUP2, 1, 4), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_bad_file_actions(self): + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [None]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [()]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(None,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(12345,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, 1, 2)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, None)]) + with self.assertRaises(ValueError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, + [(os.POSIX_SPAWN_OPEN, 3, __file__ + '\0', + os.O_RDONLY, 0)]) + + def test_open_file(self): + outfile = support.TESTFN + self.addCleanup(support.unlink, outfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + file_actions = [ + (os.POSIX_SPAWN_OPEN, 1, outfile, + os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + stat.S_IRUSR | stat.S_IWUSR), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(outfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_close_file(self): + closefile = support.TESTFN + self.addCleanup(support.unlink, closefile) + script = f"""if 1: + import os + try: + os.fstat(0) + except OSError as e: + with open({closefile!r}, 'w') as closefile: + closefile.write('is closed %d' % e.errno) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, + [(os.POSIX_SPAWN_CLOSE, 0),]) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(closefile) as f: + self.assertEqual(f.read(), 'is closed %d' % errno.EBADF) + + def test_dup2(self): + dupfile = support.TESTFN + self.addCleanup(support.unlink, dupfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + with open(dupfile, "wb") as childfile: + file_actions = [ + (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(dupfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_main(): try: - support.run_unittest(PosixTester, PosixGroupsTester) + support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn) finally: support.reap_children() diff --git a/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst new file mode 100644 index 000000000000..150401dc7412 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst @@ -0,0 +1 @@ +Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 4054389d15f3..e4bbd082450b 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1742,7 +1742,7 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " env\n" " Dictionary of strings mapping to strings.\n" " file_actions\n" -" FileActions object."); +" A sequence of file action tuples."); #define OS_POSIX_SPAWN_METHODDEF \ {"posix_spawn", (PyCFunction)os_posix_spawn, METH_FASTCALL, os_posix_spawn__doc__}, @@ -6589,4 +6589,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=fc603214822bdda6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8d3d9dddf254c3c2 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index e6721032f211..4ac6e7658999 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5114,6 +5114,111 @@ enum posix_spawn_file_actions_identifier { POSIX_SPAWN_DUP2 }; +static int +parse_file_actions(PyObject *file_actions, + posix_spawn_file_actions_t *file_actionsp) +{ + PyObject *seq; + PyObject *file_action = NULL; + PyObject *tag_obj; + + seq = PySequence_Fast(file_actions, + "file_actions must be a sequence or None"); + if (seq == NULL) { + return -1; + } + + errno = posix_spawn_file_actions_init(file_actionsp); + if (errno) { + posix_error(); + Py_DECREF(seq); + return -1; + } + + for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { + file_action = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(file_action); + if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { + PyErr_SetString(PyExc_TypeError, + "Each file_actions element must be a non-empty tuple"); + goto fail; + } + long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0)); + if (tag == -1 && PyErr_Occurred()) { + goto fail; + } + + /* Populate the file_actions object */ + switch (tag) { + case POSIX_SPAWN_OPEN: { + int fd, oflag; + PyObject *path; + unsigned long mode; + if (!PyArg_ParseTuple(file_action, "OiO&ik" + ";A open file_action tuple must have 5 elements", + &tag_obj, &fd, PyUnicode_FSConverter, &path, + &oflag, &mode)) + { + goto fail; + } + errno = posix_spawn_file_actions_addopen(file_actionsp, + fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); + Py_DECREF(path); /* addopen copied it. */ + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_CLOSE: { + int fd; + if (!PyArg_ParseTuple(file_action, "Oi" + ";A close file_action tuple must have 2 elements", + &tag_obj, &fd)) + { + goto fail; + } + errno = posix_spawn_file_actions_addclose(file_actionsp, fd); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_DUP2: { + int fd1, fd2; + if (!PyArg_ParseTuple(file_action, "Oii" + ";A dup2 file_action tuple must have 3 elements", + &tag_obj, &fd1, &fd2)) + { + goto fail; + } + errno = posix_spawn_file_actions_adddup2(file_actionsp, + fd1, fd2); + if (errno) { + posix_error(); + goto fail; + } + break; + } + default: { + PyErr_SetString(PyExc_TypeError, + "Unknown file_actions identifier"); + goto fail; + } + } + Py_DECREF(file_action); + } + Py_DECREF(seq); + return 0; + +fail: + Py_DECREF(seq); + Py_DECREF(file_action); + (void)posix_spawn_file_actions_destroy(file_actionsp); + return -1; +} + /*[clinic input] os.posix_spawn @@ -5124,7 +5229,7 @@ os.posix_spawn env: object Dictionary of strings mapping to strings. file_actions: object = None - FileActions object. + A sequence of file action tuples. / Execute the program specified by path in a new process. @@ -5133,22 +5238,22 @@ Execute the program specified by path in a new process. static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions) -/*[clinic end generated code: output=d023521f541c709c input=0ec9f1cfdc890be5]*/ +/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/ { EXECV_CHAR **argvlist = NULL; EXECV_CHAR **envlist = NULL; - posix_spawn_file_actions_t _file_actions; + posix_spawn_file_actions_t file_actions_buf; posix_spawn_file_actions_t *file_actionsp = NULL; Py_ssize_t argc, envc; - PyObject* result = NULL; - PyObject* seq = NULL; - + PyObject *result = NULL; + pid_t pid; + int err_code; /* posix_spawn has three arguments: (path, argv, env), where - argv is a list or tuple of strings and env is a dictionary + argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PySequence_Check(argv)) { + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "posix_spawn: argv must be a tuple or list"); goto exit; @@ -5180,139 +5285,35 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, goto exit; } - pid_t pid; - if (file_actions != NULL && file_actions != Py_None) { - if(posix_spawn_file_actions_init(&_file_actions) != 0){ - PyErr_SetString(PyExc_OSError, - "Error initializing file actions"); - goto exit; - } - - file_actionsp = &_file_actions; - - seq = PySequence_Fast(file_actions, "file_actions must be a sequence"); - if(seq == NULL) { + if (file_actions != Py_None) { + if (parse_file_actions(file_actions, &file_actions_buf)) { goto exit; } - PyObject* file_actions_obj; - PyObject* mode_obj; - - for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { - file_actions_obj = PySequence_Fast_GET_ITEM(seq, i); - - if(!PySequence_Check(file_actions_obj) | !PySequence_Size(file_actions_obj)) { - PyErr_SetString(PyExc_TypeError,"Each file_action element must be a non empty sequence"); - goto exit; - } - - - mode_obj = PySequence_Fast_GET_ITEM(file_actions_obj, 0); - int mode = PyLong_AsLong(mode_obj); - - /* Populate the file_actions object */ - - switch(mode) { - - case POSIX_SPAWN_OPEN: - if(PySequence_Size(file_actions_obj) != 5) { - PyErr_SetString(PyExc_TypeError,"A open file_action object must have 5 elements"); - goto exit; - } - - long open_fd = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - const char* open_path = PyUnicode_AsUTF8(PySequence_GetItem(file_actions_obj, 2)); - if(open_path == NULL) { - goto exit; - } - long open_oflag = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 3)); - if(PyErr_Occurred()) { - goto exit; - } - long open_mode = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 4)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_addopen(file_actionsp, open_fd, open_path, open_oflag, open_mode)) { - PyErr_SetString(PyExc_OSError,"Failed to add open file action"); - goto exit; - } - - break; - - case POSIX_SPAWN_CLOSE: - if(PySequence_Size(file_actions_obj) != 2){ - PyErr_SetString(PyExc_TypeError,"A close file_action object must have 2 elements"); - goto exit; - } - - long close_fd = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_addclose(file_actionsp, close_fd)) { - PyErr_SetString(PyExc_OSError,"Failed to add close file action"); - goto exit; - } - break; - - case POSIX_SPAWN_DUP2: - if(PySequence_Size(file_actions_obj) != 3){ - PyErr_SetString(PyExc_TypeError,"A dup2 file_action object must have 3 elements"); - goto exit; - } - - long fd1 = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - long fd2 = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 2)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_adddup2(file_actionsp, fd1, fd2)) { - PyErr_SetString(PyExc_OSError,"Failed to add dup2 file action"); - goto exit; - } - break; - - default: - PyErr_SetString(PyExc_TypeError,"Unknown file_actions identifier"); - goto exit; - } - } + file_actionsp = &file_actions_buf; } _Py_BEGIN_SUPPRESS_IPH - int err_code = posix_spawn(&pid, path->narrow, file_actionsp, NULL, argvlist, envlist); + err_code = posix_spawn(&pid, path->narrow, + file_actionsp, NULL, argvlist, envlist); _Py_END_SUPPRESS_IPH - if(err_code) { - PyErr_SetString(PyExc_OSError,"posix_spawn call failed"); + if (err_code) { + errno = err_code; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); goto exit; } result = PyLong_FromPid(pid); exit: - - Py_XDECREF(seq); - - if(file_actionsp) { - posix_spawn_file_actions_destroy(file_actionsp); + if (file_actionsp) { + (void)posix_spawn_file_actions_destroy(file_actionsp); } - if (envlist) { free_string_array(envlist, envc); } - if (argvlist) { free_string_array(argvlist, argc); } - return result; - - } #endif /* HAVE_POSIX_SPAWN */ From webhook-mailer at python.org Tue May 1 10:18:48 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 01 May 2018 14:18:48 -0000 Subject: [Python-checkins] bpo-20104: Improve error handling and fix a reference leak in os.posix_spawn(). (GH-6332) Message-ID: https://github.com/python/cpython/commit/77fa7835da0cb49d30ac5d4c32bf6eb71eae0742 commit: 77fa7835da0cb49d30ac5d4c32bf6eb71eae0742 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-01T07:18:44-07:00 summary: bpo-20104: Improve error handling and fix a reference leak in os.posix_spawn(). (GH-6332) (cherry picked from commit ef347535f289baad22c0601e12a36b2dcd155c3a) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst M Doc/library/os.rst M Lib/test/test_posix.py M Modules/clinic/posixmodule.c.h M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 2f3b31edd5d7..5699d50a2034 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3367,25 +3367,41 @@ written in Python, such as a mail server's external command delivery program. .. function:: posix_spawn(path, argv, env, file_actions=None) - Wraps the posix_spawn() C library API for use from Python. + Wraps the :c:func:`posix_spawn` C library API for use from Python. - Most users should use :class:`subprocess.run` instead of posix_spawn. + Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`. The *path*, *args*, and *env* arguments are similar to :func:`execve`. The *file_actions* argument may be a sequence of tuples describing actions to take on specific file descriptors in the child process between the C - library implementation's fork and exec steps. The first item in each tuple - must be one of the three type indicator listed below describing the - remaining tuple elements: + library implementation's :c:func:`fork` and :c:func:`exec` steps. + The first item in each tuple must be one of the three type indicator + listed below describing the remaining tuple elements: - (os.POSIX_SPAWN_OPEN, fd, path, open flags, mode) - (os.POSIX_SPAWN_CLOSE, fd) - (os.POSIX_SPAWN_DUP2, fd, new_fd) + .. data:: POSIX_SPAWN_OPEN - These tuples correspond to the C library posix_spawn_file_actions_addopen, - posix_spawn_file_actions_addclose, and posix_spawn_file_actions_adddup2 API - calls used to prepare for the posix_spawn call itself. + (``os.POSIX_SPAWN_OPEN``, *fd*, *path*, *flags*, *mode*) + + Performs ``os.dup2(os.open(path, flags, mode), fd)``. + + .. data:: POSIX_SPAWN_CLOSE + + (``os.POSIX_SPAWN_CLOSE``, *fd*) + + Performs ``os.close(fd)``. + + .. data:: POSIX_SPAWN_DUP2 + + (``os.POSIX_SPAWN_DUP2``, *fd*, *new_fd*) + + Performs ``os.dup2(fd, new_fd)``. + + These tuples correspond to the C library + :c:func:`posix_spawn_file_actions_addopen`, + :c:func:`posix_spawn_file_actions_addclose`, and + :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare + for the :c:func:`posix_spawn` call itself. .. versionadded:: 3.7 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 8ada0e3ab3c7..b94da3f45a2c 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -177,22 +177,6 @@ def test_fexecve(self): os.close(fp) - @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") - def test_posix_spawn(self): - pid = posix.posix_spawn(sys.executable, [sys.executable, "-c", "pass"], os.environ,[]) - self.assertEqual(os.waitpid(pid,0),(pid,0)) - - - @unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") - def test_posix_spawn_file_actions(self): - file_actions = [] - file_actions.append((0,3,os.path.realpath(__file__),0,0)) - file_actions.append((os.POSIX_SPAWN_CLOSE,2)) - file_actions.append((os.POSIX_SPAWN_DUP2,1,4)) - pid = posix.posix_spawn(sys.executable, [sys.executable, "-c", "pass"], os.environ, file_actions) - self.assertEqual(os.waitpid(pid,0),(pid,0)) - - @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()") @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") def test_waitid(self): @@ -1437,9 +1421,168 @@ def test_setgroups(self): posix.setgroups(groups) self.assertListEqual(groups, posix.getgroups()) + + at unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn") +class TestPosixSpawn(unittest.TestCase): + def test_returns_pid(self): + pidfile = support.TESTFN + self.addCleanup(support.unlink, pidfile) + script = f"""if 1: + import os + with open({pidfile!r}, "w") as pidfile: + pidfile.write(str(os.getpid())) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(pidfile) as f: + self.assertEqual(f.read(), str(pid)) + + def test_no_such_executable(self): + no_such_executable = 'no_such_executable' + try: + pid = posix.posix_spawn(no_such_executable, + [no_such_executable], + os.environ) + except FileNotFoundError as exc: + self.assertEqual(exc.filename, no_such_executable) + else: + pid2, status = os.waitpid(pid, 0) + self.assertEqual(pid2, pid) + self.assertNotEqual(status, 0) + + def test_specify_environment(self): + envfile = support.TESTFN + self.addCleanup(support.unlink, envfile) + script = f"""if 1: + import os + with open({envfile!r}, "w") as envfile: + envfile.write(os.environ['foo']) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + {'foo': 'bar'}) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(envfile) as f: + self.assertEqual(f.read(), 'bar') + + def test_empty_file_actions(self): + pid = posix.posix_spawn( + sys.executable, + [sys.executable, '-c', 'pass'], + os.environ, + [] + ) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_multiple_file_actions(self): + file_actions = [ + (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0), + (os.POSIX_SPAWN_CLOSE, 0), + (os.POSIX_SPAWN_DUP2, 1, 4), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + + def test_bad_file_actions(self): + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [None]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [()]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(None,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(12345,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE,)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, 1, 2)]) + with self.assertRaises(TypeError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, [(os.POSIX_SPAWN_CLOSE, None)]) + with self.assertRaises(ValueError): + posix.posix_spawn(sys.executable, + [sys.executable, "-c", "pass"], + os.environ, + [(os.POSIX_SPAWN_OPEN, 3, __file__ + '\0', + os.O_RDONLY, 0)]) + + def test_open_file(self): + outfile = support.TESTFN + self.addCleanup(support.unlink, outfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + file_actions = [ + (os.POSIX_SPAWN_OPEN, 1, outfile, + os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + stat.S_IRUSR | stat.S_IWUSR), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(outfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_close_file(self): + closefile = support.TESTFN + self.addCleanup(support.unlink, closefile) + script = f"""if 1: + import os + try: + os.fstat(0) + except OSError as e: + with open({closefile!r}, 'w') as closefile: + closefile.write('is closed %d' % e.errno) + """ + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, + [(os.POSIX_SPAWN_CLOSE, 0),]) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(closefile) as f: + self.assertEqual(f.read(), 'is closed %d' % errno.EBADF) + + def test_dup2(self): + dupfile = support.TESTFN + self.addCleanup(support.unlink, dupfile) + script = """if 1: + import sys + sys.stdout.write("hello") + """ + with open(dupfile, "wb") as childfile: + file_actions = [ + (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1), + ] + pid = posix.posix_spawn(sys.executable, + [sys.executable, '-c', script], + os.environ, file_actions) + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + with open(dupfile) as f: + self.assertEqual(f.read(), 'hello') + + def test_main(): try: - support.run_unittest(PosixTester, PosixGroupsTester) + support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn) finally: support.reap_children() diff --git a/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst new file mode 100644 index 000000000000..150401dc7412 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst @@ -0,0 +1 @@ +Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 4054389d15f3..e4bbd082450b 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1742,7 +1742,7 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " env\n" " Dictionary of strings mapping to strings.\n" " file_actions\n" -" FileActions object."); +" A sequence of file action tuples."); #define OS_POSIX_SPAWN_METHODDEF \ {"posix_spawn", (PyCFunction)os_posix_spawn, METH_FASTCALL, os_posix_spawn__doc__}, @@ -6589,4 +6589,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=fc603214822bdda6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8d3d9dddf254c3c2 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index e8964ce33901..a81580db0a3b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5114,6 +5114,111 @@ enum posix_spawn_file_actions_identifier { POSIX_SPAWN_DUP2 }; +static int +parse_file_actions(PyObject *file_actions, + posix_spawn_file_actions_t *file_actionsp) +{ + PyObject *seq; + PyObject *file_action = NULL; + PyObject *tag_obj; + + seq = PySequence_Fast(file_actions, + "file_actions must be a sequence or None"); + if (seq == NULL) { + return -1; + } + + errno = posix_spawn_file_actions_init(file_actionsp); + if (errno) { + posix_error(); + Py_DECREF(seq); + return -1; + } + + for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { + file_action = PySequence_Fast_GET_ITEM(seq, i); + Py_INCREF(file_action); + if (!PyTuple_Check(file_action) || !PyTuple_GET_SIZE(file_action)) { + PyErr_SetString(PyExc_TypeError, + "Each file_actions element must be a non-empty tuple"); + goto fail; + } + long tag = PyLong_AsLong(PyTuple_GET_ITEM(file_action, 0)); + if (tag == -1 && PyErr_Occurred()) { + goto fail; + } + + /* Populate the file_actions object */ + switch (tag) { + case POSIX_SPAWN_OPEN: { + int fd, oflag; + PyObject *path; + unsigned long mode; + if (!PyArg_ParseTuple(file_action, "OiO&ik" + ";A open file_action tuple must have 5 elements", + &tag_obj, &fd, PyUnicode_FSConverter, &path, + &oflag, &mode)) + { + goto fail; + } + errno = posix_spawn_file_actions_addopen(file_actionsp, + fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); + Py_DECREF(path); /* addopen copied it. */ + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_CLOSE: { + int fd; + if (!PyArg_ParseTuple(file_action, "Oi" + ";A close file_action tuple must have 2 elements", + &tag_obj, &fd)) + { + goto fail; + } + errno = posix_spawn_file_actions_addclose(file_actionsp, fd); + if (errno) { + posix_error(); + goto fail; + } + break; + } + case POSIX_SPAWN_DUP2: { + int fd1, fd2; + if (!PyArg_ParseTuple(file_action, "Oii" + ";A dup2 file_action tuple must have 3 elements", + &tag_obj, &fd1, &fd2)) + { + goto fail; + } + errno = posix_spawn_file_actions_adddup2(file_actionsp, + fd1, fd2); + if (errno) { + posix_error(); + goto fail; + } + break; + } + default: { + PyErr_SetString(PyExc_TypeError, + "Unknown file_actions identifier"); + goto fail; + } + } + Py_DECREF(file_action); + } + Py_DECREF(seq); + return 0; + +fail: + Py_DECREF(seq); + Py_DECREF(file_action); + (void)posix_spawn_file_actions_destroy(file_actionsp); + return -1; +} + /*[clinic input] os.posix_spawn @@ -5124,7 +5229,7 @@ os.posix_spawn env: object Dictionary of strings mapping to strings. file_actions: object = None - FileActions object. + A sequence of file action tuples. / Execute the program specified by path in a new process. @@ -5133,22 +5238,22 @@ Execute the program specified by path in a new process. static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env, PyObject *file_actions) -/*[clinic end generated code: output=d023521f541c709c input=0ec9f1cfdc890be5]*/ +/*[clinic end generated code: output=d023521f541c709c input=a3db1021d33230dc]*/ { EXECV_CHAR **argvlist = NULL; EXECV_CHAR **envlist = NULL; - posix_spawn_file_actions_t _file_actions; + posix_spawn_file_actions_t file_actions_buf; posix_spawn_file_actions_t *file_actionsp = NULL; Py_ssize_t argc, envc; - PyObject* result = NULL; - PyObject* seq = NULL; - + PyObject *result = NULL; + pid_t pid; + int err_code; /* posix_spawn has three arguments: (path, argv, env), where - argv is a list or tuple of strings and env is a dictionary + argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PySequence_Check(argv)) { + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "posix_spawn: argv must be a tuple or list"); goto exit; @@ -5180,139 +5285,35 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, goto exit; } - pid_t pid; - if (file_actions != NULL && file_actions != Py_None) { - if(posix_spawn_file_actions_init(&_file_actions) != 0){ - PyErr_SetString(PyExc_OSError, - "Error initializing file actions"); - goto exit; - } - - file_actionsp = &_file_actions; - - seq = PySequence_Fast(file_actions, "file_actions must be a sequence"); - if(seq == NULL) { + if (file_actions != Py_None) { + if (parse_file_actions(file_actions, &file_actions_buf)) { goto exit; } - PyObject* file_actions_obj; - PyObject* mode_obj; - - for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { - file_actions_obj = PySequence_Fast_GET_ITEM(seq, i); - - if(!PySequence_Check(file_actions_obj) | !PySequence_Size(file_actions_obj)) { - PyErr_SetString(PyExc_TypeError,"Each file_action element must be a non empty sequence"); - goto exit; - } - - - mode_obj = PySequence_Fast_GET_ITEM(file_actions_obj, 0); - int mode = PyLong_AsLong(mode_obj); - - /* Populate the file_actions object */ - - switch(mode) { - - case POSIX_SPAWN_OPEN: - if(PySequence_Size(file_actions_obj) != 5) { - PyErr_SetString(PyExc_TypeError,"A open file_action object must have 5 elements"); - goto exit; - } - - long open_fd = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - const char* open_path = PyUnicode_AsUTF8(PySequence_GetItem(file_actions_obj, 2)); - if(open_path == NULL) { - goto exit; - } - long open_oflag = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 3)); - if(PyErr_Occurred()) { - goto exit; - } - long open_mode = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 4)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_addopen(file_actionsp, open_fd, open_path, open_oflag, open_mode)) { - PyErr_SetString(PyExc_OSError,"Failed to add open file action"); - goto exit; - } - - break; - - case POSIX_SPAWN_CLOSE: - if(PySequence_Size(file_actions_obj) != 2){ - PyErr_SetString(PyExc_TypeError,"A close file_action object must have 2 elements"); - goto exit; - } - - long close_fd = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_addclose(file_actionsp, close_fd)) { - PyErr_SetString(PyExc_OSError,"Failed to add close file action"); - goto exit; - } - break; - - case POSIX_SPAWN_DUP2: - if(PySequence_Size(file_actions_obj) != 3){ - PyErr_SetString(PyExc_TypeError,"A dup2 file_action object must have 3 elements"); - goto exit; - } - - long fd1 = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 1)); - if(PyErr_Occurred()) { - goto exit; - } - long fd2 = PyLong_AsLong(PySequence_GetItem(file_actions_obj, 2)); - if(PyErr_Occurred()) { - goto exit; - } - if(posix_spawn_file_actions_adddup2(file_actionsp, fd1, fd2)) { - PyErr_SetString(PyExc_OSError,"Failed to add dup2 file action"); - goto exit; - } - break; - - default: - PyErr_SetString(PyExc_TypeError,"Unknown file_actions identifier"); - goto exit; - } - } + file_actionsp = &file_actions_buf; } _Py_BEGIN_SUPPRESS_IPH - int err_code = posix_spawn(&pid, path->narrow, file_actionsp, NULL, argvlist, envlist); + err_code = posix_spawn(&pid, path->narrow, + file_actionsp, NULL, argvlist, envlist); _Py_END_SUPPRESS_IPH - if(err_code) { - PyErr_SetString(PyExc_OSError,"posix_spawn call failed"); + if (err_code) { + errno = err_code; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); goto exit; } result = PyLong_FromPid(pid); exit: - - Py_XDECREF(seq); - - if(file_actionsp) { - posix_spawn_file_actions_destroy(file_actionsp); + if (file_actionsp) { + (void)posix_spawn_file_actions_destroy(file_actionsp); } - if (envlist) { free_string_array(envlist, envc); } - if (argvlist) { free_string_array(argvlist, argc); } - return result; - - } #endif /* HAVE_POSIX_SPAWN */ From webhook-mailer at python.org Tue May 1 10:40:21 2018 From: webhook-mailer at python.org (Ned Deily) Date: Tue, 01 May 2018 14:40:21 -0000 Subject: [Python-checkins] bpo-33377: add triplets for mips-r6 and riscv (GH-6655) (GH-6660) Message-ID: https://github.com/python/cpython/commit/0596f319020ad34010cbf98608021080ba2a1d4b commit: 0596f319020ad34010cbf98608021080ba2a1d4b branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-01T10:40:17-04:00 summary: bpo-33377: add triplets for mips-r6 and riscv (GH-6655) (GH-6660) (cherry picked from commit ddbe976964933cb943c6383a776e800cc7e0f47d) Co-authored-by: Matthias Klose files: A Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst b/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst new file mode 100644 index 000000000000..f5dbd23c7c35 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst @@ -0,0 +1,2 @@ +Add new triplets for mips r6 and riscv variants (used in extension +suffixes). diff --git a/configure b/configure index f75acf68ce2c..2ab9bc8eff2a 100755 --- a/configure +++ b/configure @@ -781,6 +781,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -893,6 +894,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1145,6 +1147,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1282,7 +1293,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1435,6 +1446,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -5238,6 +5250,26 @@ cat >> conftest.c <=6) && defined(_MIPSEL) +# if _MIPS_SIM == _ABIO32 + mipsisa32r6el-linux-gnu +# elif _MIPS_SIM == _ABIN32 + mipsisa64r6el-linux-gnuabin32 +# elif _MIPS_SIM == _ABI64 + mipsisa64r6el-linux-gnuabi64 +# else +# error unknown platform triplet +# endif +# elif defined(__mips_hard_float) && defined(__mips_isa_rev) && (__mips_isa_rev >=6) +# if _MIPS_SIM == _ABIO32 + mipsisa32r6-linux-gnu +# elif _MIPS_SIM == _ABIN32 + mipsisa64r6-linux-gnuabin32 +# elif _MIPS_SIM == _ABI64 + mipsisa64r6-linux-gnuabi64 +# else +# error unknown platform triplet +# endif # elif defined(__mips_hard_float) && defined(_MIPSEL) # if _MIPS_SIM == _ABIO32 mipsel-linux-gnu @@ -5280,6 +5312,14 @@ cat >> conftest.c <> conftest.c <=6) && defined(_MIPSEL) +# if _MIPS_SIM == _ABIO32 + mipsisa32r6el-linux-gnu +# elif _MIPS_SIM == _ABIN32 + mipsisa64r6el-linux-gnuabin32 +# elif _MIPS_SIM == _ABI64 + mipsisa64r6el-linux-gnuabi64 +# else +# error unknown platform triplet +# endif +# elif defined(__mips_hard_float) && defined(__mips_isa_rev) && (__mips_isa_rev >=6) +# if _MIPS_SIM == _ABIO32 + mipsisa32r6-linux-gnu +# elif _MIPS_SIM == _ABIN32 + mipsisa64r6-linux-gnuabin32 +# elif _MIPS_SIM == _ABI64 + mipsisa64r6-linux-gnuabi64 +# else +# error unknown platform triplet +# endif # elif defined(__mips_hard_float) && defined(_MIPSEL) # if _MIPS_SIM == _ABIO32 mipsel-linux-gnu @@ -823,6 +843,14 @@ cat >> conftest.c < https://github.com/python/cpython/commit/d06d345f04b3f7e5b318df69b1d179328a64ca9c commit: d06d345f04b3f7e5b318df69b1d179328a64ca9c branch: master author: Ray Donnelly committer: Ned Deily date: 2018-05-01T22:31:36-04:00 summary: bpo-33281: Fix ctypes.util.find_library regression on macOS (GH-6625) files: M Lib/ctypes/util.py diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 5e8b31a8546a..97973bce001d 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -67,7 +67,7 @@ def find_library(name): return fname return None -if os.name == "posix" and sys.platform == "darwin": +elif os.name == "posix" and sys.platform == "darwin": from ctypes.macholib.dyld import dyld_find as _dyld_find def find_library(name): possible = ['lib%s.dylib' % name, @@ -80,7 +80,7 @@ def find_library(name): continue return None -if sys.platform.startswith("aix"): +elif sys.platform.startswith("aix"): # AIX has two styles of storing shared libraries # GNU auto_tools refer to these as svr4 and aix # svr4 (System V Release 4) is a regular file, often with .so as suffix From webhook-mailer at python.org Tue May 1 22:41:46 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 02:41:46 -0000 Subject: [Python-checkins] bpo-33281: NEWS and ACK (GH-6681) Message-ID: https://github.com/python/cpython/commit/69a013ec189f93a0dea97cfdbb3adc348648a666 commit: 69a013ec189f93a0dea97cfdbb3adc348648a666 branch: master author: Ned Deily committer: GitHub date: 2018-05-01T22:41:43-04:00 summary: bpo-33281: NEWS and ACK (GH-6681) files: A Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst M Misc/ACKS diff --git a/Misc/ACKS b/Misc/ACKS index 3b6774219f6c..587bbecbc36a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -393,6 +393,7 @@ Jaromir Dolecek Zsolt Dollenstein Brendan Donegan Ismail Donmez +Ray Donnelly Robert Donohue Marcos Donolo Dima Dorfman diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst new file mode 100644 index 000000000000..ad08caa70b63 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst @@ -0,0 +1 @@ +Fix ctypes.util.find_library regression on macOS. From webhook-mailer at python.org Tue May 1 22:51:34 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 02:51:34 -0000 Subject: [Python-checkins] bpo-33281: Fix ctypes.util.find_library regression on macOS (GH-6625) (GH-6680) Message-ID: https://github.com/python/cpython/commit/c74ca5396aa7740d4fc90617e6b2315e849fa71f commit: c74ca5396aa7740d4fc90617e6b2315e849fa71f branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-01T22:51:31-04:00 summary: bpo-33281: Fix ctypes.util.find_library regression on macOS (GH-6625) (GH-6680) (cherry picked from commit d06d345f04b3f7e5b318df69b1d179328a64ca9c) Co-authored-by: Ray Donnelly files: M Lib/ctypes/util.py diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 5e8b31a8546a..97973bce001d 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -67,7 +67,7 @@ def find_library(name): return fname return None -if os.name == "posix" and sys.platform == "darwin": +elif os.name == "posix" and sys.platform == "darwin": from ctypes.macholib.dyld import dyld_find as _dyld_find def find_library(name): possible = ['lib%s.dylib' % name, @@ -80,7 +80,7 @@ def find_library(name): continue return None -if sys.platform.startswith("aix"): +elif sys.platform.startswith("aix"): # AIX has two styles of storing shared libraries # GNU auto_tools refer to these as svr4 and aix # svr4 (System V Release 4) is a regular file, often with .so as suffix From webhook-mailer at python.org Tue May 1 22:52:45 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 02:52:45 -0000 Subject: [Python-checkins] bpo-33281: NEWS and ACK (GH-6681) (GH-6682) Message-ID: https://github.com/python/cpython/commit/d74f35331f176e0679f0614b6cccf0dc0422e31a commit: d74f35331f176e0679f0614b6cccf0dc0422e31a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-01T22:52:42-04:00 summary: bpo-33281: NEWS and ACK (GH-6681) (GH-6682) (cherry picked from commit 69a013ec189f93a0dea97cfdbb3adc348648a666) Co-authored-by: Ned Deily files: A Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst M Misc/ACKS diff --git a/Misc/ACKS b/Misc/ACKS index 64262c490c66..0bb3f35d4915 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -392,6 +392,7 @@ Jaromir Dolecek Zsolt Dollenstein Brendan Donegan Ismail Donmez +Ray Donnelly Robert Donohue Marcos Donolo Dima Dorfman diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst new file mode 100644 index 000000000000..ad08caa70b63 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst @@ -0,0 +1 @@ +Fix ctypes.util.find_library regression on macOS. From webhook-mailer at python.org Wed May 2 01:30:39 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:30:39 -0000 Subject: [Python-checkins] bpo-33290: Have macOS installer remove "pip" alias (GH-6683) Message-ID: https://github.com/python/cpython/commit/0dd80709b5dc03756e7f4510761ae60236bb9f6d commit: 0dd80709b5dc03756e7f4510761ae60236bb9f6d branch: master author: Ned Deily committer: GitHub date: 2018-05-02T01:30:33-04:00 summary: bpo-33290: Have macOS installer remove "pip" alias (GH-6683) Currently, "pip3 install --upgrade pip" unconditionally installs a "pip" alias even for Python 3. If a user has an existing Python 3.x installed from a python.org macOS installer and then subsequently manually updates to a new version of pip, there may now be a stray "pip" alias in the Python 3.x framework bin directory which can cause confusion if the user has both a Python 2.7 and 3.x installed; if the Python 3.x fw bin directory appears early on $PATH, "pip" might invoke the pip3 for the Python 3.x rather than the pip for Python 2.7. To try to mitigate this, the macOS installer script for the ensurepip option will unconditionally remove "pip" from the 3.x framework bin directory being updated / installed. (The ambiguity can be avoided by using "pythonx.y -m pip".) files: M Mac/BuildScript/scripts/postflight.ensurepip diff --git a/Mac/BuildScript/scripts/postflight.ensurepip b/Mac/BuildScript/scripts/postflight.ensurepip index 3074fa36fc0b..36d05945b6fd 100755 --- a/Mac/BuildScript/scripts/postflight.ensurepip +++ b/Mac/BuildScript/scripts/postflight.ensurepip @@ -12,6 +12,11 @@ umask 022 "${FWK}/bin/python${PYVER}" -E -s -m ensurepip --upgrade +# bpo-33290: An earlier "pip3 install --upgrade pip" may have installed +# a "pip" in the fw bin directory. For a py3 install, remove it. + +rm -f "${FWK}/bin/pip" + "${FWK}/bin/python${PYVER}" -E -s -Wi \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ -f -x badsyntax \ From webhook-mailer at python.org Wed May 2 01:41:18 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:41:18 -0000 Subject: [Python-checkins] Mitigate macOS race condition in installer build (GH-6686) Message-ID: https://github.com/python/cpython/commit/fc6aa28bfd0502d994cec30bd3679b7def3be2af commit: fc6aa28bfd0502d994cec30bd3679b7def3be2af branch: master author: Ned Deily committer: GitHub date: 2018-05-02T01:41:15-04:00 summary: Mitigate macOS race condition in installer build (GH-6686) files: M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 68868d97a65c..d2b04d163ab4 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1524,6 +1524,10 @@ def buildDMG(): shellQuote(os.path.join(WORKDIR, 'installer')), shellQuote(imagepath + ".tmp.dmg" ))) + # Try to mitigate race condition in certain versions of macOS, e.g. 10.9, + # when hdiutil fails with "Resource busy" + + time.sleep(10) if not os.path.exists(os.path.join(WORKDIR, "mnt")): os.mkdir(os.path.join(WORKDIR, "mnt")) From webhook-mailer at python.org Wed May 2 01:44:02 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:44:02 -0000 Subject: [Python-checkins] bpo-33290: Have macOS installer remove "pip" alias (GH-6683) (GH-6684) Message-ID: https://github.com/python/cpython/commit/1470e43076559d22518f2e8d704fa9426d2659dd commit: 1470e43076559d22518f2e8d704fa9426d2659dd branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-02T01:43:59-04:00 summary: bpo-33290: Have macOS installer remove "pip" alias (GH-6683) (GH-6684) Currently, "pip3 install --upgrade pip" unconditionally installs a "pip" alias even for Python 3. If a user has an existing Python 3.x installed from a python.org macOS installer and then subsequently manually updates to a new version of pip, there may now be a stray "pip" alias in the Python 3.x framework bin directory which can cause confusion if the user has both a Python 2.7 and 3.x installed; if the Python 3.x fw bin directory appears early on $PATH, "pip" might invoke the pip3 for the Python 3.x rather than the pip for Python 2.7. To try to mitigate this, the macOS installer script for the ensurepip option will unconditionally remove "pip" from the 3.x framework bin directory being updated / installed. (The ambiguity can be avoided by using "pythonx.y -m pip".) (cherry picked from commit 0dd80709b5dc03756e7f4510761ae60236bb9f6d) Co-authored-by: Ned Deily files: M Mac/BuildScript/scripts/postflight.ensurepip diff --git a/Mac/BuildScript/scripts/postflight.ensurepip b/Mac/BuildScript/scripts/postflight.ensurepip index 3074fa36fc0b..36d05945b6fd 100755 --- a/Mac/BuildScript/scripts/postflight.ensurepip +++ b/Mac/BuildScript/scripts/postflight.ensurepip @@ -12,6 +12,11 @@ umask 022 "${FWK}/bin/python${PYVER}" -E -s -m ensurepip --upgrade +# bpo-33290: An earlier "pip3 install --upgrade pip" may have installed +# a "pip" in the fw bin directory. For a py3 install, remove it. + +rm -f "${FWK}/bin/pip" + "${FWK}/bin/python${PYVER}" -E -s -Wi \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ -f -x badsyntax \ From webhook-mailer at python.org Wed May 2 01:46:02 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:46:02 -0000 Subject: [Python-checkins] Mitigate macOS race condition in installer build (GH-6686) (GH-6687) Message-ID: https://github.com/python/cpython/commit/50903bf011d8d3841c1874628f9ac20515256872 commit: 50903bf011d8d3841c1874628f9ac20515256872 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-02T01:45:59-04:00 summary: Mitigate macOS race condition in installer build (GH-6686) (GH-6687) (cherry picked from commit fc6aa28bfd0502d994cec30bd3679b7def3be2af) Co-authored-by: Ned Deily files: M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 68868d97a65c..d2b04d163ab4 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1524,6 +1524,10 @@ def buildDMG(): shellQuote(os.path.join(WORKDIR, 'installer')), shellQuote(imagepath + ".tmp.dmg" ))) + # Try to mitigate race condition in certain versions of macOS, e.g. 10.9, + # when hdiutil fails with "Resource busy" + + time.sleep(10) if not os.path.exists(os.path.join(WORKDIR, "mnt")): os.mkdir(os.path.join(WORKDIR, "mnt")) From webhook-mailer at python.org Wed May 2 01:48:13 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:48:13 -0000 Subject: [Python-checkins] bpo-33290: Have macOS installer remove "pip" alias (GH-6683) (GH-6685) Message-ID: https://github.com/python/cpython/commit/8ac441876418a217c31fe429733d7fa4704f0e3c commit: 8ac441876418a217c31fe429733d7fa4704f0e3c branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-02T01:48:11-04:00 summary: bpo-33290: Have macOS installer remove "pip" alias (GH-6683) (GH-6685) Currently, "pip3 install --upgrade pip" unconditionally installs a "pip" alias even for Python 3. If a user has an existing Python 3.x installed from a python.org macOS installer and then subsequently manually updates to a new version of pip, there may now be a stray "pip" alias in the Python 3.x framework bin directory which can cause confusion if the user has both a Python 2.7 and 3.x installed; if the Python 3.x fw bin directory appears early on $PATH, "pip" might invoke the pip3 for the Python 3.x rather than the pip for Python 2.7. To try to mitigate this, the macOS installer script for the ensurepip option will unconditionally remove "pip" from the 3.x framework bin directory being updated / installed. (The ambiguity can be avoided by using "pythonx.y -m pip".) (cherry picked from commit 0dd80709b5dc03756e7f4510761ae60236bb9f6d) Co-authored-by: Ned Deily files: M Mac/BuildScript/scripts/postflight.ensurepip diff --git a/Mac/BuildScript/scripts/postflight.ensurepip b/Mac/BuildScript/scripts/postflight.ensurepip index 3074fa36fc0b..36d05945b6fd 100755 --- a/Mac/BuildScript/scripts/postflight.ensurepip +++ b/Mac/BuildScript/scripts/postflight.ensurepip @@ -12,6 +12,11 @@ umask 022 "${FWK}/bin/python${PYVER}" -E -s -m ensurepip --upgrade +# bpo-33290: An earlier "pip3 install --upgrade pip" may have installed +# a "pip" in the fw bin directory. For a py3 install, remove it. + +rm -f "${FWK}/bin/pip" + "${FWK}/bin/python${PYVER}" -E -s -Wi \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ -f -x badsyntax \ From webhook-mailer at python.org Wed May 2 01:49:06 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:49:06 -0000 Subject: [Python-checkins] Mitigate macOS race condition in installer build (GH-6686) (GH-6688) Message-ID: https://github.com/python/cpython/commit/fb646219e9ec673d267d264b34c25fe96dc12844 commit: fb646219e9ec673d267d264b34c25fe96dc12844 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-02T01:49:03-04:00 summary: Mitigate macOS race condition in installer build (GH-6686) (GH-6688) (cherry picked from commit fc6aa28bfd0502d994cec30bd3679b7def3be2af) Co-authored-by: Ned Deily files: M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index ef81bc147e21..d76b2c096764 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1523,6 +1523,10 @@ def buildDMG(): shellQuote(os.path.join(WORKDIR, 'installer')), shellQuote(imagepath + ".tmp.dmg" ))) + # Try to mitigate race condition in certain versions of macOS, e.g. 10.9, + # when hdiutil fails with "Resource busy" + + time.sleep(10) if not os.path.exists(os.path.join(WORKDIR, "mnt")): os.mkdir(os.path.join(WORKDIR, "mnt")) From webhook-mailer at python.org Wed May 2 01:50:15 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 05:50:15 -0000 Subject: [Python-checkins] Mitigate macOS race condition in installer build (GH-6686) (#6689) Message-ID: https://github.com/python/cpython/commit/5818f0896257c51654ce3efce9abad63e12db037 commit: 5818f0896257c51654ce3efce9abad63e12db037 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2018-05-02T01:50:12-04:00 summary: Mitigate macOS race condition in installer build (GH-6686) (#6689) (cherry picked from commit fc6aa28bfd0502d994cec30bd3679b7def3be2af) Co-authored-by: Ned Deily files: M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 7875bc8ef419..038e1917c4e1 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1530,6 +1530,10 @@ def buildDMG(): shellQuote(os.path.join(WORKDIR, 'installer')), shellQuote(imagepath + ".tmp.dmg" ))) + # Try to mitigate race condition in certain versions of macOS, e.g. 10.9, + # when hdiutil fails with "Resource busy" + + time.sleep(10) if not os.path.exists(os.path.join(WORKDIR, "mnt")): os.mkdir(os.path.join(WORKDIR, "mnt")) From webhook-mailer at python.org Wed May 2 02:54:54 2018 From: webhook-mailer at python.org (Matthias Klose) Date: Wed, 02 May 2018 06:54:54 -0000 Subject: [Python-checkins] bpo-33393: Update config.guess and config.sub files (GH-6658) (#6661) Message-ID: https://github.com/python/cpython/commit/9da7ee40037fa30d0d28fd8d7c652cde14e5a834 commit: 9da7ee40037fa30d0d28fd8d7c652cde14e5a834 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Matthias Klose date: 2018-05-02T08:54:51+02:00 summary: bpo-33393: Update config.guess and config.sub files (GH-6658) (#6661) (cherry picked from commit 7e3545c70cdecd86ffa8fcbffd79b4f78560679f) Co-authored-by: Matthias Klose files: A Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst M config.guess M config.sub diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst new file mode 100644 index 000000000000..f3317e7e68f3 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst @@ -0,0 +1 @@ +Update config.guess and config.sub files. diff --git a/config.guess b/config.guess index 2193702b12af..256083a70d35 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-05-27' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-05-27' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2017-05-27' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +149,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,30 +176,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -208,10 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -219,46 +226,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -310,28 +326,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -343,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -370,19 +377,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -395,13 +402,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -410,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -439,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -485,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -527,17 +534,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -554,7 +561,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -566,14 +573,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -584,7 +591,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -598,7 +605,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -607,18 +614,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -633,28 +640,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -687,13 +694,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -712,15 +719,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -745,11 +752,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -758,7 +765,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -766,9 +773,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -793,128 +800,109 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -928,63 +916,63 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -998,70 +986,70 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1075,34 +1063,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1112,12 +1100,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1127,9 +1115,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1149,9 +1137,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1171,9 +1159,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1182,28 +1170,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1214,7 +1202,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1234,23 +1222,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green at stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green at stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1269,39 +1257,39 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ @@ -1329,7 +1317,7 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1337,22 +1325,25 @@ EOF UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk${UNAME_RELEASE} + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1361,7 +1352,7 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 @@ -1372,7 +1363,7 @@ EOF else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1393,14 +1384,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1409,32 +1400,44 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.sub b/config.sub index 40ea5dfe1152..ba37cf99e26b 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-04-02' +timestamp='2018-04-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-04-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2017-04-02' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -94,7 +94,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -112,7 +112,7 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ @@ -120,16 +120,16 @@ case $maybe_os in kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -178,44 +178,44 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -227,10 +227,7 @@ case $os in os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -252,12 +249,12 @@ case $basic_machine in | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ - | c4x | c8051 | clipper \ + | c4x | c8051 | clipper | csky \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ @@ -299,7 +296,7 @@ case $basic_machine in | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ @@ -316,7 +313,6 @@ case $basic_machine in | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ - | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -337,7 +333,11 @@ case $basic_machine in basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + m9s12z | m68hcs12z | hcs12z | s12z) + basic_machine=s12z-unknown + os=-none ;; ms1) basic_machine=mt-unknown @@ -366,7 +366,7 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -382,7 +382,7 @@ case $basic_machine in | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ @@ -461,7 +461,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -495,7 +495,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -540,7 +540,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -548,13 +548,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -643,7 +643,7 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; @@ -652,7 +652,7 @@ case $basic_machine in os=$os"spe" ;; e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) @@ -744,9 +744,6 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -759,26 +756,26 @@ case $basic_machine in basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -797,19 +794,16 @@ case $basic_machine in os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -841,10 +835,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -863,7 +857,7 @@ case $basic_machine in os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -905,7 +899,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -950,6 +944,9 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; nsx-tandem) basic_machine=nsx-tandem ;; @@ -985,7 +982,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -1001,7 +998,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1016,16 +1013,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1035,23 +1032,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1105,17 +1102,10 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1134,7 +1124,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1248,9 +1238,6 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; - wasm32) - basic_machine=wasm32-unknown - ;; w65*) basic_machine=w65-wdc os=-none @@ -1259,6 +1246,9 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1267,20 +1257,12 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1309,10 +1291,6 @@ case $basic_machine in vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1322,9 +1300,6 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1344,7 +1319,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1352,10 +1327,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1366,8 +1341,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases that might get confused + # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux @@ -1378,18 +1353,19 @@ case $os in -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ @@ -1399,25 +1375,26 @@ case $os in | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1434,12 +1411,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1448,10 +1425,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1462,12 +1439,6 @@ case $os in -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1492,7 +1463,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1514,7 +1485,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1529,24 +1500,28 @@ case $os in -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; -ios) @@ -1556,7 +1531,7 @@ case $os in *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1652,9 +1627,6 @@ case $basic_machine in *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1694,7 +1666,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1709,9 +1681,6 @@ case $basic_machine in i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1821,15 +1790,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" From webhook-mailer at python.org Wed May 2 02:57:27 2018 From: webhook-mailer at python.org (Matthias Klose) Date: Wed, 02 May 2018 06:57:27 -0000 Subject: [Python-checkins] Enable the verbose build for extension modules with GNU make (GH-6659) (#6662) Message-ID: https://github.com/python/cpython/commit/3c5d3f519d092ea845fa6673df1222fdd668430b commit: 3c5d3f519d092ea845fa6673df1222fdd668430b branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Matthias Klose date: 2018-05-02T08:57:24+02:00 summary: Enable the verbose build for extension modules with GNU make (GH-6659) (#6662) (cherry picked from commit 10f715d71218ece737f990fa55027b8e1120cc3a) Co-authored-by: Matthias Klose files: A Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index 3a7324f50963..4c23c0e4114a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -601,11 +601,15 @@ $(srcdir)/Modules/_blake2/blake2s_impl.c: $(srcdir)/Modules/_blake2/blake2b_impl # Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for # -s, --silent or --quiet is always the first char. # Under BSD make, MAKEFLAGS might be " -s -v x=y". +# Ignore macros passed by GNU make, passed after -- sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o - @case "$$MAKEFLAGS" in \ + @case "`echo X $$MAKEFLAGS | sed 's/^X //;s/ -- .*//'`" in \ *\ -s*|s*) quiet="-q";; \ *) quiet="";; \ esac; \ + echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ + $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst new file mode 100644 index 000000000000..b25fbb02c406 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst @@ -0,0 +1,2 @@ +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. From webhook-mailer at python.org Wed May 2 04:54:56 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 08:54:56 -0000 Subject: [Python-checkins] 3.7.0b4 Message-ID: https://github.com/python/cpython/commit/eb96c376994cb7c6c2e8a4967782d1c0e2a96135 commit: eb96c376994cb7c6c2e8a4967782d1c0e2a96135 branch: 3.7 author: Ned Deily committer: Ned Deily date: 2018-05-02T03:41:45-04:00 summary: 3.7.0b4 files: A Misc/NEWS.d/3.7.0b4.rst D Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst D Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst D Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst D Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst D Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst D Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst D Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst D Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst D Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst D Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst D Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst D Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst D Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst D Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst D Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst D Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst D Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst D Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst D Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst D Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst D Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst D Misc/NEWS.d/next/Library/2018-04-05-13-36-09.bpo-33217.FfOKDI.rst D Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst D Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst D Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst D Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst D Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst D Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst D Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst D Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst D Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst D Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst D Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst D Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst D Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst D Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst D Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst D Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst D Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst D Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst D Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst M configure diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 70d86c9f8529..c01b8f98fe51 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 7 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 3 +#define PY_RELEASE_SERIAL 4 /* Version as a string */ -#define PY_VERSION "3.7.0b3+" +#define PY_VERSION "3.7.0b4" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index abface57b092..e138d49821aa 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Mar 29 07:53:04 2018 +# Autogenerated by Sphinx on Wed May 2 03:29:32 2018 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -106,7 +106,7 @@ ' corresponding targets.\n' '\n' ' * If the target list contains one target prefixed with an\n' - ' asterisk, called a "starred" target: The object must be ' + ' asterisk, called a ?starred? target: The object must be ' 'an\n' ' iterable with at least as many items as there are targets ' 'in the\n' @@ -203,10 +203,10 @@ ' If the primary is a mutable sequence object (such as a ' 'list), the\n' ' subscript must yield an integer. If it is negative, the ' - "sequence's\n" + 'sequence?s\n' ' length is added to it. The resulting value must be a ' 'nonnegative\n' - " integer less than the sequence's length, and the sequence is " + ' integer less than the sequence?s length, and the sequence is ' 'asked\n' ' to assign the assigned object to its item with that index. ' 'If the\n' @@ -216,7 +216,7 @@ '\n' ' If the primary is a mapping object (such as a dictionary), ' 'the\n' - " subscript must have a type compatible with the mapping's key " + ' subscript must have a type compatible with the mapping?s key ' 'type,\n' ' and the mapping is then asked to create a key/datum pair ' 'which maps\n' @@ -239,12 +239,12 @@ 'expressions are\n' ' evaluated, insofar they are present; defaults are zero and ' 'the\n' - " sequence's length. The bounds should evaluate to integers. " + ' sequence?s length. The bounds should evaluate to integers. ' 'If\n' - " either bound is negative, the sequence's length is added to " + ' either bound is negative, the sequence?s length is added to ' 'it. The\n' ' resulting bounds are clipped to lie between zero and the ' - "sequence's\n" + 'sequence?s\n' ' length, inclusive. Finally, the sequence object is asked to ' 'replace\n' ' the slice with the items of the assigned sequence. The ' @@ -265,7 +265,7 @@ '\n' 'Although the definition of assignment implies that overlaps ' 'between\n' - "the left-hand side and the right-hand side are 'simultaneous' " + 'the left-hand side and the right-hand side are ?simultaneous? ' '(for\n' 'example "a, b = b, a" swaps two variables), overlaps *within* ' 'the\n' @@ -464,7 +464,7 @@ '\n' 'All literals correspond to immutable data types, and hence ' 'the\n' - "object's identity is less important than its value. " + 'object?s identity is less important than its value. ' 'Multiple\n' 'evaluations of literals with the same value (either the ' 'same\n' @@ -626,10 +626,10 @@ 'Note: Defining module "__getattr__" and setting module ' '"__class__"\n' ' only affect lookups made using the attribute access ' - 'syntax --\n' + 'syntax ?\n' ' directly accessing the module globals (whether by code ' 'within the\n' - " module, or via a reference to the module's globals " + ' module, or via a reference to the module?s globals ' 'dictionary) is\n' ' unaffected.\n' '\n' @@ -654,13 +654,12 @@ 'containing the method (a so-called *descriptor* class) ' 'appears in an\n' '*owner* class (the descriptor must be in either the ' - "owner's class\n" + 'owner?s class\n' 'dictionary or in the class dictionary for one of its ' 'parents). In the\n' - 'examples below, "the attribute" refers to the attribute ' + 'examples below, ?the attribute? refers to the attribute ' 'whose name is\n' - "the key of the property in the owner class' " - '"__dict__".\n' + 'the key of the property in the owner class? "__dict__".\n' '\n' 'object.__get__(self, instance, owner)\n' '\n' @@ -717,8 +716,8 @@ '====================\n' '\n' 'In general, a descriptor is an object attribute with ' - '"binding\n' - 'behavior", one whose attribute access has been ' + '?binding\n' + 'behavior?, one whose attribute access has been ' 'overridden by methods\n' 'in the descriptor protocol: "__get__()", "__set__()", ' 'and\n' @@ -728,7 +727,7 @@ '\n' 'The default behavior for attribute access is to get, ' 'set, or delete\n' - "the attribute from an object's dictionary. For instance, " + 'the attribute from an object?s dictionary. For instance, ' '"a.x" has a\n' 'lookup chain starting with "a.__dict__[\'x\']", then\n' '"type(a).__dict__[\'x\']", and continuing through the ' @@ -783,7 +782,7 @@ 'does not define "__get__()", then accessing the ' 'attribute will return\n' 'the descriptor object itself unless there is a value in ' - "the object's\n" + 'the object?s\n' 'instance dictionary. If the descriptor defines ' '"__set__()" and/or\n' '"__delete__()", it is a data descriptor; if it defines ' @@ -904,7 +903,7 @@ '\n' '* Nonempty *__slots__* does not work for classes derived ' 'from\n' - ' "variable-length" built-in types such as "int", ' + ' ?variable-length? built-in types such as "int", ' '"bytes" and "tuple".\n' '\n' '* Any non-string iterable may be assigned to ' @@ -1056,7 +1055,7 @@ 'while\n' 'floor division of integers results in an integer; the result is ' 'that\n' - "of mathematical division with the 'floor' function applied to the\n" + 'of mathematical division with the ?floor? function applied to the\n' 'result. Division by zero raises the "ZeroDivisionError" ' 'exception.\n' '\n' @@ -1132,10 +1131,10 @@ '************\n' '\n' 'Code objects are used by the implementation to ' - 'represent "pseudo-\n' - 'compiled" executable Python code such as a function ' + 'represent ?pseudo-\n' + 'compiled? executable Python code such as a function ' 'body. They differ\n' - "from function objects because they don't contain a " + 'from function objects because they don?t contain a ' 'reference to their\n' 'global execution environment. Code objects are ' 'returned by the built-\n' @@ -1166,7 +1165,7 @@ 'bltin-null-object': 'The Null Object\n' '***************\n' '\n' - "This object is returned by functions that don't " + 'This object is returned by functions that don?t ' 'explicitly return a\n' 'value. It supports no special operations. There is ' 'exactly one null\n' @@ -1179,7 +1178,7 @@ '************\n' '\n' 'Type objects represent the various object types. An ' - "object's type is\n" + 'object?s type is\n' 'accessed by the built-in function "type()". There are ' 'no special\n' 'operations on types. The standard module "types" ' @@ -1262,7 +1261,7 @@ '\n' 'object.__call__(self[, args...])\n' '\n' - ' Called when the instance is "called" as a function; if ' + ' Called when the instance is ?called? as a function; if ' 'this method\n' ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' ' "x.__call__(arg1, arg2, ...)".\n', @@ -1322,7 +1321,7 @@ 'values are calculated, once, when the function is defined; thus, a\n' 'mutable object such as a list or dictionary used as default value ' 'will\n' - "be shared by all calls that don't specify an argument value for " + 'be shared by all calls that don?t specify an argument value for ' 'the\n' 'corresponding slot; this should usually be avoided.) If there are ' 'any\n' @@ -1335,7 +1334,7 @@ '**CPython implementation detail:** An implementation may provide\n' 'built-in functions whose positional parameters do not have names, ' 'even\n' - "if they are 'named' for the purpose of documentation, and which\n" + 'if they are ?named? for the purpose of documentation, and which\n' 'therefore cannot be supplied by keyword. In CPython, this is the ' 'case\n' 'for functions implemented in C that use "PyArg_ParseTuple()" to ' @@ -1367,16 +1366,17 @@ 'must evaluate to an *iterable*. Elements from these iterables are\n' 'treated as if they were additional positional arguments. For the ' 'call\n' - '"f(x1, x2, *y, x3, x4)", if *y* evaluates to a sequence *y1*, ...,\n' - '*yM*, this is equivalent to a call with M+4 positional arguments ' - '*x1*,\n' - '*x2*, *y1*, ..., *yM*, *x3*, *x4*.\n' + '"f(x1, x2, *y, x3, x4)", if *y* evaluates to a sequence *y1*, ?, ' + '*yM*,\n' + 'this is equivalent to a call with M+4 positional arguments *x1*, ' + '*x2*,\n' + '*y1*, ?, *yM*, *x3*, *x4*.\n' '\n' 'A consequence of this is that although the "*expression" syntax ' 'may\n' 'appear *after* explicit keyword arguments, it is processed ' '*before*\n' - 'the keyword arguments (and any "**expression" arguments -- see ' + 'the keyword arguments (and any "**expression" arguments ? see ' 'below).\n' 'So:\n' '\n' @@ -1423,7 +1423,7 @@ 'exception. How this value is computed depends on the type of the\n' 'callable object.\n' '\n' - 'If it is---\n' + 'If it is?\n' '\n' 'a user-defined function:\n' ' The code block for the function is executed, passing it the\n' @@ -1482,10 +1482,10 @@ ' class Foo(object):\n' ' pass\n' '\n' - "The class's suite is then executed in a new execution frame (see\n" + 'The class?s suite is then executed in a new execution frame (see\n' 'Naming and binding), using a newly created local namespace and the\n' 'original global namespace. (Usually, the suite contains mostly\n' - "function definitions.) When the class's suite finishes execution, " + 'function definitions.) When the class?s suite finishes execution, ' 'its\n' 'execution frame is discarded but its local namespace is saved. [4] ' 'A\n' @@ -1497,7 +1497,7 @@ 'namespace.\n' '\n' 'The order in which attributes are defined in the class body is\n' - 'preserved in the new class\'s "__dict__". Note that this is ' + 'preserved in the new class?s "__dict__". Note that this is ' 'reliable\n' 'only right after the class is created and only for classes that ' 'were\n' @@ -1521,13 +1521,13 @@ 'for\n' 'function decorators. The result is then bound to the class name.\n' '\n' - "**Programmer's note:** Variables defined in the class definition " + '**Programmer?s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' 'attributes\n' 'can be set in a method with "self.name = value". Both class and\n' 'instance attributes are accessible through the notation ' - '""self.name"",\n' + '?"self.name"?,\n' 'and an instance attribute hides a class attribute with the same ' 'name\n' 'when accessed in this way. Class attributes can be used as ' @@ -1564,15 +1564,15 @@ 'y" is\n' 'found to be false).\n' '\n' - 'Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and ' + 'Formally, if *a*, *b*, *c*, ?, *y*, *z* are expressions and ' '*op1*,\n' - '*op2*, ..., *opN* are comparison operators, then "a op1 b op2 ' - 'c ... y\n' + '*op2*, ?, *opN* are comparison operators, then "a op1 b op2 c ' + '... y\n' 'opN z" is equivalent to "a op1 b and b op2 c and ... y opN ' 'z", except\n' 'that each expression is evaluated at most once.\n' '\n' - 'Note that "a op1 b op2 c" doesn\'t imply any kind of ' + 'Note that "a op1 b op2 c" doesn?t imply any kind of ' 'comparison between\n' '*a* and *c*, so that, e.g., "x < y > z" is perfectly legal ' '(though\n' @@ -1593,7 +1593,7 @@ 'rather\n' 'abstract notion in Python: For example, there is no canonical ' 'access\n' - "method for an object's value. Also, there is no requirement " + 'method for an object?s value. Also, there is no requirement ' 'that the\n' 'value of an object should be constructed in a particular way, ' 'e.g.\n' @@ -1647,7 +1647,7 @@ 'most\n' 'important built-in types.\n' '\n' - '* Numbers of built-in numeric types (Numeric Types --- int, ' + '* Numbers of built-in numeric types (Numeric Types ? int, ' 'float,\n' ' complex) and of the standard library types ' '"fractions.Fraction" and\n' @@ -1934,9 +1934,9 @@ 'compound\n' 'statements.\n' '\n' - "A compound statement consists of one or more 'clauses.' A " + 'A compound statement consists of one or more ?clauses.? A ' 'clause\n' - "consists of a header and a 'suite.' The clause headers of a\n" + 'consists of a header and a ?suite.? The clause headers of a\n' 'particular compound statement are all at the same indentation ' 'level.\n' 'Each clause header begins with a uniquely identifying keyword ' @@ -1944,12 +1944,12 @@ 'with a colon. A suite is a group of statements controlled by a\n' 'clause. A suite can be one or more semicolon-separated simple\n' 'statements on the same line as the header, following the ' - "header's\n" + 'header?s\n' 'colon, or it can be one or more indented statements on ' 'subsequent\n' 'lines. Only the latter form of a suite can contain nested ' 'compound\n' - "statements; the following is illegal, mostly because it wouldn't " + 'statements; the following is illegal, mostly because it wouldn?t ' 'be\n' 'clear to which "if" clause a following "else" clause would ' 'belong:\n' @@ -1986,7 +1986,7 @@ '"DEDENT". Also note that optional continuation clauses always ' 'begin\n' 'with a keyword that cannot start a statement, thus there are no\n' - 'ambiguities (the \'dangling "else"\' problem is solved in Python ' + 'ambiguities (the ?dangling "else"? problem is solved in Python ' 'by\n' 'requiring nested "if" statements to be indented).\n' '\n' @@ -2037,7 +2037,7 @@ '\n' 'A "break" statement executed in the first suite terminates the ' 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' + 'without executing the "else" clause?s suite. A "continue" ' 'statement\n' 'executed in the first suite skips the rest of the suite and goes ' 'back\n' @@ -2076,7 +2076,7 @@ '\n' 'A "break" statement executed in the first suite terminates the ' 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' + 'without executing the "else" clause?s suite. A "continue" ' 'statement\n' 'executed in the first suite skips the rest of the suite and ' 'continues\n' @@ -2103,7 +2103,7 @@ 'to at\n' 'all by the loop. Hint: the built-in function "range()" returns ' 'an\n' - "iterator of integers suitable to emulate the effect of Pascal's " + 'iterator of integers suitable to emulate the effect of Pascal?s ' '"for i\n' ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' '2]".\n' @@ -2165,7 +2165,7 @@ 'expression\n' 'is evaluated, and the clause matches the exception if the ' 'resulting\n' - 'object is "compatible" with the exception. An object is ' + 'object is ?compatible? with the exception. An object is ' 'compatible\n' 'with an exception if it is the class or a base class of the ' 'exception\n' @@ -2192,7 +2192,7 @@ 'assigned to\n' 'the target specified after the "as" keyword in that except ' 'clause, if\n' - "present, and the except clause's suite is executed. All except\n" + 'present, and the except clause?s suite is executed. All except\n' 'clauses must have an executable block. When the end of this ' 'block is\n' 'reached, execution continues normally after the entire try ' @@ -2228,7 +2228,7 @@ 'alive\n' 'until the next garbage collection occurs.\n' '\n' - "Before an except clause's suite is executed, details about the\n" + 'Before an except clause?s suite is executed, details about the\n' 'exception are stored in the "sys" module and can be accessed ' 'via\n' '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting ' @@ -2249,8 +2249,8 @@ 'are\n' 'not handled by the preceding "except" clauses.\n' '\n' - 'If "finally" is present, it specifies a \'cleanup\' handler. ' - 'The "try"\n' + 'If "finally" is present, it specifies a ?cleanup? handler. The ' + '"try"\n' 'clause is executed, including any "except" and "else" clauses. ' 'If an\n' 'exception occurs in any of the clauses and is not handled, the\n' @@ -2281,13 +2281,12 @@ '\n' 'When a "return", "break" or "continue" statement is executed in ' 'the\n' - '"try" suite of a "try"..."finally" statement, the "finally" ' - 'clause is\n' - 'also executed \'on the way out.\' A "continue" statement is ' + '"try" suite of a "try"?"finally" statement, the "finally" clause ' + 'is\n' + 'also executed ?on the way out.? A "continue" statement is ' 'illegal in\n' 'the "finally" clause. (The reason is a problem with the current\n' - 'implementation --- this restriction may be lifted in the ' - 'future).\n' + 'implementation ? this restriction may be lifted in the future).\n' '\n' 'The return value of a function is determined by the last ' '"return"\n' @@ -2319,14 +2318,14 @@ 'with\n' 'methods defined by a context manager (see section With ' 'Statement\n' - 'Context Managers). This allows common ' - '"try"..."except"..."finally"\n' - 'usage patterns to be encapsulated for convenient reuse.\n' + 'Context Managers). This allows common "try"?"except"?"finally" ' + 'usage\n' + 'patterns to be encapsulated for convenient reuse.\n' '\n' ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' ' with_item ::= expression ["as" target]\n' '\n' - 'The execution of the "with" statement with one "item" proceeds ' + 'The execution of the "with" statement with one ?item? proceeds ' 'as\n' 'follows:\n' '\n' @@ -2334,9 +2333,9 @@ '"with_item")\n' ' is evaluated to obtain a context manager.\n' '\n' - '2. The context manager\'s "__exit__()" is loaded for later use.\n' + '2. The context manager?s "__exit__()" is loaded for later use.\n' '\n' - '3. The context manager\'s "__enter__()" method is invoked.\n' + '3. The context manager?s "__enter__()" method is invoked.\n' '\n' '4. If a target was included in the "with" statement, the return\n' ' value from "__enter__()" is assigned to it.\n' @@ -2353,8 +2352,7 @@ '\n' '5. The suite is executed.\n' '\n' - '6. The context manager\'s "__exit__()" method is invoked. If ' - 'an\n' + '6. The context manager?s "__exit__()" method is invoked. If an\n' ' exception caused the suite to be exited, its type, value, ' 'and\n' ' traceback are passed as arguments to "__exit__()". Otherwise, ' @@ -2394,7 +2392,7 @@ '\n' 'See also:\n' '\n' - ' **PEP 343** - The "with" statement\n' + ' **PEP 343** - The ?with? statement\n' ' The specification, background, and examples for the Python ' '"with"\n' ' statement.\n' @@ -2463,25 +2461,24 @@ '"func".\n' '\n' 'When one or more *parameters* have the form *parameter* "="\n' - '*expression*, the function is said to have "default parameter ' - 'values."\n' + '*expression*, the function is said to have ?default parameter ' + 'values.?\n' 'For a parameter with a default value, the corresponding ' '*argument* may\n' - "be omitted from a call, in which case the parameter's default " + 'be omitted from a call, in which case the parameter?s default ' 'value is\n' 'substituted. If a parameter has a default value, all following\n' - 'parameters up until the ""*"" must also have a default value --- ' - 'this\n' - 'is a syntactic restriction that is not expressed by the ' - 'grammar.\n' + 'parameters up until the ?"*"? must also have a default value ? ' + 'this is\n' + 'a syntactic restriction that is not expressed by the grammar.\n' '\n' '**Default parameter values are evaluated from left to right when ' 'the\n' 'function definition is executed.** This means that the ' 'expression is\n' 'evaluated once, when the function is defined, and that the same ' - '"pre-\n' - 'computed" value is used for each call. This is especially ' + '?pre-\n' + 'computed? value is used for each call. This is especially ' 'important\n' 'to understand when a default parameter is a mutable object, such ' 'as a\n' @@ -2507,26 +2504,26 @@ 'mentioned in\n' 'the parameter list, either from position arguments, from ' 'keyword\n' - 'arguments, or from default values. If the form ""*identifier"" ' + 'arguments, or from default values. If the form ?"*identifier"? ' 'is\n' 'present, it is initialized to a tuple receiving any excess ' 'positional\n' 'parameters, defaulting to the empty tuple. If the form\n' - '""**identifier"" is present, it is initialized to a new ordered\n' + '?"**identifier"? is present, it is initialized to a new ordered\n' 'mapping receiving any excess keyword arguments, defaulting to a ' 'new\n' - 'empty mapping of the same type. Parameters after ""*"" or\n' - '""*identifier"" are keyword-only parameters and may only be ' + 'empty mapping of the same type. Parameters after ?"*"? or\n' + '?"*identifier"? are keyword-only parameters and may only be ' 'passed\n' 'used keyword arguments.\n' '\n' - 'Parameters may have annotations of the form "": expression"" ' + 'Parameters may have annotations of the form ?": expression"? ' 'following\n' 'the parameter name. Any parameter may have an annotation even ' 'those\n' 'of the form "*identifier" or "**identifier". Functions may ' 'have\n' - '"return" annotation of the form ""-> expression"" after the ' + '?return? annotation of the form ?"-> expression"? after the ' 'parameter\n' 'list. These annotations can be any valid Python expression. ' 'The\n' @@ -2534,8 +2531,7 @@ 'function.\n' 'The annotation values are available as values of a dictionary ' 'keyed by\n' - 'the parameters\' names in the "__annotations__" attribute of ' - 'the\n' + 'the parameters? names in the "__annotations__" attribute of the\n' 'function object. If the "annotations" import from "__future__" ' 'is\n' 'used, annotations are preserved as strings at runtime which ' @@ -2553,16 +2549,16 @@ 'lambda\n' 'expression is merely a shorthand for a simplified function ' 'definition;\n' - 'a function defined in a ""def"" statement can be passed around ' + 'a function defined in a ?"def"? statement can be passed around ' 'or\n' 'assigned to another name just like a function defined by a ' 'lambda\n' - 'expression. The ""def"" form is actually more powerful since ' + 'expression. The ?"def"? form is actually more powerful since ' 'it\n' 'allows the execution of multiple statements and annotations.\n' '\n' - "**Programmer's note:** Functions are first-class objects. A " - '""def""\n' + '**Programmer?s note:** Functions are first-class objects. A ' + '?"def"?\n' 'statement executed inside a function definition defines a local\n' 'function that can be returned or passed around. Free variables ' 'used\n' @@ -2621,12 +2617,12 @@ ' class Foo(object):\n' ' pass\n' '\n' - "The class's suite is then executed in a new execution frame " + 'The class?s suite is then executed in a new execution frame ' '(see\n' 'Naming and binding), using a newly created local namespace and ' 'the\n' 'original global namespace. (Usually, the suite contains mostly\n' - "function definitions.) When the class's suite finishes " + 'function definitions.) When the class?s suite finishes ' 'execution, its\n' 'execution frame is discarded but its local namespace is saved. ' '[4] A\n' @@ -2639,7 +2635,7 @@ 'namespace.\n' '\n' 'The order in which attributes are defined in the class body is\n' - 'preserved in the new class\'s "__dict__". Note that this is ' + 'preserved in the new class?s "__dict__". Note that this is ' 'reliable\n' 'only right after the class is created and only for classes that ' 'were\n' @@ -2664,14 +2660,14 @@ 'function decorators. The result is then bound to the class ' 'name.\n' '\n' - "**Programmer's note:** Variables defined in the class definition " + '**Programmer?s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' 'attributes\n' 'can be set in a method with "self.name = value". Both class ' 'and\n' 'instance attributes are accessible through the notation ' - '""self.name"",\n' + '?"self.name"?,\n' 'and an instance attribute hides a class attribute with the same ' 'name\n' 'when accessed in this way. Class attributes can be used as ' @@ -2807,20 +2803,19 @@ ' exception. That new exception causes the old one to be ' 'lost.\n' '\n' - '[2] Currently, control "flows off the end" except in the case ' + '[2] Currently, control ?flows off the end? except in the case ' 'of\n' ' an exception or the execution of a "return", "continue", or\n' ' "break" statement.\n' '\n' '[3] A string literal appearing as the first statement in the\n' - ' function body is transformed into the function\'s "__doc__"\n' - " attribute and therefore the function's *docstring*.\n" + ' function body is transformed into the function?s "__doc__"\n' + ' attribute and therefore the function?s *docstring*.\n' '\n' '[4] A string literal appearing as the first statement in the ' 'class\n' - ' body is transformed into the namespace\'s "__doc__" item ' - 'and\n' - " therefore the class's *docstring*.\n", + ' body is transformed into the namespace?s "__doc__" item and\n' + ' therefore the class?s *docstring*.\n', 'context-managers': 'With Statement Context Managers\n' '*******************************\n' '\n' @@ -2850,7 +2845,7 @@ '\n' ' Enter the runtime context related to this object. The ' '"with"\n' - " statement will bind this method's return value to the " + ' statement will bind this method?s return value to the ' 'target(s)\n' ' specified in the "as" clause of the statement, if ' 'any.\n' @@ -2875,11 +2870,11 @@ '\n' ' Note that "__exit__()" methods should not reraise the ' 'passed-in\n' - " exception; this is the caller's responsibility.\n" + ' exception; this is the caller?s responsibility.\n' '\n' 'See also:\n' '\n' - ' **PEP 343** - The "with" statement\n' + ' **PEP 343** - The ?with? statement\n' ' The specification, background, and examples for the ' 'Python "with"\n' ' statement.\n', @@ -2905,7 +2900,7 @@ '\n' 'When a description of an arithmetic operator below uses the ' 'phrase\n' - '"the numeric arguments are converted to a common type," this ' + '?the numeric arguments are converted to a common type,? this ' 'means\n' 'that the operator implementation for built-in types works as ' 'follows:\n' @@ -2923,7 +2918,7 @@ '\n' 'Some additional rules apply for certain operators (e.g., a ' 'string as a\n' - "left argument to the '%' operator). Extensions must define " + 'left argument to the ?%? operator). Extensions must define ' 'their own\n' 'conversion behavior.\n', 'customization': 'Basic customization\n' @@ -2947,7 +2942,7 @@ '\n' ' Typical implementations create a new instance of the ' 'class by\n' - ' invoking the superclass\'s "__new__()" method using\n' + ' invoking the superclass?s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' ' modifying the newly-created instance as necessary before ' @@ -2956,7 +2951,7 @@ '\n' ' If "__new__()" returns an instance of *cls*, then the ' 'new\n' - ' instance\'s "__init__()" method will be invoked like\n' + ' instance?s "__init__()" method will be invoked like\n' ' "__init__(self[, ...])", where *self* is the new ' 'instance and the\n' ' remaining arguments are the same as were passed to ' @@ -2964,7 +2959,7 @@ '\n' ' If "__new__()" does not return an instance of *cls*, ' 'then the new\n' - ' instance\'s "__init__()" method will not be invoked.\n' + ' instance?s "__init__()" method will not be invoked.\n' '\n' ' "__new__()" is intended mainly to allow subclasses of ' 'immutable\n' @@ -2982,7 +2977,7 @@ 'those\n' ' passed to the class constructor expression. If a base ' 'class has an\n' - ' "__init__()" method, the derived class\'s "__init__()" ' + ' "__init__()" method, the derived class?s "__init__()" ' 'method, if\n' ' any, must explicitly call it to ensure proper ' 'initialization of the\n' @@ -3003,7 +2998,7 @@ 'is also\n' ' called a finalizer or (improperly) a destructor. If a ' 'base class\n' - ' has a "__del__()" method, the derived class\'s ' + ' has a "__del__()" method, the derived class?s ' '"__del__()" method,\n' ' if any, must explicitly call it to ensure proper ' 'deletion of the\n' @@ -3024,11 +3019,11 @@ 'for\n' ' objects that still exist when the interpreter exits.\n' '\n' - ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' - 'the former\n' + ' Note: "del x" doesn?t directly call "x.__del__()" ? the ' + 'former\n' ' decrements the reference count for "x" by one, and the ' 'latter is\n' - ' only called when "x"\'s reference count reaches zero.\n' + ' only called when "x"?s reference count reaches zero.\n' '\n' ' **CPython implementation detail:** It is possible for a ' 'reference\n' @@ -3040,7 +3035,7 @@ 'reference\n' ' cycles is when an exception has been caught in a local ' 'variable.\n' - " The frame's locals then reference the exception, which " + ' The frame?s locals then reference the exception, which ' 'references\n' ' its own traceback, which references the locals of all ' 'frames caught\n' @@ -3087,7 +3082,7 @@ 'object.__repr__(self)\n' '\n' ' Called by the "repr()" built-in function to compute the ' - '"official"\n' + '?official?\n' ' string representation of an object. If at all possible, ' 'this\n' ' should look like a valid Python expression that could be ' @@ -3101,7 +3096,7 @@ ' value must be a string object. If a class defines ' '"__repr__()" but\n' ' not "__str__()", then "__repr__()" is also used when an ' - '"informal"\n' + '?informal?\n' ' string representation of instances of that class is ' 'required.\n' '\n' @@ -3113,7 +3108,7 @@ '\n' ' Called by "str(object)" and the built-in functions ' '"format()" and\n' - ' "print()" to compute the "informal" or nicely printable ' + ' "print()" to compute the ?informal? or nicely printable ' 'string\n' ' representation of an object. The return value must be a ' 'string\n' @@ -3141,7 +3136,7 @@ 'extension,\n' ' evaluation of formatted string literals and the ' '"str.format()"\n' - ' method, to produce a "formatted" string representation ' + ' method, to produce a ?formatted? string representation ' 'of an\n' ' object. The "format_spec" argument is a string that ' 'contains a\n' @@ -3177,7 +3172,7 @@ 'object.__gt__(self, other)\n' 'object.__ge__(self, other)\n' '\n' - ' These are the so-called "rich comparison" methods. The\n' + ' These are the so-called ?rich comparison? methods. The\n' ' correspondence between operator symbols and method names ' 'is as\n' ' follows: "x>> import pdb\n' @@ -3427,11 +3422,11 @@ 'post-\n' 'mortem debugging (or after normal exit of the program), pdb ' 'will\n' - "restart the program. Automatic restarting preserves pdb's state " + 'restart the program. Automatic restarting preserves pdb?s state ' '(such\n' 'as breakpoints) and in most cases is more useful than quitting ' 'the\n' - "debugger upon program's exit.\n" + 'debugger upon program?s exit.\n' '\n' 'New in version 3.2: "pdb.py" now accepts a "-c" option that ' 'executes\n' @@ -3621,7 +3616,7 @@ 'the last command was a "list" command, the next 11 lines are ' 'listed.\n' '\n' - "Commands that the debugger doesn't recognize are assumed to be " + 'Commands that the debugger doesn?t recognize are assumed to be ' 'Python\n' 'statements and are executed in the context of the program being\n' 'debugged. Python statements can also be prefixed with an ' @@ -3632,7 +3627,7 @@ 'function.\n' 'When an exception occurs in such a statement, the exception name ' 'is\n' - "printed but the debugger's state is not changed.\n" + 'printed but the debugger?s state is not changed.\n' '\n' 'The debugger supports aliases. Aliases can have parameters ' 'which\n' @@ -3649,7 +3644,7 @@ 'first\n' '";;" pair, even if it is in the middle of a quoted string.\n' '\n' - 'If a file ".pdbrc" exists in the user\'s home directory or in ' + 'If a file ".pdbrc" exists in the user?s home directory or in ' 'the\n' 'current directory, it is read in and executed as if it had been ' 'typed\n' @@ -3705,7 +3700,7 @@ 'prefixed\n' ' with a filename and a colon, to specify a breakpoint in ' 'another\n' - " file (probably one that hasn't been loaded yet). The file " + ' file (probably one that hasn?t been loaded yet). The file ' 'is\n' ' searched on "sys.path". Note that each breakpoint is ' 'assigned a\n' @@ -3810,7 +3805,7 @@ ' breakpoint?which could have its own command list, leading to\n' ' ambiguities about which list to execute.\n' '\n' - " If you use the 'silent' command in the command list, the " + ' If you use the ?silent? command in the command list, the ' 'usual\n' ' message about stopping at a breakpoint is not printed. This ' 'may be\n' @@ -3869,13 +3864,13 @@ 'the\n' ' bottom-most frame. This lets you jump back and execute code ' 'again,\n' - " or jump forward to skip code that you don't want to run.\n" + ' or jump forward to skip code that you don?t want to run.\n' '\n' - ' It should be noted that not all jumps are allowed -- for ' - 'instance\n' - ' it is not possible to jump into the middle of a "for" loop or ' - 'out\n' - ' of a "finally" clause.\n' + ' It should be noted that not all jumps are allowed ? for ' + 'instance it\n' + ' is not possible to jump into the middle of a "for" loop or ' + 'out of a\n' + ' "finally" clause.\n' '\n' 'l(ist) [first[, last]]\n' '\n' @@ -3918,8 +3913,8 @@ ' value.\n' '\n' ' Note: "print()" can also be used, but is not a debugger ' - 'command\n' - ' --- this executes the Python "print()" function.\n' + 'command ?\n' + ' this executes the Python "print()" function.\n' '\n' 'pp expression\n' '\n' @@ -4089,7 +4084,7 @@ 'dictionary:\n' 'each key object is used as a key into the dictionary to store the\n' 'corresponding datum. This means that you can specify the same key\n' - "multiple times in the key/datum list, and the final dictionary's " + 'multiple times in the key/datum list, and the final dictionary?s ' 'value\n' 'for that key will be the last one given.\n' '\n' @@ -4103,7 +4098,7 @@ '\n' 'A dict comprehension, in contrast to list and set comprehensions,\n' 'needs two expressions separated with a colon followed by the usual\n' - '"for" and "if" clauses. When the comprehension is run, the ' + '?for? and ?if? clauses. When the comprehension is run, the ' 'resulting\n' 'key and value elements are inserted in the new dictionary in the ' 'order\n' @@ -4177,7 +4172,7 @@ 'error (such as division by zero). A Python program can also\n' 'explicitly raise an exception with the "raise" statement. ' 'Exception\n' - 'handlers are specified with the "try" ... "except" statement. ' + 'handlers are specified with the "try" ? "except" statement. ' 'The\n' '"finally" clause of such a statement can be used to specify ' 'cleanup\n' @@ -4185,7 +4180,7 @@ 'whether an\n' 'exception occurred or not in the preceding code.\n' '\n' - 'Python uses the "termination" model of error handling: an ' + 'Python uses the ?termination? model of error handling: an ' 'exception\n' 'handler can find out what happened and continue execution at ' 'an outer\n' @@ -4253,7 +4248,7 @@ 'argument to the interpreter) is a code block. A script command ' '(a\n' 'command specified on the interpreter command line with the ' - "'**-c**'\n" + '?**-c**?\n' 'option) is a code block. The string argument passed to the ' 'built-in\n' 'functions "eval()" and "exec()" is a code block.\n' @@ -4262,7 +4257,7 @@ 'contains\n' 'some administrative information (used for debugging) and ' 'determines\n' - "where and how execution continues after the code block's " + 'where and how execution continues after the code block?s ' 'execution has\n' 'completed.\n' '\n' @@ -4337,7 +4332,7 @@ 'nearest\n' 'enclosing scope. The set of all such scopes visible to a code ' 'block\n' - "is called the block's *environment*.\n" + 'is called the block?s *environment*.\n' '\n' 'When a name is not found at all, a "NameError" exception is ' 'raised. If\n' @@ -4415,7 +4410,7 @@ 'the class. The scope of names defined in a class block is ' 'limited to\n' 'the class block; it does not extend to the code blocks of ' - 'methods --\n' + 'methods ?\n' 'this includes comprehensions and generator expressions since ' 'they are\n' 'implemented using a function scope. This means that the ' @@ -4443,7 +4438,7 @@ 'global\n' 'namespace; this should be a dictionary or a module (in the ' 'latter case\n' - "the module's dictionary is used). By default, when in the " + 'the module?s dictionary is used). By default, when in the ' '"__main__"\n' 'module, "__builtins__" is the built-in module "builtins"; when ' 'in any\n' @@ -4498,7 +4493,7 @@ 'error (such as division by zero). A Python program can also\n' 'explicitly raise an exception with the "raise" statement. ' 'Exception\n' - 'handlers are specified with the "try" ... "except" statement. ' + 'handlers are specified with the "try" ? "except" statement. ' 'The\n' '"finally" clause of such a statement can be used to specify ' 'cleanup\n' @@ -4506,7 +4501,7 @@ 'whether an\n' 'exception occurred or not in the preceding code.\n' '\n' - 'Python uses the "termination" model of error handling: an ' + 'Python uses the ?termination? model of error handling: an ' 'exception\n' 'handler can find out what happened and continue execution at an ' 'outer\n' @@ -4586,7 +4581,7 @@ '(a.k.a. a\n' '*singleton*); it is optional in all other cases. A single ' 'expression\n' - "without a trailing comma doesn't create a tuple, but rather " + 'without a trailing comma doesn?t create a tuple, but rather ' 'yields the\n' 'value of that expression. (To create an empty tuple, use an ' 'empty pair\n' @@ -4647,8 +4642,7 @@ 'terminates.\n' '\n' 'A "break" statement executed in the first suite terminates the loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' - 'statement\n' + 'without executing the "else" clause?s suite. A "continue" statement\n' 'executed in the first suite skips the rest of the suite and ' 'continues\n' 'with the next item, or with the "else" clause if there is no next\n' @@ -4670,7 +4664,7 @@ 'Names in the target list are not deleted when the loop is finished,\n' 'but if the sequence is empty, they will not have been assigned to at\n' 'all by the loop. Hint: the built-in function "range()" returns an\n' - 'iterator of integers suitable to emulate the effect of Pascal\'s "for ' + 'iterator of integers suitable to emulate the effect of Pascal?s "for ' 'i\n' ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n' '\n' @@ -4706,7 +4700,7 @@ 'are\n' 'differences.\n' '\n' - 'Format strings contain "replacement fields" surrounded by ' + 'Format strings contain ?replacement fields? surrounded by ' 'curly braces\n' '"{}". Anything that is not contained in braces is ' 'considered literal\n' @@ -4749,29 +4743,27 @@ '\n' 'The *field_name* itself begins with an *arg_name* that is ' 'either a\n' - "number or a keyword. If it's a number, it refers to a " + 'number or a keyword. If it?s a number, it refers to a ' 'positional\n' - "argument, and if it's a keyword, it refers to a named " + 'argument, and if it?s a keyword, it refers to a named ' 'keyword\n' 'argument. If the numerical arg_names in a format string ' 'are 0, 1, 2,\n' - '... in sequence, they can all be omitted (not just some) ' - 'and the\n' - 'numbers 0, 1, 2, ... will be automatically inserted in that ' - 'order.\n' - 'Because *arg_name* is not quote-delimited, it is not ' - 'possible to\n' - 'specify arbitrary dictionary keys (e.g., the strings ' - '"\'10\'" or\n' - '"\':-]\'") within a format string. The *arg_name* can be ' - 'followed by any\n' - 'number of index or attribute expressions. An expression of ' - 'the form\n' - '"\'.name\'" selects the named attribute using "getattr()", ' - 'while an\n' - 'expression of the form "\'[index]\'" does an index lookup ' - 'using\n' - '"__getitem__()".\n' + '? in sequence, they can all be omitted (not just some) and ' + 'the numbers\n' + '0, 1, 2, ? will be automatically inserted in that order. ' + 'Because\n' + '*arg_name* is not quote-delimited, it is not possible to ' + 'specify\n' + 'arbitrary dictionary keys (e.g., the strings "\'10\'" or ' + '"\':-]\'") within\n' + 'a format string. The *arg_name* can be followed by any ' + 'number of index\n' + 'or attribute expressions. An expression of the form ' + '"\'.name\'" selects\n' + 'the named attribute using "getattr()", while an expression ' + 'of the form\n' + '"\'[index]\'" does an index lookup using "__getitem__()".\n' '\n' 'Changed in version 3.1: The positional argument specifiers ' 'can be\n' @@ -4826,7 +4818,7 @@ 'alignment,\n' 'padding, decimal precision and so on. Each value type can ' 'define its\n' - 'own "formatting mini-language" or interpretation of the ' + 'own ?formatting mini-language? or interpretation of the ' '*format_spec*.\n' '\n' 'Most built-in types support a common formatting ' @@ -4852,7 +4844,7 @@ 'Format Specification Mini-Language\n' '==================================\n' '\n' - '"Format specifications" are used within replacement fields ' + '?Format specifications? are used within replacement fields ' 'contained\n' 'within a format string to define how individual values are ' 'presented\n' @@ -4894,13 +4886,13 @@ 'character that can be any character and defaults to a space ' 'if\n' 'omitted. It is not possible to use a literal curly brace ' - '(""{"" or\n' - '""}"") as the *fill* character in a formatted string ' + '(?"{"? or\n' + '?"}"?) as the *fill* character in a formatted string ' 'literal or when\n' 'using the "str.format()" method. However, it is possible ' 'to insert a\n' 'curly brace with a nested replacement field. This ' - "limitation doesn't\n" + 'limitation doesn?t\n' 'affect the "format()" function.\n' '\n' 'The meaning of the various alignment options is as ' @@ -4929,10 +4921,10 @@ 'the sign (if any) |\n' ' | | but before the digits. This is used for ' 'printing fields |\n' - " | | in the form '+000000120'. This alignment " + ' | | in the form ?+000000120?. This alignment ' 'option is only |\n' ' | | valid for numeric types. It becomes the ' - "default when '0' |\n" + 'default when ?0? |\n' ' | | immediately precedes the field ' 'width. |\n' ' ' @@ -4981,7 +4973,7 @@ ' ' '+-----------+------------------------------------------------------------+\n' '\n' - 'The "\'#\'" option causes the "alternate form" to be used ' + 'The "\'#\'" option causes the ?alternate form? to be used ' 'for the\n' 'conversion. The alternate form is defined differently for ' 'different\n' @@ -5150,7 +5142,7 @@ '+===========+============================================================+\n' ' | "\'e\'" | Exponent notation. Prints the number in ' 'scientific |\n' - " | | notation using the letter 'e' to indicate " + ' | | notation using the letter ?e? to indicate ' 'the exponent. |\n' ' | | The default precision is ' '"6". |\n' @@ -5158,7 +5150,7 @@ '+-----------+------------------------------------------------------------+\n' ' | "\'E\'" | Exponent notation. Same as "\'e\'" ' 'except it uses an upper |\n' - " | | case 'E' as the separator " + ' | | case ?E? as the separator ' 'character. |\n' ' ' '+-----------+------------------------------------------------------------+\n' @@ -5295,7 +5287,7 @@ "{longitude}'.format(**coord)\n" " 'Coordinates: 37.24N, -115.81W'\n" '\n' - "Accessing arguments' attributes:\n" + 'Accessing arguments? attributes:\n' '\n' ' >>> c = 3-5j\n' " >>> ('The complex number {0} is formed from the real " @@ -5313,7 +5305,7 @@ ' >>> str(Point(4, 2))\n' " 'Point(4, 2)'\n" '\n' - "Accessing arguments' items:\n" + 'Accessing arguments? items:\n' '\n' ' >>> coord = (3, 5)\n' " >>> 'X: {0[0]}; Y: {0[1]}'.format(coord)\n" @@ -5475,25 +5467,24 @@ '"func".\n' '\n' 'When one or more *parameters* have the form *parameter* "="\n' - '*expression*, the function is said to have "default parameter ' - 'values."\n' + '*expression*, the function is said to have ?default parameter ' + 'values.?\n' 'For a parameter with a default value, the corresponding ' '*argument* may\n' - "be omitted from a call, in which case the parameter's default " + 'be omitted from a call, in which case the parameter?s default ' 'value is\n' 'substituted. If a parameter has a default value, all following\n' - 'parameters up until the ""*"" must also have a default value --- ' - 'this\n' - 'is a syntactic restriction that is not expressed by the ' - 'grammar.\n' + 'parameters up until the ?"*"? must also have a default value ? ' + 'this is\n' + 'a syntactic restriction that is not expressed by the grammar.\n' '\n' '**Default parameter values are evaluated from left to right when ' 'the\n' 'function definition is executed.** This means that the ' 'expression is\n' 'evaluated once, when the function is defined, and that the same ' - '"pre-\n' - 'computed" value is used for each call. This is especially ' + '?pre-\n' + 'computed? value is used for each call. This is especially ' 'important\n' 'to understand when a default parameter is a mutable object, such ' 'as a\n' @@ -5519,26 +5510,26 @@ 'mentioned in\n' 'the parameter list, either from position arguments, from ' 'keyword\n' - 'arguments, or from default values. If the form ""*identifier"" ' + 'arguments, or from default values. If the form ?"*identifier"? ' 'is\n' 'present, it is initialized to a tuple receiving any excess ' 'positional\n' 'parameters, defaulting to the empty tuple. If the form\n' - '""**identifier"" is present, it is initialized to a new ordered\n' + '?"**identifier"? is present, it is initialized to a new ordered\n' 'mapping receiving any excess keyword arguments, defaulting to a ' 'new\n' - 'empty mapping of the same type. Parameters after ""*"" or\n' - '""*identifier"" are keyword-only parameters and may only be ' + 'empty mapping of the same type. Parameters after ?"*"? or\n' + '?"*identifier"? are keyword-only parameters and may only be ' 'passed\n' 'used keyword arguments.\n' '\n' - 'Parameters may have annotations of the form "": expression"" ' + 'Parameters may have annotations of the form ?": expression"? ' 'following\n' 'the parameter name. Any parameter may have an annotation even ' 'those\n' 'of the form "*identifier" or "**identifier". Functions may ' 'have\n' - '"return" annotation of the form ""-> expression"" after the ' + '?return? annotation of the form ?"-> expression"? after the ' 'parameter\n' 'list. These annotations can be any valid Python expression. ' 'The\n' @@ -5546,8 +5537,7 @@ 'function.\n' 'The annotation values are available as values of a dictionary ' 'keyed by\n' - 'the parameters\' names in the "__annotations__" attribute of ' - 'the\n' + 'the parameters? names in the "__annotations__" attribute of the\n' 'function object. If the "annotations" import from "__future__" ' 'is\n' 'used, annotations are preserved as strings at runtime which ' @@ -5565,16 +5555,16 @@ 'lambda\n' 'expression is merely a shorthand for a simplified function ' 'definition;\n' - 'a function defined in a ""def"" statement can be passed around ' + 'a function defined in a ?"def"? statement can be passed around ' 'or\n' 'assigned to another name just like a function defined by a ' 'lambda\n' - 'expression. The ""def"" form is actually more powerful since ' + 'expression. The ?"def"? form is actually more powerful since ' 'it\n' 'allows the execution of multiple statements and annotations.\n' '\n' - "**Programmer's note:** Functions are first-class objects. A " - '""def""\n' + '**Programmer?s note:** Functions are first-class objects. A ' + '?"def"?\n' 'statement executed inside a function definition defines a local\n' 'function that can be returned or passed around. Free variables ' 'used\n' @@ -5633,8 +5623,7 @@ 'change\n' 'the meaning of the program.\n' '\n' - '**Programmer\'s note:** "global" is a directive to the parser. ' - 'It\n' + '**Programmer?s note:** "global" is a directive to the parser. It\n' 'applies only to code parsed at the same time as the "global"\n' 'statement. In particular, a "global" statement contained in a ' 'string\n' @@ -5691,7 +5680,7 @@ 'within the\n' ' context of a class definition, are re-written to use a ' 'mangled form\n' - ' to help avoid name clashes between "private" attributes of ' + ' to help avoid name clashes between ?private? attributes of ' 'base and\n' ' derived classes. See section Identifiers (Names).\n', 'identifiers': 'Identifiers and keywords\n' @@ -5839,7 +5828,7 @@ 'within the\n' ' context of a class definition, are re-written to use a ' 'mangled form\n' - ' to help avoid name clashes between "private" attributes of ' + ' to help avoid name clashes between ?private? attributes of ' 'base and\n' ' derived classes. See section Identifiers (Names).\n', 'if': 'The "if" statement\n' @@ -5920,7 +5909,7 @@ 'either\n' 'that the module could not be located, *or* that an error occurred\n' 'while initializing the module, which includes execution of the\n' - "module's code.\n" + 'module?s code.\n' '\n' 'If the requested module is retrieved successfully, it will be ' 'made\n' @@ -5931,7 +5920,7 @@ '\n' '* If no other name is specified, and the module being imported is ' 'a\n' - " top level module, the module's name is bound in the local " + ' top level module, the module?s name is bound in the local ' 'namespace\n' ' as a reference to the imported module\n' '\n' @@ -5984,7 +5973,7 @@ '\n' 'The *public names* defined by a module are determined by checking ' 'the\n' - 'module\'s namespace for a variable named "__all__"; if defined, it ' + 'module?s namespace for a variable named "__all__"; if defined, it ' 'must\n' 'be a sequence of strings which are names defined or imported by ' 'that\n' @@ -5992,7 +5981,7 @@ 'and\n' 'are required to exist. If "__all__" is not defined, the set of ' 'public\n' - "names includes all names found in the module's namespace which do " + 'names includes all names found in the module?s namespace which do ' 'not\n' 'begin with an underscore character ("\'_\'"). "__all__" should ' 'contain\n' @@ -6002,8 +5991,7 @@ 'were\n' 'imported and used within the module).\n' '\n' - 'The wild card form of import --- "from module import *" --- is ' - 'only\n' + 'The wild card form of import ? "from module import *" ? is only\n' 'allowed at the module level. Attempting to use it in class or\n' 'function definitions will raise a "SyntaxError".\n' '\n' @@ -6116,7 +6104,7 @@ '\n' ' import __future__ [as name]\n' '\n' - "That is not a future statement; it's an ordinary import statement " + 'That is not a future statement; it?s an ordinary import statement ' 'with\n' 'no special semantics or syntax restrictions.\n' '\n' @@ -6127,8 +6115,7 @@ 'the\n' 'future statement. This can be controlled by optional arguments ' 'to\n' - '"compile()" --- see the documentation of that function for ' - 'details.\n' + '"compile()" ? see the documentation of that function for details.\n' '\n' 'A future statement typed at an interactive interpreter prompt ' 'will\n' @@ -6334,7 +6321,7 @@ 'nearest\n' 'enclosing scope. The set of all such scopes visible to a code ' 'block\n' - "is called the block's *environment*.\n" + 'is called the block?s *environment*.\n' '\n' 'When a name is not found at all, a "NameError" exception is ' 'raised. If\n' @@ -6408,7 +6395,7 @@ 'the class. The scope of names defined in a class block is limited ' 'to\n' 'the class block; it does not extend to the code blocks of methods ' - '--\n' + '?\n' 'this includes comprehensions and generator expressions since they ' 'are\n' 'implemented using a function scope. This means that the ' @@ -6435,7 +6422,7 @@ 'global\n' 'namespace; this should be a dictionary or a module (in the latter ' 'case\n' - "the module's dictionary is used). By default, when in the " + 'the module?s dictionary is used). By default, when in the ' '"__main__"\n' 'module, "__builtins__" is the built-in module "builtins"; when in ' 'any\n' @@ -6511,7 +6498,7 @@ '\n' 'Note that numeric literals do not include a sign; a phrase like ' '"-1"\n' - 'is actually an expression composed of the unary operator \'"-"\' ' + 'is actually an expression composed of the unary operator ?"-"? ' 'and the\n' 'literal "1".\n', 'numeric-types': 'Emulating numeric types\n' @@ -6601,15 +6588,15 @@ '"__rpow__()" (the\n' ' coercion rules would become too complicated).\n' '\n' - " Note: If the right operand's type is a subclass of the " + ' Note: If the right operand?s type is a subclass of the ' 'left\n' - " operand's type and that subclass provides the " + ' operand?s type and that subclass provides the ' 'reflected method\n' ' for the operation, this method will be called before ' 'the left\n' - " operand's non-reflected method. This behavior allows " + ' operand?s non-reflected method. This behavior allows ' 'subclasses\n' - " to override their ancestors' operations.\n" + ' to override their ancestors? operations.\n' '\n' 'object.__iadd__(self, other)\n' 'object.__isub__(self, other)\n' @@ -6647,7 +6634,7 @@ 'certain\n' ' situations, augmented assignment can result in ' 'unexpected errors\n' - " (see Why does a_tuple[i] += ['item'] raise an exception " + ' (see Why does a_tuple[i] += [?item?] raise an exception ' 'when the\n' ' addition works?), but this behavior is in fact part of ' 'the data\n' @@ -6709,18 +6696,18 @@ 'objects': 'Objects, values and types\n' '*************************\n' '\n' - "*Objects* are Python's abstraction for data. All data in a " + '*Objects* are Python?s abstraction for data. All data in a ' 'Python\n' 'program is represented by objects or by relations between ' 'objects. (In\n' - 'a sense, and in conformance to Von Neumann\'s model of a "stored\n' - 'program computer," code is also represented by objects.)\n' + 'a sense, and in conformance to Von Neumann?s model of a ?stored\n' + 'program computer,? code is also represented by objects.)\n' '\n' - "Every object has an identity, a type and a value. An object's\n" + 'Every object has an identity, a type and a value. An object?s\n' '*identity* never changes once it has been created; you may think ' 'of it\n' - 'as the object\'s address in memory. The \'"is"\' operator ' - 'compares the\n' + 'as the object?s address in memory. The ?"is"? operator compares ' + 'the\n' 'identity of two objects; the "id()" function returns an integer\n' 'representing its identity.\n' '\n' @@ -6728,14 +6715,14 @@ 'memory\n' 'address where "x" is stored.\n' '\n' - "An object's type determines the operations that the object " + 'An object?s type determines the operations that the object ' 'supports\n' - '(e.g., "does it have a length?") and also defines the possible ' + '(e.g., ?does it have a length??) and also defines the possible ' 'values\n' 'for objects of that type. The "type()" function returns an ' - "object's\n" + 'object?s\n' 'type (which is an object itself). Like its identity, an ' - "object's\n" + 'object?s\n' '*type* is also unchangeable. [1]\n' '\n' 'The *value* of some objects can change. Objects whose value can\n' @@ -6744,14 +6731,14 @@ 'once they are created are called *immutable*. (The value of an\n' 'immutable container object that contains a reference to a ' 'mutable\n' - "object can change when the latter's value is changed; however " + 'object can change when the latter?s value is changed; however ' 'the\n' 'container is still considered immutable, because the collection ' 'of\n' 'objects it contains cannot be changed. So, immutability is not\n' 'strictly the same as having an unchangeable value, it is more ' 'subtle.)\n' - "An object's mutability is determined by its type; for instance,\n" + 'An object?s mutability is determined by its type; for instance,\n' 'numbers, strings and tuples are immutable, while dictionaries ' 'and\n' 'lists are mutable.\n' @@ -6759,9 +6746,9 @@ 'Objects are never explicitly destroyed; however, when they ' 'become\n' 'unreachable they may be garbage-collected. An implementation is\n' - 'allowed to postpone garbage collection or omit it altogether --- ' - 'it is\n' - 'a matter of implementation quality how garbage collection is\n' + 'allowed to postpone garbage collection or omit it altogether ? it ' + 'is a\n' + 'matter of implementation quality how garbage collection is\n' 'implemented, as long as no objects are collected that are still\n' 'reachable.\n' '\n' @@ -6781,13 +6768,14 @@ '(so\n' 'you should always close files explicitly).\n' '\n' - "Note that the use of the implementation's tracing or debugging\n" + 'Note that the use of the implementation?s tracing or debugging\n' 'facilities may keep objects alive that would normally be ' 'collectable.\n' - 'Also note that catching an exception with a \'"try"..."except"\'\n' - 'statement may keep objects alive.\n' + 'Also note that catching an exception with a ?"try"?"except"? ' + 'statement\n' + 'may keep objects alive.\n' '\n' - 'Some objects contain references to "external" resources such as ' + 'Some objects contain references to ?external? resources such as ' 'open\n' 'files or windows. It is understood that these resources are ' 'freed\n' @@ -6798,14 +6786,13 @@ 'release the external resource, usually a "close()" method. ' 'Programs\n' 'are strongly recommended to explicitly close such objects. The\n' - '\'"try"..."finally"\' statement and the \'"with"\' statement ' - 'provide\n' + '?"try"?"finally"? statement and the ?"with"? statement provide\n' 'convenient ways to do this.\n' '\n' 'Some objects contain references to other objects; these are ' 'called\n' '*containers*. Examples of containers are tuples, lists and\n' - "dictionaries. The references are part of a container's value. " + 'dictionaries. The references are part of a container?s value. ' 'In\n' 'most cases, when we talk about the value of a container, we imply ' 'the\n' @@ -6862,7 +6849,7 @@ '| "lambda" | ' 'Lambda expression |\n' '+-------------------------------------------------+---------------------------------------+\n' - '| "if" -- "else" | ' + '| "if" ? "else" | ' 'Conditional expression |\n' '+-------------------------------------------------+---------------------------------------+\n' '| "or" | ' @@ -6945,7 +6932,7 @@ 'application.\n' '\n' '[2] If x is very close to an exact integer multiple of ' - "y, it's\n" + 'y, it?s\n' ' possible for "x//y" to be one larger than ' '"(x-x%y)//y" due to\n' ' rounding. In such cases, Python returns the latter ' @@ -6956,8 +6943,8 @@ '\n' '[3] The Unicode standard distinguishes between *code ' 'points* (e.g.\n' - ' U+0041) and *abstract characters* (e.g. "LATIN ' - 'CAPITAL LETTER A").\n' + ' U+0041) and *abstract characters* (e.g. ?LATIN ' + 'CAPITAL LETTER A?).\n' ' While most abstract characters in Unicode are only ' 'represented\n' ' using one code point, there is a number of abstract ' @@ -6965,8 +6952,8 @@ ' that can in addition be represented using a sequence ' 'of more than\n' ' one code point. For example, the abstract character ' - '"LATIN\n' - ' CAPITAL LETTER C WITH CEDILLA" can be represented as ' + '?LATIN\n' + ' CAPITAL LETTER C WITH CEDILLA? can be represented as ' 'a single\n' ' *precomposed character* at code position U+00C7, or ' 'as a sequence\n' @@ -6982,9 +6969,9 @@ 'to humans. For\n' ' example, ""\\u00C7" == "\\u0043\\u0327"" is "False", ' 'even though both\n' - ' strings represent the same abstract character "LATIN ' + ' strings represent the same abstract character ?LATIN ' 'CAPITAL\n' - ' LETTER C WITH CEDILLA".\n' + ' LETTER C WITH CEDILLA?.\n' '\n' ' To compare strings at the level of abstract ' 'characters (that is,\n' @@ -7014,10 +7001,11 @@ '\n' ' pass_stmt ::= "pass"\n' '\n' - '"pass" is a null operation --- when it is executed, nothing ' - 'happens.\n' - 'It is useful as a placeholder when a statement is required\n' - 'syntactically, but no code needs to be executed, for example:\n' + '"pass" is a null operation ? when it is executed, nothing happens. ' + 'It\n' + 'is useful as a placeholder when a statement is required ' + 'syntactically,\n' + 'but no code needs to be executed, for example:\n' '\n' ' def f(arg): pass # a function that does nothing (yet)\n' '\n' @@ -7073,7 +7061,7 @@ '"BaseException". If it is a class, the exception instance will be\n' 'obtained when needed by instantiating the class with no arguments.\n' '\n' - "The *type* of the exception is the exception instance's class, the\n" + 'The *type* of the exception is the exception instance?s class, the\n' '*value* is the instance itself.\n' '\n' 'A traceback object is normally created automatically when an ' @@ -7119,7 +7107,7 @@ 'inside\n' 'an exception handler or a "finally" clause: the previous exception ' 'is\n' - 'then attached as the new exception\'s "__context__" attribute:\n' + 'then attached as the new exception?s "__context__" attribute:\n' '\n' ' >>> try:\n' ' ... print(1 / 0)\n' @@ -7219,7 +7207,7 @@ '"clear()",\n' '"setdefault()", "pop()", "popitem()", "copy()", and ' '"update()"\n' - "behaving similar to those for Python's standard dictionary " + 'behaving similar to those for Python?s standard dictionary ' 'objects.\n' 'The "collections.abc" module provides a "MutableMapping" ' 'abstract base\n' @@ -7245,7 +7233,7 @@ 'the\n' '"__contains__()" method to allow efficient use of the "in" ' 'operator;\n' - 'for mappings, "in" should search the mapping\'s keys; for ' + 'for mappings, "in" should search the mapping?s keys; for ' 'sequences, it\n' 'should search through the values. It is further ' 'recommended that both\n' @@ -7263,7 +7251,7 @@ 'Should return\n' ' the length of the object, an integer ">=" 0. Also, an ' 'object that\n' - ' doesn\'t define a "__bool__()" method and whose ' + ' doesn?t define a "__bool__()" method and whose ' '"__len__()" method\n' ' returns zero is considered to be false in a Boolean ' 'context.\n' @@ -7420,7 +7408,7 @@ 'values or\n' ' the key-item pairs.\n' '\n' - ' For objects that don\'t define "__contains__()", the ' + ' For objects that don?t define "__contains__()", the ' 'membership test\n' ' first tries iteration via "__iter__()", then the old ' 'sequence\n' @@ -7508,7 +7496,7 @@ 'object.__dict__\n' '\n' ' A dictionary or other mapping object used to store an ' - "object's\n" + 'object?s\n' ' (writable) attributes.\n' '\n' 'instance.__class__\n' @@ -7568,15 +7556,15 @@ 'to\n' ' "[1.0, 2.0]", and similarly for tuples.\n' '\n' - "[3] They must have since the parser can't tell the type of " + '[3] They must have since the parser can?t tell the type of ' 'the\n' ' operands.\n' '\n' '[4] Cased characters are those with general category ' 'property\n' - ' being one of "Lu" (Letter, uppercase), "Ll" (Letter, ' + ' being one of ?Lu? (Letter, uppercase), ?Ll? (Letter, ' 'lowercase),\n' - ' or "Lt" (Letter, titlecase).\n' + ' or ?Lt? (Letter, titlecase).\n' '\n' '[5] To format only a tuple you should therefore provide a\n' ' singleton tuple whose only element is the tuple to be ' @@ -7588,7 +7576,7 @@ 'special\n' 'syntax (such as arithmetic operations or subscripting and ' 'slicing) by\n' - "defining methods with special names. This is Python's " + 'defining methods with special names. This is Python?s ' 'approach to\n' '*operator overloading*, allowing classes to define their own ' 'behavior\n' @@ -7622,7 +7610,7 @@ 'elements, but\n' 'extracting a slice may not make sense. (One example of this ' 'is the\n' - '"NodeList" interface in the W3C\'s Document Object Model.)\n' + '"NodeList" interface in the W3C?s Document Object Model.)\n' '\n' '\n' 'Basic customization\n' @@ -7646,7 +7634,7 @@ '\n' ' Typical implementations create a new instance of the ' 'class by\n' - ' invoking the superclass\'s "__new__()" method using\n' + ' invoking the superclass?s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' ' modifying the newly-created instance as necessary before ' @@ -7655,7 +7643,7 @@ '\n' ' If "__new__()" returns an instance of *cls*, then the ' 'new\n' - ' instance\'s "__init__()" method will be invoked like\n' + ' instance?s "__init__()" method will be invoked like\n' ' "__init__(self[, ...])", where *self* is the new instance ' 'and the\n' ' remaining arguments are the same as were passed to ' @@ -7663,7 +7651,7 @@ '\n' ' If "__new__()" does not return an instance of *cls*, then ' 'the new\n' - ' instance\'s "__init__()" method will not be invoked.\n' + ' instance?s "__init__()" method will not be invoked.\n' '\n' ' "__new__()" is intended mainly to allow subclasses of ' 'immutable\n' @@ -7681,7 +7669,7 @@ 'those\n' ' passed to the class constructor expression. If a base ' 'class has an\n' - ' "__init__()" method, the derived class\'s "__init__()" ' + ' "__init__()" method, the derived class?s "__init__()" ' 'method, if\n' ' any, must explicitly call it to ensure proper ' 'initialization of the\n' @@ -7702,8 +7690,8 @@ 'is also\n' ' called a finalizer or (improperly) a destructor. If a ' 'base class\n' - ' has a "__del__()" method, the derived class\'s ' - '"__del__()" method,\n' + ' has a "__del__()" method, the derived class?s "__del__()" ' + 'method,\n' ' if any, must explicitly call it to ensure proper deletion ' 'of the\n' ' base class part of the instance.\n' @@ -7723,11 +7711,11 @@ 'for\n' ' objects that still exist when the interpreter exits.\n' '\n' - ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' - 'the former\n' + ' Note: "del x" doesn?t directly call "x.__del__()" ? the ' + 'former\n' ' decrements the reference count for "x" by one, and the ' 'latter is\n' - ' only called when "x"\'s reference count reaches zero.\n' + ' only called when "x"?s reference count reaches zero.\n' '\n' ' **CPython implementation detail:** It is possible for a ' 'reference\n' @@ -7739,7 +7727,7 @@ 'reference\n' ' cycles is when an exception has been caught in a local ' 'variable.\n' - " The frame's locals then reference the exception, which " + ' The frame?s locals then reference the exception, which ' 'references\n' ' its own traceback, which references the locals of all ' 'frames caught\n' @@ -7785,7 +7773,7 @@ 'object.__repr__(self)\n' '\n' ' Called by the "repr()" built-in function to compute the ' - '"official"\n' + '?official?\n' ' string representation of an object. If at all possible, ' 'this\n' ' should look like a valid Python expression that could be ' @@ -7799,7 +7787,7 @@ ' value must be a string object. If a class defines ' '"__repr__()" but\n' ' not "__str__()", then "__repr__()" is also used when an ' - '"informal"\n' + '?informal?\n' ' string representation of instances of that class is ' 'required.\n' '\n' @@ -7811,7 +7799,7 @@ '\n' ' Called by "str(object)" and the built-in functions ' '"format()" and\n' - ' "print()" to compute the "informal" or nicely printable ' + ' "print()" to compute the ?informal? or nicely printable ' 'string\n' ' representation of an object. The return value must be a ' 'string\n' @@ -7839,7 +7827,7 @@ 'extension,\n' ' evaluation of formatted string literals and the ' '"str.format()"\n' - ' method, to produce a "formatted" string representation of ' + ' method, to produce a ?formatted? string representation of ' 'an\n' ' object. The "format_spec" argument is a string that ' 'contains a\n' @@ -7875,7 +7863,7 @@ 'object.__gt__(self, other)\n' 'object.__ge__(self, other)\n' '\n' - ' These are the so-called "rich comparison" methods. The\n' + ' These are the so-called ?rich comparison? methods. The\n' ' correspondence between operator symbols and method names ' 'is as\n' ' follows: "x=" 0. Also, an ' 'object that\n' - ' doesn\'t define a "__bool__()" method and whose ' + ' doesn?t define a "__bool__()" method and whose ' '"__len__()" method\n' ' returns zero is considered to be false in a Boolean ' 'context.\n' @@ -9117,7 +9105,7 @@ 'values or\n' ' the key-item pairs.\n' '\n' - ' For objects that don\'t define "__contains__()", the ' + ' For objects that don?t define "__contains__()", the ' 'membership test\n' ' first tries iteration via "__iter__()", then the old ' 'sequence\n' @@ -9213,15 +9201,15 @@ '"__rpow__()" (the\n' ' coercion rules would become too complicated).\n' '\n' - " Note: If the right operand's type is a subclass of the " + ' Note: If the right operand?s type is a subclass of the ' 'left\n' - " operand's type and that subclass provides the reflected " + ' operand?s type and that subclass provides the reflected ' 'method\n' ' for the operation, this method will be called before ' 'the left\n' - " operand's non-reflected method. This behavior allows " + ' operand?s non-reflected method. This behavior allows ' 'subclasses\n' - " to override their ancestors' operations.\n" + ' to override their ancestors? operations.\n' '\n' 'object.__iadd__(self, other)\n' 'object.__isub__(self, other)\n' @@ -9259,7 +9247,7 @@ 'certain\n' ' situations, augmented assignment can result in unexpected ' 'errors\n' - " (see Why does a_tuple[i] += ['item'] raise an exception " + ' (see Why does a_tuple[i] += [?item?] raise an exception ' 'when the\n' ' addition works?), but this behavior is in fact part of ' 'the data\n' @@ -9349,7 +9337,7 @@ '\n' ' Enter the runtime context related to this object. The ' '"with"\n' - " statement will bind this method's return value to the " + ' statement will bind this method?s return value to the ' 'target(s)\n' ' specified in the "as" clause of the statement, if any.\n' '\n' @@ -9373,11 +9361,11 @@ '\n' ' Note that "__exit__()" methods should not reraise the ' 'passed-in\n' - " exception; this is the caller's responsibility.\n" + ' exception; this is the caller?s responsibility.\n' '\n' 'See also:\n' '\n' - ' **PEP 343** - The "with" statement\n' + ' **PEP 343** - The ?with? statement\n' ' The specification, background, and examples for the ' 'Python "with"\n' ' statement.\n' @@ -9388,9 +9376,9 @@ '\n' 'For custom classes, implicit invocations of special methods ' 'are only\n' - "guaranteed to work correctly if defined on an object's type, " + 'guaranteed to work correctly if defined on an object?s type, ' 'not in\n' - "the object's instance dictionary. That behaviour is the " + 'the object?s instance dictionary. That behaviour is the ' 'reason why\n' 'the following code raises an exception:\n' '\n' @@ -9424,7 +9412,7 @@ '\n' 'Incorrectly attempting to invoke an unbound method of a ' 'class in this\n' - "way is sometimes referred to as 'metaclass confusion', and " + 'way is sometimes referred to as ?metaclass confusion?, and ' 'is avoided\n' 'by bypassing the instance when looking up special methods:\n' '\n' @@ -9437,7 +9425,7 @@ 'interest of\n' 'correctness, implicit special method lookup generally also ' 'bypasses\n' - 'the "__getattribute__()" method even of the object\'s ' + 'the "__getattribute__()" method even of the object?s ' 'metaclass:\n' '\n' ' >>> class Meta(type):\n' @@ -9717,11 +9705,11 @@ 'Alphabetic\n' ' characters are those characters defined in the Unicode ' 'character\n' - ' database as "Letter", i.e., those with general category ' + ' database as ?Letter?, i.e., those with general category ' 'property\n' - ' being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note ' + ' being one of ?Lm?, ?Lt?, ?Lu?, ?Ll?, or ?Lo?. Note ' 'that this is\n' - ' different from the "Alphabetic" property defined in the ' + ' different from the ?Alphabetic? property defined in the ' 'Unicode\n' ' Standard.\n' '\n' @@ -9745,7 +9733,7 @@ 'in base 10,\n' ' e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a ' 'decimal character\n' - ' is a character in the Unicode General Category "Nd".\n' + ' is a character in the Unicode General Category ?Nd?.\n' '\n' 'str.isdigit()\n' '\n' @@ -9804,7 +9792,7 @@ 'characters are\n' ' those characters defined in the Unicode character ' 'database as\n' - ' "Other" or "Separator", excepting the ASCII space ' + ' ?Other? or ?Separator?, excepting the ASCII space ' '(0x20) which is\n' ' considered printable. (Note that printable characters ' 'in this\n' @@ -9822,9 +9810,9 @@ 'Whitespace\n' ' characters are those characters defined in the Unicode ' 'character\n' - ' database as "Other" or "Separator" and those with ' + ' database as ?Other? or ?Separator? and those with ' 'bidirectional\n' - ' property being one of "WS", "B", or "S".\n' + ' property being one of ?WS?, ?B?, or ?S?.\n' '\n' 'str.istitle()\n' '\n' @@ -10282,9 +10270,9 @@ '"str.upper().isupper()" might be\n' ' "False" if "s" contains uncased characters or if the ' 'Unicode\n' - ' category of the resulting character(s) is not "Lu" ' + ' category of the resulting character(s) is not ?Lu? ' '(Letter,\n' - ' uppercase), but e.g. "Lt" (Letter, titlecase).\n' + ' uppercase), but e.g. ?Lt? (Letter, titlecase).\n' '\n' ' The uppercasing algorithm used is described in section ' '3.13 of the\n' @@ -10379,9 +10367,9 @@ 'literals,\n' '"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated ' 'specially.\n' - "Given that Python 2.x's raw unicode literals behave differently " + 'Given that Python 2.x?s raw unicode literals behave differently ' 'than\n' - 'Python 3.x\'s the "\'ur\'" syntax is not supported.\n' + 'Python 3.x?s the "\'ur\'" syntax is not supported.\n' '\n' 'New in version 3.3: The "\'rb\'" prefix of raw bytes literals has ' 'been\n' @@ -10405,7 +10393,7 @@ 'In triple-quoted literals, unescaped newlines and quotes are ' 'allowed\n' '(and are retained), except that three unescaped quotes in a row\n' - 'terminate the literal. (A "quote" is the character used to open ' + 'terminate the literal. (A ?quote? is the character used to open ' 'the\n' 'literal, i.e. either "\'" or """.)\n' '\n' @@ -10584,13 +10572,13 @@ 'item whose\n' 'index is that value (counting from zero). Since the support ' 'for\n' - "negative indices and slicing occurs in the object's " + 'negative indices and slicing occurs in the object?s ' '"__getitem__()"\n' 'method, subclasses overriding this method will need to ' 'explicitly add\n' 'that support.\n' '\n' - "A string's items are characters. A character is not a " + 'A string?s items are characters. A character is not a ' 'separate data\n' 'type but a string of exactly one character.\n', 'truth': 'Truth Value Testing\n' @@ -10647,7 +10635,7 @@ 'less except clause, if present, must be last; it matches any\n' 'exception. For an except clause with an expression, that expression\n' 'is evaluated, and the clause matches the exception if the resulting\n' - 'object is "compatible" with the exception. An object is compatible\n' + 'object is ?compatible? with the exception. An object is compatible\n' 'with an exception if it is the class or a base class of the ' 'exception\n' 'object or a tuple containing an item compatible with the exception.\n' @@ -10669,7 +10657,7 @@ 'When a matching except clause is found, the exception is assigned to\n' 'the target specified after the "as" keyword in that except clause, ' 'if\n' - "present, and the except clause's suite is executed. All except\n" + 'present, and the except clause?s suite is executed. All except\n' 'clauses must have an executable block. When the end of this block ' 'is\n' 'reached, execution continues normally after the entire try ' @@ -10699,7 +10687,7 @@ 'cycle with the stack frame, keeping all locals in that frame alive\n' 'until the next garbage collection occurs.\n' '\n' - "Before an except clause's suite is executed, details about the\n" + 'Before an except clause?s suite is executed, details about the\n' 'exception are stored in the "sys" module and can be accessed via\n' '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of ' 'the\n' @@ -10713,7 +10701,7 @@ 'the end of the "try" clause. [2] Exceptions in the "else" clause are\n' 'not handled by the preceding "except" clauses.\n' '\n' - 'If "finally" is present, it specifies a \'cleanup\' handler. The ' + 'If "finally" is present, it specifies a ?cleanup? handler. The ' '"try"\n' 'clause is executed, including any "except" and "else" clauses. If ' 'an\n' @@ -10741,12 +10729,10 @@ 'execution of the "finally" clause.\n' '\n' 'When a "return", "break" or "continue" statement is executed in the\n' - '"try" suite of a "try"..."finally" statement, the "finally" clause ' - 'is\n' - 'also executed \'on the way out.\' A "continue" statement is illegal ' - 'in\n' + '"try" suite of a "try"?"finally" statement, the "finally" clause is\n' + 'also executed ?on the way out.? A "continue" statement is illegal in\n' 'the "finally" clause. (The reason is a problem with the current\n' - 'implementation --- this restriction may be lifted in the future).\n' + 'implementation ? this restriction may be lifted in the future).\n' '\n' 'The return value of a function is determined by the last "return"\n' 'statement executed. Since the "finally" clause always executes, a\n' @@ -10781,7 +10767,7 @@ 'will often be provided via the standard library instead.\n' '\n' 'Some of the type descriptions below contain a paragraph listing\n' - "'special attributes.' These are attributes that provide access to " + '?special attributes.? These are attributes that provide access to ' 'the\n' 'implementation and are not intended for general use. Their ' 'definition\n' @@ -10794,7 +10780,7 @@ 'It\n' ' is used to signify the absence of a value in many situations, ' 'e.g.,\n' - " it is returned from functions that don't explicitly return\n" + ' it is returned from functions that don?t explicitly return\n' ' anything. Its truth value is false.\n' '\n' 'NotImplemented\n' @@ -10845,7 +10831,7 @@ 'shift\n' ' and mask operations, a binary representation is assumed, ' 'and\n' - " negative numbers are represented in a variant of 2's\n" + ' negative numbers are represented in a variant of 2?s\n' ' complement which gives the illusion of an infinite string ' 'of\n' ' sign bits extending to the left.\n' @@ -10899,7 +10885,7 @@ 'items\n' ' of a sequence. When the length of a sequence is *n*, the index ' 'set\n' - ' contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence *a* ' + ' contains the numbers 0, 1, ?, *n*-1. Item *i* of sequence *a* ' 'is\n' ' selected by "a[i]".\n' '\n' @@ -10909,8 +10895,8 @@ 'implies\n' ' that the index set is renumbered so that it starts at 0.\n' '\n' - ' Some sequences also support "extended slicing" with a third ' - '"step"\n' + ' Some sequences also support ?extended slicing? with a third ' + '?step?\n' ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' 'where\n' ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' @@ -10935,7 +10921,7 @@ 'code\n' ' points. All the code points in the range "U+0000 - ' 'U+10FFFF"\n' - " can be represented in a string. Python doesn't have a " + ' can be represented in a string. Python doesn?t have a ' '"char"\n' ' type; instead, every code point in the string is ' 'represented\n' @@ -10954,7 +10940,7 @@ ' The items of a tuple are arbitrary Python objects. Tuples ' 'of\n' ' two or more items are formed by comma-separated lists of\n' - " expressions. A tuple of one item (a 'singleton') can be\n" + ' expressions. A tuple of one item (a ?singleton?) can be\n' ' formed by affixing a comma to an expression (an expression ' 'by\n' ' itself does not create a tuple, since parentheses must be\n' @@ -11060,7 +11046,7 @@ 'object\n' ' identity, the reason being that the efficient implementation ' 'of\n' - " dictionaries requires a key's hash value to remain constant.\n" + ' dictionaries requires a key?s hash value to remain constant.\n' ' Numeric types used for keys obey the normal rules for ' 'numeric\n' ' comparison: if two numbers compare equal (e.g., "1" and ' @@ -11085,7 +11071,7 @@ ' definition (see section Function definitions). It should be\n' ' called with an argument list containing the same number of ' 'items\n' - " as the function's formal parameter list.\n" + ' as the function?s formal parameter list.\n' '\n' ' Special attributes:\n' '\n' @@ -11095,8 +11081,8 @@ '| |\n' ' ' '+===========================+=================================+=============+\n' - ' | "__doc__" | The function\'s ' - 'documentation | Writable |\n' + ' | "__doc__" | The function?s documentation ' + '| Writable |\n' ' | | string, or "None" if ' '| |\n' ' | | unavailable; not inherited by ' @@ -11105,12 +11091,12 @@ '| |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function\'s ' - 'name | Writable |\n' + ' | "__name__" | The function?s name ' + '| Writable |\n' ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function\'s *qualified ' - 'name* | Writable |\n' + ' | "__qualname__" | The function?s *qualified name* ' + '| Writable |\n' ' | | New in version 3.3. ' '| |\n' ' ' @@ -11143,9 +11129,9 @@ '+---------------------------+---------------------------------+-------------+\n' ' | "__globals__" | A reference to the dictionary ' '| Read-only |\n' - " | | that holds the function's " + ' | | that holds the function?s ' '| |\n' - ' | | global variables --- the global ' + ' | | global variables ? the global ' '| |\n' ' | | namespace of the module in ' '| |\n' @@ -11163,7 +11149,7 @@ '| Read-only |\n' ' | | contain bindings for the ' '| |\n' - " | | function's free variables. See " + ' | | function?s free variables. See ' '| |\n' ' | | below for information on the ' '| |\n' @@ -11190,7 +11176,7 @@ ' ' '+---------------------------+---------------------------------+-------------+\n' '\n' - ' Most of the attributes labelled "Writable" check the type of ' + ' Most of the attributes labelled ?Writable? check the type of ' 'the\n' ' assigned value.\n' '\n' @@ -11209,7 +11195,7 @@ ' A cell object has the attribute "cell_contents". This can be\n' ' used to get the value of the cell, as well as set the value.\n' '\n' - " Additional information about a function's definition can be\n" + ' Additional information about a function?s definition can be\n' ' retrieved from its code object; see the description of ' 'internal\n' ' types below.\n' @@ -11222,7 +11208,7 @@ ' Special read-only attributes: "__self__" is the class ' 'instance\n' ' object, "__func__" is the function object; "__doc__" is the\n' - ' method\'s documentation (same as "__func__.__doc__"); ' + ' method?s documentation (same as "__func__.__doc__"); ' '"__name__"\n' ' is the method name (same as "__func__.__name__"); ' '"__module__"\n' @@ -11246,7 +11232,7 @@ 'instances,\n' ' its "__self__" attribute is the instance, and the method ' 'object\n' - ' is said to be bound. The new method\'s "__func__" attribute ' + ' is said to be bound. The new method?s "__func__" attribute ' 'is\n' ' the original function object.\n' '\n' @@ -11279,7 +11265,7 @@ '\n' ' When an instance method object is derived from a class ' 'method\n' - ' object, the "class instance" stored in "__self__" will ' + ' object, the ?class instance? stored in "__self__" will ' 'actually\n' ' be the class itself, so that calling either "x.f(1)" or ' '"C.f(1)"\n' @@ -11312,7 +11298,7 @@ 'object\n' ' which can be used to execute the body of the function: ' 'calling\n' - ' the iterator\'s "iterator.__next__()" method will cause the\n' + ' the iterator?s "iterator.__next__()" method will cause the\n' ' function to execute until it provides a value using the ' '"yield"\n' ' statement. When the function executes a "return" statement ' @@ -11341,7 +11327,7 @@ 'for"\n' ' statement to execute the body of the function.\n' '\n' - ' Calling the asynchronous iterator\'s "aiterator.__anext__()"\n' + ' Calling the asynchronous iterator?s "aiterator.__anext__()"\n' ' method will return an *awaitable* which when awaited will\n' ' execute until it provides a value using the "yield" ' 'expression.\n' @@ -11360,9 +11346,9 @@ 'of\n' ' the arguments are determined by the C function. Special ' 'read-\n' - ' only attributes: "__doc__" is the function\'s documentation\n' + ' only attributes: "__doc__" is the function?s documentation\n' ' string, or "None" if unavailable; "__name__" is the ' - "function's\n" + 'function?s\n' ' name; "__self__" is set to "None" (but see the next item);\n' ' "__module__" is the name of the module the function was ' 'defined\n' @@ -11405,16 +11391,16 @@ ' translated to lookups in this dictionary, e.g., "m.x" is ' 'equivalent\n' ' to "m.__dict__["x"]". A module object does not contain the code\n' - " object used to initialize the module (since it isn't needed " + ' object used to initialize the module (since it isn?t needed ' 'once\n' ' the initialization is done).\n' '\n' - " Attribute assignment updates the module's namespace dictionary,\n" + ' Attribute assignment updates the module?s namespace dictionary,\n' ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Predefined (writable) attributes: "__name__" is the module\'s ' + ' Predefined (writable) attributes: "__name__" is the module?s ' 'name;\n' - ' "__doc__" is the module\'s documentation string, or "None" if\n' + ' "__doc__" is the module?s documentation string, or "None" if\n' ' unavailable; "__annotations__" (optional) is a dictionary\n' ' containing *variable annotations* collected during module body\n' ' execution; "__file__" is the pathname of the file from which ' @@ -11427,7 +11413,7 @@ 'is\n' ' the pathname of the shared library file.\n' '\n' - ' Special read-only attribute: "__dict__" is the module\'s ' + ' Special read-only attribute: "__dict__" is the module?s ' 'namespace\n' ' as a dictionary object.\n' '\n' @@ -11456,7 +11442,7 @@ ' classes. This search of the base classes uses the C3 method\n' ' resolution order which behaves correctly even in the presence ' 'of\n' - " 'diamond' inheritance structures where there are multiple\n" + ' ?diamond? inheritance structures where there are multiple\n' ' inheritance paths leading back to a common ancestor. Additional\n' ' details on the C3 MRO used by Python can be found in the\n' ' documentation accompanying the 2.3 release at\n' @@ -11475,7 +11461,7 @@ 'differ\n' ' from those actually contained in its "__dict__".\n' '\n' - " Class attribute assignments update the class's dictionary, " + ' Class attribute assignments update the class?s dictionary, ' 'never\n' ' the dictionary of a base class.\n' '\n' @@ -11487,11 +11473,11 @@ 'is\n' ' the module name in which the class was defined; "__dict__" is ' 'the\n' - ' dictionary containing the class\'s namespace; "__bases__" is a ' + ' dictionary containing the class?s namespace; "__bases__" is a ' 'tuple\n' ' containing the base classes, in the order of their occurrence ' 'in\n' - ' the base class list; "__doc__" is the class\'s documentation ' + ' the base class list; "__doc__" is the class?s documentation ' 'string,\n' ' or "None" if undefined; "__annotations__" (optional) is a\n' ' dictionary containing *variable annotations* collected during ' @@ -11504,7 +11490,7 @@ ' A class instance has a namespace implemented as a dictionary ' 'which\n' ' is the first place in which attribute references are searched.\n' - " When an attribute is not found there, and the instance's class " + ' When an attribute is not found there, and the instance?s class ' 'has\n' ' an attribute by that name, the search continues with the class\n' ' attributes. If a class attribute is found that is a ' @@ -11513,17 +11499,17 @@ 'object\n' ' whose "__self__" attribute is the instance. Static method and\n' ' class method objects are also transformed; see above under\n' - ' "Classes". See section Implementing Descriptors for another way ' + ' ?Classes?. See section Implementing Descriptors for another way ' 'in\n' ' which attributes of a class retrieved via its instances may ' 'differ\n' - ' from the objects actually stored in the class\'s "__dict__". If ' + ' from the objects actually stored in the class?s "__dict__". If ' 'no\n' - " class attribute is found, and the object's class has a\n" + ' class attribute is found, and the object?s class has a\n' ' "__getattr__()" method, that is called to satisfy the lookup.\n' '\n' - " Attribute assignments and deletions update the instance's\n" - " dictionary, never a class's dictionary. If the class has a\n" + ' Attribute assignments and deletions update the instance?s\n' + ' dictionary, never a class?s dictionary. If the class has a\n' ' "__setattr__()" or "__delattr__()" method, this is called ' 'instead\n' ' of updating the instance dictionary directly.\n' @@ -11534,7 +11520,7 @@ ' Special method names.\n' '\n' ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance\'s class.\n' + ' "__class__" is the instance?s class.\n' '\n' 'I/O objects (also known as file objects)\n' ' A *file object* represents an open file. Various shortcuts are\n' @@ -11546,7 +11532,7 @@ ' provided by extension modules).\n' '\n' ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - " initialized to file objects corresponding to the interpreter's\n" + ' initialized to file objects corresponding to the interpreter?s\n' ' standard input, output and error streams; they are all open in ' 'text\n' ' mode and therefore follow the interface defined by the\n' @@ -11564,7 +11550,7 @@ ' or *bytecode*. The difference between a code object and a\n' ' function object is that the function object contains an ' 'explicit\n' - " reference to the function's globals (the module in which it " + ' reference to the function?s globals (the module in which it ' 'was\n' ' defined), while a code object contains no context; also the\n' ' default argument values are stored in the function object, ' @@ -11667,13 +11653,12 @@ ' undefined interpreter behaviour if exceptions raised by the\n' ' trace function escape to the function being traced.\n' '\n' - ' "f_lineno" is the current line number of the frame --- ' - 'writing\n' - ' to this from within a trace function jumps to the given line\n' - ' (only for the bottom-most frame). A debugger can implement ' - 'a\n' - ' Jump command (aka Set Next Statement) by writing to ' - 'f_lineno.\n' + ' "f_lineno" is the current line number of the frame ? writing ' + 'to\n' + ' this from within a trace function jumps to the given line ' + '(only\n' + ' for the bottom-most frame). A debugger can implement a Jump\n' + ' command (aka Set Next Statement) by writing to f_lineno.\n' '\n' ' Frame objects support one method:\n' '\n' @@ -11799,7 +11784,7 @@ ' is retrieved from classes and class instances. The behaviour ' 'of\n' ' class method objects upon such retrieval is described above,\n' - ' under "User-defined methods". Class method objects are ' + ' under ?User-defined methods?. Class method objects are ' 'created\n' ' by the built-in "classmethod()" constructor.\n', 'typesfunctions': 'Functions\n' @@ -11819,8 +11804,8 @@ 'different object types.\n' '\n' 'See Function definitions for more information.\n', - 'typesmapping': 'Mapping Types --- "dict"\n' - '************************\n' + 'typesmapping': 'Mapping Types ? "dict"\n' + '**********************\n' '\n' 'A *mapping* object maps *hashable* values to arbitrary ' 'objects.\n' @@ -11831,7 +11816,7 @@ 'in "list", "set", and "tuple" classes, and the "collections" ' 'module.)\n' '\n' - "A dictionary's keys are *almost* arbitrary values. Values " + 'A dictionary?s keys are *almost* arbitrary values. Values ' 'that are\n' 'not *hashable*, that is, values containing lists, ' 'dictionaries or\n' @@ -12007,13 +11992,13 @@ '\n' ' items()\n' '\n' - ' Return a new view of the dictionary\'s items ("(key, ' + ' Return a new view of the dictionary?s items ("(key, ' 'value)"\n' ' pairs). See the documentation of view objects.\n' '\n' ' keys()\n' '\n' - " Return a new view of the dictionary's keys. See the\n" + ' Return a new view of the dictionary?s keys. See the\n' ' documentation of view objects.\n' '\n' ' pop(key[, default])\n' @@ -12061,14 +12046,14 @@ '\n' ' values()\n' '\n' - " Return a new view of the dictionary's values. See " + ' Return a new view of the dictionary?s values. See ' 'the\n' ' documentation of view objects.\n' '\n' ' Dictionaries compare equal if and only if they have the ' 'same "(key,\n' - ' value)" pairs. Order comparisons (\'<\', \'<=\', \'>=\', ' - "'>') raise\n" + ' value)" pairs. Order comparisons (?=?, ?>?) ' + 'raise\n' ' "TypeError".\n' '\n' 'See also: "types.MappingProxyType" can be used to create a ' @@ -12082,7 +12067,7 @@ 'The objects returned by "dict.keys()", "dict.values()" and\n' '"dict.items()" are *view objects*. They provide a dynamic ' 'view on the\n' - "dictionary's entries, which means that when the dictionary " + 'dictionary?s entries, which means that when the dictionary ' 'changes,\n' 'the view reflects these changes.\n' '\n' @@ -12100,31 +12085,26 @@ '(represented as\n' ' tuples of "(key, value)") in the dictionary.\n' '\n' - ' Keys and values are iterated over in an arbitrary order ' - 'which is\n' - ' non-random, varies across Python implementations, and ' - 'depends on\n' - " the dictionary's history of insertions and deletions. If " - 'keys,\n' - ' values and items views are iterated over with no ' - 'intervening\n' - ' modifications to the dictionary, the order of items will ' - 'directly\n' - ' correspond. This allows the creation of "(value, key)" ' - 'pairs using\n' - ' "zip()": "pairs = zip(d.values(), d.keys())". Another ' - 'way to\n' - ' create the same list is "pairs = [(v, k) for (k, v) in ' - 'd.items()]".\n' + ' Keys and values are iterated over in insertion order. ' + 'This allows\n' + ' the creation of "(value, key)" pairs using "zip()": ' + '"pairs =\n' + ' zip(d.values(), d.keys())". Another way to create the ' + 'same list is\n' + ' "pairs = [(v, k) for (k, v) in d.items()]".\n' '\n' ' Iterating views while adding or deleting entries in the ' 'dictionary\n' ' may raise a "RuntimeError" or fail to iterate over all ' 'entries.\n' '\n' + ' Changed in version 3.7: Dict order is guaranteed to be ' + 'insertion\n' + ' order.\n' + '\n' 'x in dictview\n' '\n' - ' Return "True" if *x* is in the underlying dictionary\'s ' + ' Return "True" if *x* is in the underlying dictionary?s ' 'keys, values\n' ' or items (in the latter case, *x* should be a "(key, ' 'value)"\n' @@ -12158,10 +12138,10 @@ ' >>> print(n)\n' ' 504\n' '\n' - ' >>> # keys and values are iterated over in the same ' - 'order\n' + ' >>> # keys and values are iterated over in the same order ' + '(insertion order)\n' ' >>> list(keys)\n' - " ['eggs', 'bacon', 'sausage', 'spam']\n" + " ['eggs', 'sausage', 'bacon', 'spam']\n" ' >>> list(values)\n' ' [2, 1, 1, 500]\n' '\n' @@ -12169,7 +12149,7 @@ " >>> del dishes['eggs']\n" " >>> del dishes['sausage']\n" ' >>> list(keys)\n' - " ['spam', 'bacon']\n" + " ['bacon', 'spam']\n" '\n' ' >>> # set operations\n' " >>> keys & {'eggs', 'bacon', 'salad'}\n" @@ -12239,7 +12219,7 @@ 'The only special operation on a module is attribute access: ' '"m.name",\n' 'where *m* is a module and *name* accesses a name defined in ' - "*m*'s\n" + '*m*?s\n' 'symbol table. Module attributes can be assigned to. (Note ' 'that the\n' '"import" statement is not, strictly speaking, an operation ' @@ -12252,14 +12232,14 @@ '\n' 'A special attribute of every module is "__dict__". This is ' 'the\n' - "dictionary containing the module's symbol table. Modifying " + 'dictionary containing the module?s symbol table. Modifying ' 'this\n' - "dictionary will actually change the module's symbol table, " + 'dictionary will actually change the module?s symbol table, ' 'but direct\n' 'assignment to the "__dict__" attribute is not possible (you ' 'can write\n' '"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but ' - "you can't\n" + 'you can?t\n' 'write "m.__dict__ = {}"). Modifying "__dict__" directly is ' 'not\n' 'recommended.\n' @@ -12270,8 +12250,8 @@ 'written as\n' '"".\n', - 'typesseq': 'Sequence Types --- "list", "tuple", "range"\n' - '*******************************************\n' + 'typesseq': 'Sequence Types ? "list", "tuple", "range"\n' + '*****************************************\n' '\n' 'There are three basic sequence types: lists, tuples, and range\n' 'objects. Additional sequence types tailored for processing of ' @@ -12445,7 +12425,7 @@ '*j* are\n' ' reduced to "len(s) - 1" if they are greater. If *i* or *j* ' 'are\n' - ' omitted or "None", they become "end" values (which end ' + ' omitted or "None", they become ?end? values (which end ' 'depends on\n' ' the sign of *k*). Note, *k* cannot be zero. If *k* is ' '"None", it\n' @@ -12476,7 +12456,7 @@ 'documentation\n' '\n' '7. Some sequence types (such as "range") only support item\n' - " sequences that follow specific patterns, and hence don't " + ' sequences that follow specific patterns, and hence don?t ' 'support\n' ' sequence concatenation or repetition.\n' '\n' @@ -12633,7 +12613,7 @@ ' sequence.\n' '\n' '5. "clear()" and "copy()" are included for consistency with the\n' - " interfaces of mutable containers that don't support slicing\n" + ' interfaces of mutable containers that don?t support slicing\n' ' operations (such as "dict" and "set")\n' '\n' ' New in version 3.3: "clear()" and "copy()" methods.\n' @@ -12673,7 +12653,7 @@ '\n' ' The constructor builds a list whose items are the same and in ' 'the\n' - " same order as *iterable*'s items. *iterable* may be either " + ' same order as *iterable*?s items. *iterable* may be either ' 'a\n' ' sequence, a container that supports iteration, or an ' 'iterator\n' @@ -12740,8 +12720,8 @@ 'is\n' ' stable if it guarantees not to change the relative order ' 'of\n' - ' elements that compare equal --- this is helpful for ' - 'sorting in\n' + ' elements that compare equal ? this is helpful for sorting ' + 'in\n' ' multiple passes (for example, sort by department, then by ' 'salary\n' ' grade).\n' @@ -12787,7 +12767,7 @@ '\n' ' The constructor builds a tuple whose items are the same and ' 'in the\n' - " same order as *iterable*'s items. *iterable* may be either " + ' same order as *iterable*?s items. *iterable* may be either ' 'a\n' ' sequence, a container that supports iteration, or an ' 'iterator\n' @@ -12916,7 +12896,7 @@ 'Range objects implement the "collections.abc.Sequence" ABC, and\n' 'provide features such as containment tests, element index ' 'lookup,\n' - 'slicing and support for negative indices (see Sequence Types --- ' + 'slicing and support for negative indices (see Sequence Types ? ' 'list,\n' 'tuple, range):\n' '\n' @@ -12954,7 +12934,7 @@ 'constant\n' 'time instead of iterating through all items.\n' '\n' - "Changed in version 3.3: Define '==' and '!=' to compare range " + 'Changed in version 3.3: Define ?==? and ?!=? to compare range ' 'objects\n' 'based on the sequence of values they define (instead of ' 'comparing\n' @@ -13093,7 +13073,7 @@ '\n' '5. "clear()" and "copy()" are included for consistency ' 'with the\n' - " interfaces of mutable containers that don't support " + ' interfaces of mutable containers that don?t support ' 'slicing\n' ' operations (such as "dict" and "set")\n' '\n' @@ -13148,7 +13128,7 @@ '\n' 'A "break" statement executed in the first suite terminates the ' 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' + 'without executing the "else" clause?s suite. A "continue" ' 'statement\n' 'executed in the first suite skips the rest of the suite and goes ' 'back\n' @@ -13158,21 +13138,22 @@ '\n' 'The "with" statement is used to wrap the execution of a block with\n' 'methods defined by a context manager (see section With Statement\n' - 'Context Managers). This allows common "try"..."except"..."finally"\n' - 'usage patterns to be encapsulated for convenient reuse.\n' + 'Context Managers). This allows common "try"?"except"?"finally" ' + 'usage\n' + 'patterns to be encapsulated for convenient reuse.\n' '\n' ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' ' with_item ::= expression ["as" target]\n' '\n' - 'The execution of the "with" statement with one "item" proceeds as\n' + 'The execution of the "with" statement with one ?item? proceeds as\n' 'follows:\n' '\n' '1. The context expression (the expression given in the "with_item")\n' ' is evaluated to obtain a context manager.\n' '\n' - '2. The context manager\'s "__exit__()" is loaded for later use.\n' + '2. The context manager?s "__exit__()" is loaded for later use.\n' '\n' - '3. The context manager\'s "__enter__()" method is invoked.\n' + '3. The context manager?s "__enter__()" method is invoked.\n' '\n' '4. If a target was included in the "with" statement, the return\n' ' value from "__enter__()" is assigned to it.\n' @@ -13186,7 +13167,7 @@ '\n' '5. The suite is executed.\n' '\n' - '6. The context manager\'s "__exit__()" method is invoked. If an\n' + '6. The context manager?s "__exit__()" method is invoked. If an\n' ' exception caused the suite to be exited, its type, value, and\n' ' traceback are passed as arguments to "__exit__()". Otherwise, ' 'three\n' @@ -13222,7 +13203,7 @@ '\n' 'See also:\n' '\n' - ' **PEP 343** - The "with" statement\n' + ' **PEP 343** - The ?with? statement\n' ' The specification, background, and examples for the Python ' '"with"\n' ' statement.\n', diff --git a/Misc/NEWS.d/3.7.0b4.rst b/Misc/NEWS.d/3.7.0b4.rst new file mode 100644 index 000000000000..a6cae2819182 --- /dev/null +++ b/Misc/NEWS.d/3.7.0b4.rst @@ -0,0 +1,466 @@ +.. bpo: 33363 +.. date: 2018-04-26-22-48-28 +.. nonce: 8RCnN2 +.. release date: 2018-05-02 +.. section: Core and Builtins + +Raise a SyntaxError for ``async with`` and ``async for`` statements outside +of async functions. + +.. + +.. bpo: 33128 +.. date: 2018-04-24-22-31-04 +.. nonce: g2yLuf +.. section: Core and Builtins + +Fix a bug that causes PathFinder to appear twice on sys.meta_path. Patch by +Pablo Galindo Salgado. + +.. + +.. bpo: 33312 +.. date: 2018-04-19-08-30-07 +.. nonce: mDe2iL +.. section: Core and Builtins + +Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by +adjusting how the internal struct _dictkeysobject shared keys structure is +declared. + +.. + +.. bpo: 33231 +.. date: 2018-04-05-22-20-44 +.. nonce: 3Jmo0q +.. section: Core and Builtins + +Fix potential memory leak in ``normalizestring()``. + +.. + +.. bpo: 33205 +.. date: 2018-04-03-00-58-41 +.. nonce: lk2F3r +.. section: Core and Builtins + +Change dict growth function from +``round_up_to_power_2(used*2+hashtable_size/2)`` to +``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when +``used == 0``. Now dict has more chance to be shrinked. + +.. + +.. bpo: 29922 +.. date: 2018-04-03-00-30-25 +.. nonce: CdLuMl +.. section: Core and Builtins + +Improved error messages in 'async with' when ``__aenter__()`` or +``__aexit__()`` return non-awaitable object. + +.. + +.. bpo: 33199 +.. date: 2018-04-02-09-32-40 +.. nonce: TPnxQu +.. section: Core and Builtins + +Fix ``ma_version_tag`` in dict implementation is uninitialized when copying +from key-sharing dict. + +.. + +.. bpo: 33281 +.. date: 2018-05-01-22-35-50 +.. nonce: d4jOt4 +.. section: Library + +Fix ctypes.util.find_library regression on macOS. + +.. + +.. bpo: 33383 +.. date: 2018-04-29-11-15-38 +.. nonce: g32YWn +.. section: Library + +Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when +it is called with a single argument. + +.. + +.. bpo: 33329 +.. date: 2018-04-23-13-21-39 +.. nonce: lQ-Eod +.. section: Library + +Fix multiprocessing regression on newer glibcs + +.. + +.. bpo: 991266 +.. date: 2018-04-21-00-24-08 +.. nonce: h93TP_ +.. section: Library + +Fix quoting of the ``Comment`` attribute of +:class:`http.cookies.SimpleCookie`. + +.. + +.. bpo: 33131 +.. date: 2018-04-20-10-43-17 +.. nonce: L2E977 +.. section: Library + +Upgrade bundled version of pip to 10.0.1. + +.. + +.. bpo: 33308 +.. date: 2018-04-18-19-12-25 +.. nonce: fW75xi +.. section: Library + +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. + +.. + +.. bpo: 33266 +.. date: 2018-04-16-15-59-21 +.. nonce: w2PAm- +.. section: Library + +lib2to3 now recognizes ``rf'...'`` strings. + +.. + +.. bpo: 11594 +.. date: 2018-04-16-08-42-03 +.. nonce: QLo4vv +.. section: Library + +Ensure line-endings are respected when using lib2to3. + +.. + +.. bpo: 33254 +.. date: 2018-04-13-15-14-47 +.. nonce: DS4KFK +.. section: Library + +Have :func:`importlib.resources.contents` and +:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` +instead of an :term:`iterator`. + +.. + +.. bpo: 33256 +.. date: 2018-04-10-20-57-14 +.. nonce: ndHkqu +.. section: Library + +Fix display of ```` call in the html produced by ``cgitb.html()``. +Patch by St?phane Blondon. + +.. + +.. bpo: 33185 +.. date: 2018-04-08-22-54-07 +.. nonce: Id-Ba9 +.. section: Library + +Fixed regression when running pydoc with the :option:`-m` switch. (The +regression was introduced in 3.7.0b3 by the resolution of :issue:`33053`) + +This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` when +necessary, rather than adding ``"."``. + +.. + +.. bpo: 33169 +.. date: 2018-04-06-14-56-26 +.. nonce: ByhDqb +.. section: Library + +Delete entries of ``None`` in :data:`sys.path_importer_cache` when +:meth:`importlib.machinery.invalidate_caches` is called. + +.. + +.. bpo: 33217 +.. date: 2018-04-05-13-36-09 +.. nonce: FfOKDI +.. section: Library + +Deprecate looking up non-Enum objects in Enum classes and Enum members (will +raise :exc:`TypeError` in 3.8+). + +.. + +.. bpo: 33203 +.. date: 2018-04-05-11-09-45 +.. nonce: Hje9Py +.. section: Library + +``random.Random.choice()`` now raises ``IndexError`` for empty sequences +consistently even when called from subclasses without a ``getrandbits()`` +implementation. + +.. + +.. bpo: 33224 +.. date: 2018-04-04-23-41-30 +.. nonce: pyR0jB +.. section: Library + +Update difflib.mdiff() for PEP 479. Convert an uncaught StopIteration in a +generator into a return-statement. + +.. + +.. bpo: 33209 +.. date: 2018-04-03-10-37-13 +.. nonce: 9sGWE_ +.. section: Library + +End framing at the end of C implementation of :func:`pickle.Pickler.dump`. + +.. + +.. bpo: 20104 +.. date: 2018-04-01-19-21-04 +.. nonce: -AKcGa +.. section: Library + +Improved error handling and fixed a reference leak in +:func:`os.posix_spawn()`. + +.. + +.. bpo: 33175 +.. date: 2018-03-29-04-32-25 +.. nonce: _zs1yM +.. section: Library + +In dataclasses, Field.__set_name__ now looks up the __set_name__ special +method on the class, not the instance, of the default value. + +.. + +.. bpo: 33097 +.. date: 2018-03-18-16-48-23 +.. nonce: Yl4gI2 +.. section: Library + +Raise RuntimeError when ``executor.submit`` is called during interpreter +shutdown. + +.. + +.. bpo: 31908 +.. date: 2017-10-31 +.. nonce: g4xh8x +.. section: Library + +Fix output of cover files for ``trace`` module command-line tool. Previously +emitted cover files only when ``--missing`` option was used. Patch by +Michael Selik. + +.. + +.. bpo: 33378 +.. date: 2018-04-29-04-02-18 +.. nonce: -anAHN +.. section: Documentation + +Add Korean language switcher for https://docs.python.org/3/ + +.. + +.. bpo: 33276 +.. date: 2018-04-20-14-09-36 +.. nonce: rA1z_3 +.. section: Documentation + +Clarify that the ``__path__`` attribute on modules cannot be just any value. + +.. + +.. bpo: 33201 +.. date: 2018-04-01-21-03-41 +.. nonce: aa8Lkl +.. section: Documentation + +Modernize documentation for writing C extension types. + +.. + +.. bpo: 33195 +.. date: 2018-04-01-14-30-36 +.. nonce: dRS-XX +.. section: Documentation + +Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` +related APIs are deprecated since Python 3.3, but it is missed in the +document. + +.. + +.. bpo: 8243 +.. date: 2018-01-13-20-30-53 +.. nonce: s98r28 +.. section: Documentation + +Add a note about curses.addch and curses.addstr exception behavior when +writing outside a window, or pad. + +.. + +.. bpo: 32337 +.. date: 2017-12-22-17-29-37 +.. nonce: eZe-ID +.. section: Documentation + +Update documentation related with ``dict`` order. + +.. + +.. bpo: 33358 +.. date: 2018-04-27-11-46-35 +.. nonce: _OcR59 +.. section: Tests + +Fix ``test_embed.test_pre_initialization_sys_options()`` when the +interpreter is built with ``--enable-shared``. + +.. + +.. bpo: 33394 +.. date: 2018-04-30-17-36-46 +.. nonce: _Vdi4t +.. section: Build + +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. + +.. + +.. bpo: 33393 +.. date: 2018-04-30-17-19-37 +.. nonce: HkVCqI +.. section: Build + +Update config.guess and config.sub files. + +.. + +.. bpo: 33377 +.. date: 2018-04-30-16-53-00 +.. nonce: QBh6vP +.. section: Build + +Add new triplets for mips r6 and riscv variants (used in extension +suffixes). + +.. + +.. bpo: 32232 +.. date: 2018-04-17-00-38-19 +.. nonce: o7G_UO +.. section: Build + +By default, modules configured in `Modules/Setup` are no longer built with +`-DPy_BUILD_CORE`. Instead, modules that specifically need that preprocessor +definition include it in their individual entries. + +.. + +.. bpo: 33182 +.. date: 2018-03-30-14-55-48 +.. nonce: CePczb +.. section: Build + +The embedding tests can once again be built with clang 6.0 + +.. + +.. bpo: 33184 +.. date: 2018-04-13-11-28-55 +.. nonce: 7YhqQE +.. section: Windows + +Update Windows installer to use OpenSSL 1.1.0h. + +.. + +.. bpo: 33184 +.. date: 2018-04-07-00-51-34 +.. nonce: 3j208P +.. section: macOS + +Update macOS installer build to use OpenSSL 1.1.0h. + +.. + +.. bpo: 21474 +.. date: 2018-04-29-16-13-02 +.. nonce: bglg-F +.. section: IDLE + +Update word/identifier definition from ascii to unicode. In text and entry +boxes, this affects selection by double-click, movement left/right by +control-left/right, and deletion left/right by control-BACKSPACE/DEL. + +.. + +.. bpo: 33204 +.. date: 2018-04-02-00-28-13 +.. nonce: NBsuIv +.. section: IDLE + +IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot +be paired with either 'r' or 'f'. Consistently color as much of the prefix, +starting at the right, as is valid. Revise and extend colorizer test. + +.. + +.. bpo: 33189 +.. date: 2018-04-03-18-10-00 +.. nonce: QrXR00 +.. section: Tools/Demos + +:program:`pygettext.py` now recognizes only literal strings as docstrings +and translatable strings, and rejects bytes literals and f-string +expressions. + +.. + +.. bpo: 31920 +.. date: 2018-03-26-18-54-24 +.. nonce: u_WKsT +.. section: Tools/Demos + +Fixed handling directories as arguments in the ``pygettext`` script. Based +on patch by Oleg Krasnikov. + +.. + +.. bpo: 29673 +.. date: 2018-03-16-17-25-05 +.. nonce: m8QtaW +.. section: Tools/Demos + +Fix pystackv and pystack gdbinit macros. + +.. + +.. bpo: 31583 +.. date: 2017-09-26-10-11-21 +.. nonce: TM90_H +.. section: Tools/Demos + +Fix 2to3 for using with --add-suffix option but without --output-dir option +for relative path to files in current directory. diff --git a/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst b/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst deleted file mode 100644 index 6310e5d5b557..000000000000 --- a/Misc/NEWS.d/next/Build/2018-03-30-14-55-48.bpo-33182.CePczb.rst +++ /dev/null @@ -1 +0,0 @@ -The embedding tests can once again be built with clang 6.0 diff --git a/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst b/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst deleted file mode 100644 index fea0b60fcedd..000000000000 --- a/Misc/NEWS.d/next/Build/2018-04-17-00-38-19.bpo-32232.o7G_UO.rst +++ /dev/null @@ -1,3 +0,0 @@ -By default, modules configured in `Modules/Setup` are no longer built with -`-DPy_BUILD_CORE`. Instead, modules that specifically need that preprocessor -definition include it in their individual entries. diff --git a/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst b/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst deleted file mode 100644 index f5dbd23c7c35..000000000000 --- a/Misc/NEWS.d/next/Build/2018-04-30-16-53-00.bpo-33377.QBh6vP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add new triplets for mips r6 and riscv variants (used in extension -suffixes). diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst deleted file mode 100644 index f3317e7e68f3..000000000000 --- a/Misc/NEWS.d/next/Build/2018-04-30-17-19-37.bpo-33393.HkVCqI.rst +++ /dev/null @@ -1 +0,0 @@ -Update config.guess and config.sub files. diff --git a/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst b/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst deleted file mode 100644 index b25fbb02c406..000000000000 --- a/Misc/NEWS.d/next/Build/2018-04-30-17-36-46.bpo-33394._Vdi4t.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enable the verbose build for extension modules, when GNU make is passed -macros on the command line. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst deleted file mode 100644 index 22abf8d00011..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-02-09-32-40.bpo-33199.TPnxQu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``ma_version_tag`` in dict implementation is uninitialized when copying -from key-sharing dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst deleted file mode 100644 index d8c144e59d6c..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-30-25.bpo-29922.CdLuMl.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improved error messages in 'async with' when ``__aenter__()`` or -``__aexit__()`` return non-awaitable object. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst deleted file mode 100644 index 44511865abfa..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-03-00-58-41.bpo-33205.lk2F3r.rst +++ /dev/null @@ -1,3 +0,0 @@ -Change dict growth function from ``round_up_to_power_2(used*2+hashtable_size/2)`` to -``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when ``used == 0``. -Now dict has more chance to be shrinked. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst deleted file mode 100644 index de54fbb52671..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-05-22-20-44.bpo-33231.3Jmo0q.rst +++ /dev/null @@ -1 +0,0 @@ -Fix potential memory leak in ``normalizestring()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst deleted file mode 100644 index 40b51b902c9f..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-19-08-30-07.bpo-33312.mDe2iL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by -adjusting how the internal struct _dictkeysobject shared keys structure is -declared. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst deleted file mode 100644 index 66b98cdf51cf..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-24-22-31-04.bpo-33128.g2yLuf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that causes PathFinder to appear twice on sys.meta_path. Patch by -Pablo Galindo Salgado. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst deleted file mode 100644 index ad8d24895343..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-04-26-22-48-28.bpo-33363.8RCnN2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise a SyntaxError for ``async with`` and ``async for`` statements outside -of async functions. diff --git a/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst b/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst deleted file mode 100644 index a905467cd59f..000000000000 --- a/Misc/NEWS.d/next/Documentation/2017-12-22-17-29-37.bpo-32337.eZe-ID.rst +++ /dev/null @@ -1 +0,0 @@ -Update documentation related with ``dict`` order. diff --git a/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst b/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst deleted file mode 100644 index a3520d05c095..000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-01-13-20-30-53.bpo-8243.s98r28.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a note about curses.addch and curses.addstr exception behavior when -writing outside a window, or pad. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst b/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst deleted file mode 100644 index 6884640325b0..000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-04-01-14-30-36.bpo-33195.dRS-XX.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` -related APIs are deprecated since Python 3.3, but it is missed in the -document. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst b/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst deleted file mode 100644 index bdee48ba0314..000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-04-01-21-03-41.bpo-33201.aa8Lkl.rst +++ /dev/null @@ -1 +0,0 @@ -Modernize documentation for writing C extension types. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst b/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst deleted file mode 100644 index 0da58a0ce4c8..000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-04-20-14-09-36.bpo-33276.rA1z_3.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify that the ``__path__`` attribute on modules cannot be just any value. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst b/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst deleted file mode 100644 index 43214d10b7c5..000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-04-29-04-02-18.bpo-33378.-anAHN.rst +++ /dev/null @@ -1 +0,0 @@ -Add Korean language switcher for https://docs.python.org/3/ diff --git a/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst b/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst deleted file mode 100644 index 3ae937bab930..000000000000 --- a/Misc/NEWS.d/next/IDLE/2018-04-02-00-28-13.bpo-33204.NBsuIv.rst +++ /dev/null @@ -1,3 +0,0 @@ -IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot -be paired with either 'r' or 'f'. Consistently color as much of the prefix, -starting at the right, as is valid. Revise and extend colorizer test. diff --git a/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst b/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst deleted file mode 100644 index caf640b73b29..000000000000 --- a/Misc/NEWS.d/next/IDLE/2018-04-29-16-13-02.bpo-21474.bglg-F.rst +++ /dev/null @@ -1,3 +0,0 @@ -Update word/identifier definition from ascii to unicode. In text and entry -boxes, this affects selection by double-click, movement left/right by -control-left/right, and deletion left/right by control-BACKSPACE/DEL. diff --git a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst b/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst deleted file mode 100644 index 700bc690764f..000000000000 --- a/Misc/NEWS.d/next/Library/2017-10-31.bpo-31908.g4xh8x.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix output of cover files for ``trace`` module command-line tool. -Previously emitted cover files only when ``--missing`` option was used. -Patch by Michael Selik. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst b/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst deleted file mode 100644 index d9411eb51623..000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-18-16-48-23.bpo-33097.Yl4gI2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise RuntimeError when ``executor.submit`` is called during interpreter -shutdown. diff --git a/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst b/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst deleted file mode 100644 index c872499cd679..000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-29-04-32-25.bpo-33175._zs1yM.rst +++ /dev/null @@ -1,2 +0,0 @@ -In dataclasses, Field.__set_name__ now looks up the __set_name__ special -method on the class, not the instance, of the default value. diff --git a/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst b/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst deleted file mode 100644 index 150401dc7412..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-01-19-21-04.bpo-20104.-AKcGa.rst +++ /dev/null @@ -1 +0,0 @@ -Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`. diff --git a/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst b/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst deleted file mode 100644 index d98b1e174e55..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-03-10-37-13.bpo-33209.9sGWE_.rst +++ /dev/null @@ -1 +0,0 @@ -End framing at the end of C implementation of :func:`pickle.Pickler.dump`. diff --git a/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst b/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst deleted file mode 100644 index 87ff100da4b6..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-04-23-41-30.bpo-33224.pyR0jB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update difflib.mdiff() for PEP 479. Convert an uncaught StopIteration in a -generator into a return-statement. diff --git a/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst b/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst deleted file mode 100644 index ab6d17b5d1ba..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-05-11-09-45.bpo-33203.Hje9Py.rst +++ /dev/null @@ -1,3 +0,0 @@ -``random.Random.choice()`` now raises ``IndexError`` for empty sequences -consistently even when called from subclasses without a ``getrandbits()`` -implementation. diff --git a/Misc/NEWS.d/next/Library/2018-04-05-13-36-09.bpo-33217.FfOKDI.rst b/Misc/NEWS.d/next/Library/2018-04-05-13-36-09.bpo-33217.FfOKDI.rst deleted file mode 100644 index 8dfc9e5a15c0..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-05-13-36-09.bpo-33217.FfOKDI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate looking up non-Enum objects in Enum classes and Enum members (will -raise :exc:`TypeError` in 3.8+). diff --git a/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst b/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst deleted file mode 100644 index b5bacfcb5732..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-06-14-56-26.bpo-33169.ByhDqb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Delete entries of ``None`` in :data:`sys.path_importer_cache` when -:meth:`importlib.machinery.invalidate_caches` is called. diff --git a/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst b/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst deleted file mode 100644 index 1f51d7e5120d..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-08-22-54-07.bpo-33185.Id-Ba9.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed regression when running pydoc with the :option:`-m` switch. (The regression -was introduced in 3.7.0b3 by the resolution of :issue:`33053`) - -This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` when -necessary, rather than adding ``"."``. diff --git a/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst b/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst deleted file mode 100644 index a0605c04b4de..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-10-20-57-14.bpo-33256.ndHkqu.rst +++ /dev/null @@ -1 +0,0 @@ -Fix display of ```` call in the html produced by ``cgitb.html()``. Patch by St?phane Blondon. diff --git a/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst b/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst deleted file mode 100644 index c77a902524b8..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Have :func:`importlib.resources.contents` and -:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` instead -of an :term:`iterator`. diff --git a/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst b/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst deleted file mode 100644 index be2abf6c34dd..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-16-08-42-03.bpo-11594.QLo4vv.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure line-endings are respected when using lib2to3. diff --git a/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst b/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst deleted file mode 100644 index 6c93c48b8886..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-16-15-59-21.bpo-33266.w2PAm-.rst +++ /dev/null @@ -1 +0,0 @@ -lib2to3 now recognizes ``rf'...'`` strings. diff --git a/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst b/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst deleted file mode 100644 index 586004a3c6c9..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-18-19-12-25.bpo-33308.fW75xi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a crash in the :mod:`parser` module when converting an ST object to a -tree of tuples or lists with ``line_info=False`` and ``col_info=True``. diff --git a/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst b/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst deleted file mode 100644 index 875c6ac5f742..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-20-10-43-17.bpo-33131.L2E977.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade bundled version of pip to 10.0.1. diff --git a/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst b/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst deleted file mode 100644 index 3af6c27cf21d..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-21-00-24-08.bpo-991266.h93TP_.rst +++ /dev/null @@ -1 +0,0 @@ -Fix quoting of the ``Comment`` attribute of :class:`http.cookies.SimpleCookie`. diff --git a/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst b/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst deleted file mode 100644 index d1a4e56d04b9..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-23-13-21-39.bpo-33329.lQ-Eod.rst +++ /dev/null @@ -1 +0,0 @@ -Fix multiprocessing regression on newer glibcs diff --git a/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst b/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst deleted file mode 100644 index 7b65baac97bf..000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-29-11-15-38.bpo-33383.g32YWn.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when -it is called with a single argument. diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst deleted file mode 100644 index ad08caa70b63..000000000000 --- a/Misc/NEWS.d/next/Library/2018-05-01-22-35-50.bpo-33281.d4jOt4.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ctypes.util.find_library regression on macOS. diff --git a/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst b/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst deleted file mode 100644 index 89406e994a91..000000000000 --- a/Misc/NEWS.d/next/Tests/2018-04-27-11-46-35.bpo-33358._OcR59.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``test_embed.test_pre_initialization_sys_options()`` when the interpreter -is built with ``--enable-shared``. diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst b/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst deleted file mode 100644 index 472f61c5129e..000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2017-09-26-10-11-21.bpo-31583.TM90_H.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix 2to3 for using with --add-suffix option but without --output-dir -option for relative path to files in current directory. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst b/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst deleted file mode 100644 index 3d515b3ee4db..000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2018-03-16-17-25-05.bpo-29673.m8QtaW.rst +++ /dev/null @@ -1 +0,0 @@ -Fix pystackv and pystack gdbinit macros. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst b/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst deleted file mode 100644 index 39c694b0728d..000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2018-03-26-18-54-24.bpo-31920.u_WKsT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed handling directories as arguments in the ``pygettext`` script. Based -on patch by Oleg Krasnikov. diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst b/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst deleted file mode 100644 index 4d4137240e61..000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2018-04-03-18-10-00.bpo-33189.QrXR00.rst +++ /dev/null @@ -1,2 +0,0 @@ -:program:`pygettext.py` now recognizes only literal strings as docstrings -and translatable strings, and rejects bytes literals and f-string expressions. diff --git a/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst b/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst deleted file mode 100644 index ca47a9811088..000000000000 --- a/Misc/NEWS.d/next/Windows/2018-04-13-11-28-55.bpo-33184.7YhqQE.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows installer to use OpenSSL 1.1.0h. diff --git a/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst b/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst deleted file mode 100644 index 03308ed6a72b..000000000000 --- a/Misc/NEWS.d/next/macOS/2018-04-07-00-51-34.bpo-33184.3j208P.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer build to use OpenSSL 1.1.0h. diff --git a/README.rst b/README.rst index fcd23442d766..68bc5712d4c3 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.7.0 beta 3+ -==================================== +This is Python version 3.7.0 beta 4 +=================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI diff --git a/configure b/configure index 2ab9bc8eff2a..f1f01df4a80e 100755 --- a/configure +++ b/configure @@ -781,7 +781,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -894,7 +893,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1147,15 +1145,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1293,7 +1282,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1446,7 +1435,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] From webhook-mailer at python.org Wed May 2 05:01:57 2018 From: webhook-mailer at python.org (Ned Deily) Date: Wed, 02 May 2018 09:01:57 -0000 Subject: [Python-checkins] bump to 3.7.0b4+ Message-ID: https://github.com/python/cpython/commit/01e19f8fedb1e02476c4e42d387829135c9e76a1 commit: 01e19f8fedb1e02476c4e42d387829135c9e76a1 branch: 3.7 author: Ned Deily committer: Ned Deily date: 2018-05-02T05:01:31-04:00 summary: bump to 3.7.0b4+ files: M Include/patchlevel.h M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index c01b8f98fe51..d7bd1d394454 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 4 /* Version as a string */ -#define PY_VERSION "3.7.0b4" +#define PY_VERSION "3.7.0b4+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/README.rst b/README.rst index 68bc5712d4c3..ffa9631b0287 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.7.0 beta 4 -=================================== +This is Python version 3.7.0 beta 4+ +==================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI From solipsis at pitrou.net Wed May 2 05:18:16 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 02 May 2018 09:18:16 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=2 Message-ID: <20180502091816.1.B3151F097246F63D@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, -7, 8] memory blocks, sum=1 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [0, 0, -2] memory blocks, sum=-2 test_multiprocessing_forkserver leaked [1, 0, -2] memory blocks, sum=-1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogY5Ysth', '--timeout', '7200'] From webhook-mailer at python.org Wed May 2 05:29:20 2018 From: webhook-mailer at python.org (INADA Naoki) Date: Wed, 02 May 2018 09:29:20 -0000 Subject: [Python-checkins] bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) Message-ID: https://github.com/python/cpython/commit/491bbedc209fea314a04cb3015da68fb0aa63238 commit: 491bbedc209fea314a04cb3015da68fb0aa63238 branch: master author: lekma committer: INADA Naoki date: 2018-05-02T18:29:10+09:00 summary: bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) files: A Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst M Objects/setobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst new file mode 100644 index 000000000000..ab17aa408c06 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst @@ -0,0 +1 @@ +Fix a leak in set_symmetric_difference(). diff --git a/Objects/setobject.c b/Objects/setobject.c index 80101dda9bee..82b583820816 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1744,8 +1744,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other) if (otherset == NULL) return NULL; rv = set_symmetric_difference_update(otherset, (PyObject *)so); - if (rv == NULL) + if (rv == NULL) { + Py_DECREF(otherset); return NULL; + } Py_DECREF(rv); return (PyObject *)otherset; } From webhook-mailer at python.org Wed May 2 05:50:51 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 02 May 2018 09:50:51 -0000 Subject: [Python-checkins] bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) Message-ID: https://github.com/python/cpython/commit/6a56790e0b50846f1f968e48c3a321c148b5e6cd commit: 6a56790e0b50846f1f968e48c3a321c148b5e6cd branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-02T02:50:48-07:00 summary: bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) (cherry picked from commit 491bbedc209fea314a04cb3015da68fb0aa63238) Co-authored-by: lekma files: A Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst M Objects/setobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst new file mode 100644 index 000000000000..ab17aa408c06 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst @@ -0,0 +1 @@ +Fix a leak in set_symmetric_difference(). diff --git a/Objects/setobject.c b/Objects/setobject.c index 47db6b245ca6..ce35aa2a0cdb 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1744,8 +1744,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other) if (otherset == NULL) return NULL; rv = set_symmetric_difference_update(otherset, (PyObject *)so); - if (rv == NULL) + if (rv == NULL) { + Py_DECREF(otherset); return NULL; + } Py_DECREF(rv); return (PyObject *)otherset; } From webhook-mailer at python.org Wed May 2 06:12:23 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 02 May 2018 10:12:23 -0000 Subject: [Python-checkins] bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) Message-ID: https://github.com/python/cpython/commit/d5546991a2123b6ec84f7c4ecf37b62bedd78ea4 commit: d5546991a2123b6ec84f7c4ecf37b62bedd78ea4 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-02T03:12:18-07:00 summary: bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) (cherry picked from commit 491bbedc209fea314a04cb3015da68fb0aa63238) Co-authored-by: lekma files: A Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst M Objects/setobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst new file mode 100644 index 000000000000..ab17aa408c06 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst @@ -0,0 +1 @@ +Fix a leak in set_symmetric_difference(). diff --git a/Objects/setobject.c b/Objects/setobject.c index c742041b16de..96485f83ecb6 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1740,8 +1740,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other) if (otherset == NULL) return NULL; rv = set_symmetric_difference_update(otherset, (PyObject *)so); - if (rv == NULL) + if (rv == NULL) { + Py_DECREF(otherset); return NULL; + } Py_DECREF(rv); return (PyObject *)otherset; } From webhook-mailer at python.org Wed May 2 06:23:44 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 02 May 2018 10:23:44 -0000 Subject: [Python-checkins] bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) Message-ID: https://github.com/python/cpython/commit/6d3d02c69a65abcd64eb6d83baac5675f9208318 commit: 6d3d02c69a65abcd64eb6d83baac5675f9208318 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-02T03:23:41-07:00 summary: bpo-33391: Fix refleak in set_symmetric_difference (GH-6670) (cherry picked from commit 491bbedc209fea314a04cb3015da68fb0aa63238) Co-authored-by: lekma files: A Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst M Objects/setobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst new file mode 100644 index 000000000000..ab17aa408c06 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-02-08-36-03.bpo-33391.z4a7rb.rst @@ -0,0 +1 @@ +Fix a leak in set_symmetric_difference(). diff --git a/Objects/setobject.c b/Objects/setobject.c index 154be43564dd..31da3dbfecb1 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1710,8 +1710,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other) if (otherset == NULL) return NULL; rv = set_symmetric_difference_update(otherset, (PyObject *)so); - if (rv == NULL) + if (rv == NULL) { + Py_DECREF(otherset); return NULL; + } Py_DECREF(rv); return (PyObject *)otherset; } From solipsis at pitrou.net Thu May 3 05:14:13 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 03 May 2018 09:14:13 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=3 Message-ID: <20180503091413.1.1CA64F40A943263E@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 7, -7] memory blocks, sum=0 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [1, 0, -2] memory blocks, sum=-1 test_multiprocessing_forkserver leaked [-2, 2, 0] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogIS9exp', '--timeout', '7200'] From lp_benchmark_robot at intel.com Thu May 3 22:03:47 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 3 May 2018 19:03:47 -0700 Subject: [Python-checkins] [4 down, 2 up, 59 flat] Results for Python (master branch) 2018-05-03 Message-ID: <919d6a19-1b58-4168-91cf-f496304e4ef3@orsmsx110.amr.corp.intel.com> Results for project python/master, build date: 2018-05-03 09:54:21-07:00. - commit: 491bbed - previous commit: ffa2c3e - revision date: 2018-05-02 18:29:10+09:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.604% | +0.323% | +8.224% | +7.450% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.990% | -0.957% | +23.763% | +11.188% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 0.784% | -0.574% | +25.540% | +10.648% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 0.931% | +0.317% | +23.691% | +9.424% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.217% | +0.093% | +9.806% | +13.235% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.792% | -0.744% | +11.770% | +10.896% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.658% | +1.501% | +8.875% | +10.071% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.540% | -0.289% | -1.804% | +8.906% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 1.963% | +1.328% | +12.382% | +16.495% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 2.860% | -1.348% | +20.707% | +14.374% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.267% | -0.245% | +5.167% | +7.040% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 1.889% | +0.219% | +6.296% | +6.243% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.116% | +0.362% | +2.862% | +7.049% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.353% | -1.002% | +13.589% | +10.084% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.634% | +0.305% | +10.918% | +9.895% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 6.492% | -1.296% | +3.931% | +12.477% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 1.047% | -0.189% | +11.161% | +11.903% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 2.981% | -2.272% | +10.624% | +10.552% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.987% | +1.024% | +2.411% | +10.113% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 3.707% | -2.412% | -5.860% | +17.526% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.455% | -2.209% | +17.476% | +12.552% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.245% | +0.662% | +48.179% | +11.925% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.882% | -2.724% | +11.692% | +13.947% | +-----+------------------------+--------+------------+------------+------------+ | :-( | mako| 0.497% | -2.383% | +15.412% | +16.005% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 7.469% | -5.390% | +4.360% | +14.952% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 1.821% | -0.966% | +4.551% | +5.788% | +-----+------------------------+--------+------------+------------+------------+ | :-( | nbody| 0.630% | -2.392% | -2.148% | +3.096% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 1.181% | -1.248% | +4.652% | +7.971% | +-----+------------------------+--------+------------+------------+------------+ | :-( | pathlib| 1.344% | -4.060% | -1.311% | +12.306% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.273% | -1.459% | +0.289% | +23.186% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.265% | +1.442% | +4.349% | +22.412% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.738% | +2.135% | +5.651% | +19.920% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 8.390% | -4.324% | +8.311% | +14.957% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.119% | +0.032% | +0.209% | +10.132% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.114% | +0.324% | +18.340% | +5.728% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.081% | +0.326% | +5.343% | +5.687% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.900% | -0.313% | +10.484% | +13.883% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.336% | -4.503% | +1.318% | +13.095% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.207% | +0.236% | -2.013% | +13.177% | +-----+------------------------+--------+------------+------------+------------+ | :-) | regex_effbot| 2.351% | +6.075% | -2.699% | +4.460% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 1.068% | -0.498% | +3.409% | +6.371% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 0.926% | -0.703% | +9.817% | +15.323% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 2.089% | -0.409% | -3.160% | +5.168% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 3.020% | -0.825% | +22.611% | +11.885% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.239% | -0.393% | +4.395% | +4.353% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 2.219% | -1.129% | +13.447% | +11.238% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 0.671% | +1.221% | -5.803% | -0.931% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.835% | +0.663% | +3.568% | +6.081% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.340% | -0.236% | +6.721% | +6.072% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.812% | -0.690% | +7.800% | +5.342% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 3.436% | -0.258% | +0.797% | +9.067% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 3.573% | -0.775% | +16.839% | +7.393% | +-----+------------------------+--------+------------+------------+------------+ | :-) | sympy_integrate| 1.439% | +5.631% | +17.668% | +6.658% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 4.970% | -0.299% | +17.931% | +7.933% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.487% | -1.295% | +15.089% | +10.686% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 5.019% | -3.672% | +18.772% | +9.009% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 1.395% | -0.813% | +7.006% | +6.692% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.875% | +0.143% | +2.206% | -0.451% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 4.430% | -0.522% | +8.467% | +22.050% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 2.107% | -2.513% | -3.916% | +15.242% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 2.266% | -3.098% | +5.647% | +9.247% | +-----+------------------------+--------+------------+------------+------------+ | :-( | xml_etree_generate| 0.969% | -3.292% | +2.015% | +12.701% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.438% | -0.385% | +2.578% | +8.268% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 3.199% | -2.171% | -9.094% | +10.813% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.170% | -2.347% | +3.953% | +11.540% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/4-down-2-up-59-flat-results-for-python-master-branch-2018-05-03 Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From solipsis at pitrou.net Fri May 4 05:08:58 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 04 May 2018 09:08:58 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=3 Message-ID: <20180504090858.1.3A40D3CEBAEBD918@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [-2, 2, -1] memory blocks, sum=-1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogqyCwLI', '--timeout', '7200'] From webhook-mailer at python.org Fri May 4 07:01:03 2018 From: webhook-mailer at python.org (Antoine Pitrou) Date: Fri, 04 May 2018 11:01:03 -0000 Subject: [Python-checkins] bpo-33332: Add signal.valid_signals() (GH-6581) Message-ID: https://github.com/python/cpython/commit/9d3627e311211a1b4abcda29c36fe4afe2c46532 commit: 9d3627e311211a1b4abcda29c36fe4afe2c46532 branch: master author: Antoine Pitrou committer: GitHub date: 2018-05-04T13:00:50+02:00 summary: bpo-33332: Add signal.valid_signals() (GH-6581) files: A Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst M Doc/library/signal.rst M Lib/asyncio/unix_events.py M Lib/multiprocessing/resource_sharer.py M Lib/signal.py M Lib/test/support/__init__.py M Lib/test/test_asyncio/test_unix_events.py M Lib/test/test_signal.py M Modules/clinic/signalmodule.c.h M Modules/signalmodule.c M aclocal.m4 M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 3f17e08f0f95..67ee979dc0e0 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -216,6 +216,15 @@ The :mod:`signal` module defines the following functions: .. versionadded:: 3.8 +.. function:: valid_signals() + + Return the set of valid signal numbers on this platform. This can be + less than ``range(1, NSIG)`` if some signals are reserved by the system + for internal use. + + .. versionadded:: 3.8 + + .. function:: pause() Cause the process to sleep until a signal is received; the appropriate handler @@ -268,8 +277,8 @@ The :mod:`signal` module defines the following functions: argument. *mask* is a set of signal numbers (e.g. {:const:`signal.SIGINT`, - :const:`signal.SIGTERM`}). Use ``range(1, signal.NSIG)`` for a full mask - including all signals. + :const:`signal.SIGTERM`}). Use :func:`~signal.valid_signals` for a full + mask including all signals. For example, ``signal.pthread_sigmask(signal.SIG_BLOCK, [])`` reads the signal mask of the calling thread. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 6cac137cacb3..f64037a25c67 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -167,8 +167,8 @@ def _check_signal(self, sig): if not isinstance(sig, int): raise TypeError(f'sig must be an int, not {sig!r}') - if not (1 <= sig < signal.NSIG): - raise ValueError(f'sig {sig} out of range(1, {signal.NSIG})') + if sig not in signal.valid_signals(): + raise ValueError(f'invalid signal number {sig}') def _make_read_pipe_transport(self, pipe, protocol, waiter=None, extra=None): diff --git a/Lib/multiprocessing/resource_sharer.py b/Lib/multiprocessing/resource_sharer.py index 6d99da102ffc..730b2aa17bdf 100644 --- a/Lib/multiprocessing/resource_sharer.py +++ b/Lib/multiprocessing/resource_sharer.py @@ -136,7 +136,7 @@ def _start(self): def _serve(self): if hasattr(signal, 'pthread_sigmask'): - signal.pthread_sigmask(signal.SIG_BLOCK, range(1, signal.NSIG)) + signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) while 1: try: with self._listener.accept() as conn: diff --git a/Lib/signal.py b/Lib/signal.py index 9f05c9198df7..826b62cf596c 100644 --- a/Lib/signal.py +++ b/Lib/signal.py @@ -65,8 +65,7 @@ def pthread_sigmask(how, mask): if 'sigpending' in _globals: @_wraps(_signal.sigpending) def sigpending(): - sigs = _signal.sigpending() - return set(_int_to_enum(x, Signals) for x in sigs) + return {_int_to_enum(x, Signals) for x in _signal.sigpending()} if 'sigwait' in _globals: @@ -76,4 +75,11 @@ def sigwait(sigset): return _int_to_enum(retsig, Signals) sigwait.__doc__ = _signal.sigwait + +if 'valid_signals' in _globals: + @_wraps(_signal.valid_signals) + def valid_signals(): + return {_int_to_enum(x, Signals) for x in _signal.valid_signals()} + + del _globals, _wraps diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a5f86d4c4176..f1c4c952eff3 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2810,7 +2810,7 @@ class SaveSignals: def __init__(self): import signal self.signal = signal - self.signals = list(range(1, signal.NSIG)) + self.signals = signal.valid_signals() # SIGKILL and SIGSTOP signals cannot be ignored nor caught for signame in ('SIGKILL', 'SIGSTOP'): try: diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 104f99593797..a01efedf66d9 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -69,6 +69,7 @@ def test_handle_signal_cancelled_handler(self): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_setup_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals m_signal.set_wakeup_fd.side_effect = ValueError self.assertRaises( @@ -96,6 +97,7 @@ def test_add_signal_handler_coroutine_error(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals cb = lambda: True self.loop.add_signal_handler(signal.SIGHUP, cb) @@ -106,6 +108,7 @@ def test_add_signal_handler(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_install_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals def set_wakeup_fd(fd): if fd == -1: @@ -125,6 +128,7 @@ class Err(OSError): @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error2(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals class Err(OSError): errno = errno.EINVAL @@ -145,6 +149,7 @@ class Err(OSError): errno = errno.EINVAL m_signal.signal.side_effect = Err m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.assertRaises( RuntimeError, @@ -156,6 +161,7 @@ class Err(OSError): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -170,6 +176,7 @@ def test_remove_signal_handler(self, m_signal): def test_remove_signal_handler_2(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.SIGINT = signal.SIGINT + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGINT, lambda: True) self.loop._signal_handlers[signal.SIGHUP] = object() @@ -187,6 +194,7 @@ def test_remove_signal_handler_2(self, m_signal): @mock.patch('asyncio.base_events.logger') def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) m_signal.set_wakeup_fd.side_effect = ValueError @@ -197,6 +205,7 @@ def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) m_signal.signal.side_effect = OSError @@ -207,6 +216,7 @@ def test_remove_signal_handler_error(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error2(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) class Err(OSError): @@ -219,6 +229,7 @@ class Err(OSError): @mock.patch('asyncio.unix_events.signal') def test_close(self, m_signal): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) self.loop.add_signal_handler(signal.SIGCHLD, lambda: True) @@ -236,6 +247,7 @@ def test_close(self, m_signal): @mock.patch('asyncio.unix_events.signal') def test_close_on_finalizing(self, m_signal, m_sys): m_signal.NSIG = signal.NSIG + m_signal.valid_signals = signal.valid_signals self.loop.add_signal_handler(signal.SIGHUP, lambda: True) self.assertEqual(len(self.loop._signal_handlers), 1) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 7635eec148d8..7ce89f61ab3e 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -67,9 +67,28 @@ def test_interprocess_signal(self): script = os.path.join(dirname, 'signalinterproctester.py') assert_python_ok(script) + def test_valid_signals(self): + s = signal.valid_signals() + self.assertIsInstance(s, set) + self.assertIn(signal.Signals.SIGINT, s) + self.assertIn(signal.Signals.SIGALRM, s) + self.assertNotIn(0, s) + self.assertNotIn(signal.NSIG, s) + self.assertLess(len(s), signal.NSIG) + @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): + + def test_valid_signals(self): + s = signal.valid_signals() + self.assertIsInstance(s, set) + self.assertGreaterEqual(len(s), 6) + self.assertIn(signal.Signals.SIGINT, s) + self.assertNotIn(0, s) + self.assertNotIn(signal.NSIG, s) + self.assertLess(len(s), signal.NSIG) + def test_issue9324(self): # Updated for issue #10003, adding SIGBREAK handler = lambda x, y: None @@ -922,6 +941,17 @@ def test_pthread_sigmask_arguments(self): self.assertRaises(TypeError, signal.pthread_sigmask, 1) self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3) self.assertRaises(OSError, signal.pthread_sigmask, 1700, []) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [signal.NSIG]) + + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') + def test_pthread_sigmask_valid_signals(self): + s = signal.pthread_sigmask(signal.SIG_BLOCK, signal.valid_signals()) + self.addCleanup(signal.pthread_sigmask, signal.SIG_SETMASK, s) + # Get current blocked set + s = signal.pthread_sigmask(signal.SIG_UNBLOCK, signal.valid_signals()) + self.assertLessEqual(s, signal.valid_signals()) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') diff --git a/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst b/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst new file mode 100644 index 000000000000..05dca54d5776 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-23-21-41-30.bpo-33332.Y6OZ8Z.rst @@ -0,0 +1,2 @@ +Add ``signal.valid_signals()`` to expose the POSIX sigfillset() +functionality. diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 1c439716c498..eca2da10ad33 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -341,6 +341,31 @@ PyDoc_STRVAR(signal_sigwait__doc__, #endif /* defined(HAVE_SIGWAIT) */ +#if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) + +PyDoc_STRVAR(signal_valid_signals__doc__, +"valid_signals($module, /)\n" +"--\n" +"\n" +"Return a set of valid signal numbers on this platform.\n" +"\n" +"The signal numbers returned by this function can be safely passed to\n" +"functions like `pthread_sigmask`."); + +#define SIGNAL_VALID_SIGNALS_METHODDEF \ + {"valid_signals", (PyCFunction)signal_valid_signals, METH_NOARGS, signal_valid_signals__doc__}, + +static PyObject * +signal_valid_signals_impl(PyObject *module); + +static PyObject * +signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_valid_signals_impl(module); +} + +#endif /* (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) */ + #if defined(HAVE_SIGWAITINFO) PyDoc_STRVAR(signal_sigwaitinfo__doc__, @@ -459,6 +484,10 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #define SIGNAL_SIGWAIT_METHODDEF #endif /* !defined(SIGNAL_SIGWAIT_METHODDEF) */ +#ifndef SIGNAL_VALID_SIGNALS_METHODDEF + #define SIGNAL_VALID_SIGNALS_METHODDEF +#endif /* !defined(SIGNAL_VALID_SIGNALS_METHODDEF) */ + #ifndef SIGNAL_SIGWAITINFO_METHODDEF #define SIGNAL_SIGWAITINFO_METHODDEF #endif /* !defined(SIGNAL_SIGWAITINFO_METHODDEF) */ @@ -470,4 +499,4 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=7b41486acf93aa8e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f35d79e0cfee3f1b input=a9049054013a1b77]*/ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 35fd87e2d1e7..003bbb60e387 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -841,11 +841,21 @@ iterable_to_sigset(PyObject *iterable, sigset_t *mask) if (signum == -1 && PyErr_Occurred()) goto error; if (0 < signum && signum < NSIG) { - /* bpo-33329: ignore sigaddset() return value as it can fail - * for some reserved signals, but we want the `range(1, NSIG)` - * idiom to allow selecting all valid signals. - */ - (void) sigaddset(mask, (int)signum); + if (sigaddset(mask, (int)signum)) { + if (errno != EINVAL) { + /* Probably impossible */ + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + /* For backwards compatibility, allow idioms such as + * `range(1, NSIG)` but warn about invalid signal numbers + */ + const char *msg = + "invalid signal number %ld, please use valid_signals()"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { + goto error; + } + } } else { PyErr_Format(PyExc_ValueError, @@ -1001,6 +1011,47 @@ signal_sigwait(PyObject *module, PyObject *sigset) #endif /* #ifdef HAVE_SIGWAIT */ +#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) + +/*[clinic input] +signal.valid_signals + +Return a set of valid signal numbers on this platform. + +The signal numbers returned by this function can be safely passed to +functions like `pthread_sigmask`. +[clinic start generated code]*/ + +static PyObject * +signal_valid_signals_impl(PyObject *module) +/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/ +{ +#ifdef MS_WINDOWS +#ifdef SIGBREAK + PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE, + SIGILL, SIGINT, SIGSEGV, SIGTERM); +#else + PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL, + SIGINT, SIGSEGV, SIGTERM); +#endif + if (tup == NULL) { + return NULL; + } + PyObject *set = PySet_New(tup); + Py_DECREF(tup); + return set; +#else + sigset_t mask; + if (sigemptyset(&mask) || sigfillset(&mask)) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return sigset_to_set(mask); +#endif +} + +#endif /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */ + + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) static int initialized; static PyStructSequence_Field struct_siginfo_fields[] = { @@ -1225,6 +1276,9 @@ static PyMethodDef signal_methods[] = { SIGNAL_SIGWAIT_METHODDEF SIGNAL_SIGWAITINFO_METHODDEF SIGNAL_SIGTIMEDWAIT_METHODDEF +#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) + SIGNAL_VALID_SIGNALS_METHODDEF +#endif {NULL, NULL} /* sentinel */ }; diff --git a/aclocal.m4 b/aclocal.m4 index 8ed232fb515f..69205776ed4c 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -12,9 +12,9 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 12 (pkg-config-0.29.2) - +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl dnl Copyright ? 2004 Scott James Remnant . dnl Copyright ? 2012-2015 Dan Nicholson dnl @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $2]) +AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -187,7 +187,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full diff --git a/configure b/configure index 673cfbd3cf62..adf8cf3ab9c1 100755 --- a/configure +++ b/configure @@ -11259,7 +11259,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ sched_rr_get_interval \ - sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ diff --git a/configure.ac b/configure.ac index 419bc34eab76..b52247356d75 100644 --- a/configure.ac +++ b/configure.ac @@ -3474,7 +3474,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ sched_rr_get_interval \ - sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index a0efff9777d2..848872a7dca3 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -896,6 +896,9 @@ /* Define to 1 if you have the `sigaltstack' function. */ #undef HAVE_SIGALTSTACK +/* Define to 1 if you have the `sigfillset' function. */ +#undef HAVE_SIGFILLSET + /* Define to 1 if `si_band' is a member of `siginfo_t'. */ #undef HAVE_SIGINFO_T_SI_BAND From webhook-mailer at python.org Fri May 4 17:21:04 2018 From: webhook-mailer at python.org (Vinay Sajip) Date: Fri, 04 May 2018 21:21:04 -0000 Subject: [Python-checkins] bpo-33400: Clarified documentation to indicate no strict adherence to ISO 8601. (GH-6702) Message-ID: https://github.com/python/cpython/commit/c4994dc00d9828a99510f3851da93b0e1c18361d commit: c4994dc00d9828a99510f3851da93b0e1c18361d branch: master author: Vinay Sajip committer: GitHub date: 2018-05-04T22:20:54+01:00 summary: bpo-33400: Clarified documentation to indicate no strict adherence to ISO 8601. (GH-6702) files: M Doc/howto/logging.rst M Doc/library/logging.config.rst M Doc/library/logging.rst M Lib/logging/__init__.py diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index f8b78b618569..e9e5580df969 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -296,9 +296,9 @@ which should print something like this: 2010-12-12 11:41:42,612 is when this event was logged. -The default format for date/time display (shown above) is ISO8601. If you need -more control over the formatting of the date/time, provide a *datefmt* -argument to ``basicConfig``, as in this example:: +The default format for date/time display (shown above) is like ISO8601 or +RFC 3339. If you need more control over the formatting of the date/time, provide +a *datefmt* argument to ``basicConfig``, as in this example:: import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 1f9d7c7f220b..b5007610c40f 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -790,10 +790,10 @@ Sections which specify formatter configuration are typified by the following. The ``format`` entry is the overall format string, and the ``datefmt`` entry is the :func:`strftime`\ -compatible date/time format string. If empty, the -package substitutes ISO8601 format date/times, which is almost equivalent to -specifying the date format string ``'%Y-%m-%d %H:%M:%S'``. The ISO8601 format -also specifies milliseconds, which are appended to the result of using the above -format string, with a comma separator. An example time in ISO8601 format is +package substitutes ISO8601-style format date/times, which is almost equivalent to +specifying the date format string ``'%Y-%m-%d %H:%M:%S'``. This format also +specifies milliseconds, which are appended to the result of using the above +format string, with a comma separator. An example time in this format is ``2003-01-23 00:29:50,411``. The ``class`` entry is optional. It indicates the name of the formatter's class diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index f9eda173ad0d..9a54bf9325a0 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -515,8 +515,9 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on Returns a new instance of the :class:`Formatter` class. The instance is initialized with a format string for the message as a whole, as well as a format string for the date/time portion of a message. If no *fmt* is - specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the - ISO8601 date format is used. + specified, ``'%(message)s'`` is used. If no *datefmt* is specified, an + ISO8601-like (or RFC3339-like) date format is used. See the + :meth:`formatTime` documentation for more details. The *style* parameter can be one of '%', '{' or '$' and determines how the format string will be merged with its data: using one of %-formatting, @@ -556,8 +557,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on formatters to provide for any specific requirement, but the basic behavior is as follows: if *datefmt* (a string) is specified, it is used with :func:`time.strftime` to format the creation time of the - record. Otherwise, the ISO8601 format is used. The resulting string is - returned. + record. Otherwise, an ISO8601-like (or RDC 3339-like) format is used. The + resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, :func:`time.localtime` is used; to change @@ -568,7 +569,7 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on attribute in the ``Formatter`` class. .. versionchanged:: 3.3 - Previously, the default ISO 8601 format was hard-coded as in this + Previously, the default ISO8601-like format was hard-coded as in this example: ``2010-09-06 22:38:15,292`` where the part before the comma is handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the part after the comma is a millisecond value. Because strptime does not diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 9f2c0f0c58a3..46c590687c7d 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -466,7 +466,8 @@ def __init__(self, fmt=None, datefmt=None, style='%'): Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with - the optional datefmt argument (if omitted, you get the ISO8601 format). + the optional datefmt argument. If datefmt is omitted, you get an + ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or @@ -494,13 +495,13 @@ def formatTime(self, record, datefmt=None): in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the - record. Otherwise, the ISO8601 format is used. The resulting - string is returned. This function uses a user-configurable function - to convert the creation time to a tuple. By default, time.localtime() - is used; to change this for a particular formatter instance, set the - 'converter' attribute to a function with the same signature as - time.localtime() or time.gmtime(). To change it for all formatters, - for example if you want all logging times to be shown in GMT, + record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. + The resulting string is returned. This function uses a user-configurable + function to convert the creation time to a tuple. By default, + time.localtime() is used; to change this for a particular formatter + instance, set the 'converter' attribute to a function with the same + signature as time.localtime() or time.gmtime(). To change it for all + formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) From webhook-mailer at python.org Fri May 4 18:02:52 2018 From: webhook-mailer at python.org (Vinay Sajip) Date: Fri, 04 May 2018 22:02:52 -0000 Subject: [Python-checkins] bpo-33400: Clarified documentation to indicate no strict adherence to ISO 8601. (GH-6703) Message-ID: https://github.com/python/cpython/commit/eb5abdc70815c4207829551ede4a7dc302d56c19 commit: eb5abdc70815c4207829551ede4a7dc302d56c19 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Vinay Sajip date: 2018-05-04T23:02:48+01:00 summary: bpo-33400: Clarified documentation to indicate no strict adherence to ISO 8601. (GH-6703) (cherry picked from commit c4994dc00d9828a99510f3851da93b0e1c18361d) Co-authored-by: Vinay Sajip files: M Doc/howto/logging.rst M Doc/library/logging.config.rst M Doc/library/logging.rst M Lib/logging/__init__.py diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index cc230e1897ba..5976c32d93b0 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -296,9 +296,9 @@ which should print something like this: 2010-12-12 11:41:42,612 is when this event was logged. -The default format for date/time display (shown above) is ISO8601. If you need -more control over the formatting of the date/time, provide a *datefmt* -argument to ``basicConfig``, as in this example:: +The default format for date/time display (shown above) is like ISO8601 or +RFC 3339. If you need more control over the formatting of the date/time, provide +a *datefmt* argument to ``basicConfig``, as in this example:: import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 9a75a3c81d83..5f5ea03362ea 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -783,10 +783,10 @@ Sections which specify formatter configuration are typified by the following. The ``format`` entry is the overall format string, and the ``datefmt`` entry is the :func:`strftime`\ -compatible date/time format string. If empty, the -package substitutes ISO8601 format date/times, which is almost equivalent to -specifying the date format string ``'%Y-%m-%d %H:%M:%S'``. The ISO8601 format -also specifies milliseconds, which are appended to the result of using the above -format string, with a comma separator. An example time in ISO8601 format is +package substitutes ISO8601-style format date/times, which is almost equivalent to +specifying the date format string ``'%Y-%m-%d %H:%M:%S'``. This format also +specifies milliseconds, which are appended to the result of using the above +format string, with a comma separator. An example time in this format is ``2003-01-23 00:29:50,411``. The ``class`` entry is optional. It indicates the name of the formatter's class diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 55b8dda0df47..d0a6e613d8ee 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -515,8 +515,9 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on Returns a new instance of the :class:`Formatter` class. The instance is initialized with a format string for the message as a whole, as well as a format string for the date/time portion of a message. If no *fmt* is - specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the - ISO8601 date format is used. + specified, ``'%(message)s'`` is used. If no *datefmt* is specified, an + ISO8601-like (or RFC3339-like) date format is used. See the + :meth:`formatTime` documentation for more details. The *style* parameter can be one of '%', '{' or '$' and determines how the format string will be merged with its data: using one of %-formatting, @@ -556,8 +557,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on formatters to provide for any specific requirement, but the basic behavior is as follows: if *datefmt* (a string) is specified, it is used with :func:`time.strftime` to format the creation time of the - record. Otherwise, the ISO8601 format is used. The resulting string is - returned. + record. Otherwise, an ISO8601-like (or RDC 3339-like) format is used. The + resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, :func:`time.localtime` is used; to change @@ -568,7 +569,7 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on attribute in the ``Formatter`` class. .. versionchanged:: 3.3 - Previously, the default ISO 8601 format was hard-coded as in this + Previously, the default ISO8601-like format was hard-coded as in this example: ``2010-09-06 22:38:15,292`` where the part before the comma is handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the part after the comma is a millisecond value. Because strptime does not diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 3617dbb6d996..e2084f550508 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -473,7 +473,8 @@ def __init__(self, fmt=None, datefmt=None, style='%'): Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with - the optional datefmt argument (if omitted, you get the ISO8601 format). + the optional datefmt argument. If datefmt is omitted, you get an + ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or @@ -501,13 +502,13 @@ def formatTime(self, record, datefmt=None): in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the - record. Otherwise, the ISO8601 format is used. The resulting - string is returned. This function uses a user-configurable function - to convert the creation time to a tuple. By default, time.localtime() - is used; to change this for a particular formatter instance, set the - 'converter' attribute to a function with the same signature as - time.localtime() or time.gmtime(). To change it for all formatters, - for example if you want all logging times to be shown in GMT, + record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. + The resulting string is returned. This function uses a user-configurable + function to convert the creation time to a tuple. By default, + time.localtime() is used; to change this for a particular formatter + instance, set the 'converter' attribute to a function with the same + signature as time.localtime() or time.gmtime(). To change it for all + formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) From lp_benchmark_robot at intel.com Fri May 4 19:50:54 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 4 May 2018 16:50:54 -0700 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-05-04 Message-ID: Results for project python/master, build date: 2018-05-04 09:43:37-07:00. - commit: 9d3627e - previous commit: 491bbed - revision date: 2018-05-04 13:00:50+02:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.614% | +0.093% | +8.310% | +7.737% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.722% | -0.036% | +23.735% | +12.833% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 0.988% | +0.056% | +25.581% | +12.083% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.298% | +0.009% | +23.698% | +9.526% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.171% | -0.005% | +9.801% | +14.490% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.489% | +0.434% | +12.153% | +10.749% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.778% | +0.606% | +9.427% | +9.797% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.525% | +0.412% | -1.385% | +9.957% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 3.294% | -1.359% | +11.190% | +17.046% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 1.410% | +1.362% | +21.787% | +13.023% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.249% | +0.122% | +5.282% | +6.809% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.278% | +0.894% | +7.134% | +6.340% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.086% | -0.302% | +2.569% | +7.353% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.134% | +0.080% | +13.658% | +10.642% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.164% | +2.091% | +12.781% | +9.025% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 6.831% | -0.029% | +3.903% | +12.791% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.425% | +0.246% | +11.380% | +11.462% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 2.547% | +0.873% | +11.404% | +11.672% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 0.945% | -0.150% | +2.265% | +9.853% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 1.922% | +0.705% | -5.113% | +16.410% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.415% | +0.904% | +18.222% | +13.536% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 3.004% | -1.257% | +47.528% | +12.984% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.365% | +0.651% | +12.267% | +14.545% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.459% | +0.265% | +15.636% | +15.910% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 8.215% | -1.690% | +2.743% | +15.598% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 1.303% | -0.187% | +4.373% | +7.381% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.682% | +1.343% | -0.776% | +2.308% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 2.020% | +1.110% | +5.710% | +6.967% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.127% | +0.200% | -1.109% | +11.880% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.651% | +0.060% | +0.349% | +22.356% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.213% | -0.025% | +4.325% | +20.808% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.713% | +0.430% | +6.057% | +19.828% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 4.567% | +3.309% | +11.345% | +11.373% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.159% | +0.029% | +0.238% | +10.511% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.125% | +0.112% | +18.431% | +6.403% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.083% | +0.125% | +5.462% | +6.361% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.942% | -0.084% | +10.408% | +13.571% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 4.911% | +1.368% | +2.668% | +11.831% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.533% | -0.125% | -2.141% | +13.985% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.459% | -1.411% | -4.147% | +8.126% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 0.887% | -0.219% | +3.198% | +9.745% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.946% | -0.321% | +9.527% | +14.992% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.602% | +1.760% | -1.344% | +5.101% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 2.932% | -1.584% | +21.385% | +13.065% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 1.791% | +0.719% | +5.082% | +4.695% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 1.508% | +0.728% | +14.077% | +9.759% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.872% | +1.067% | -4.674% | +2.545% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.732% | -0.015% | +3.554% | +9.241% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.072% | -0.073% | +6.652% | +6.720% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.842% | -0.405% | +7.427% | +4.914% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 3.491% | -0.328% | +0.472% | +9.252% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 2.926% | +0.595% | +17.333% | +7.469% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 1.383% | +0.517% | +18.094% | +6.808% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 3.862% | +1.158% | +18.881% | +8.409% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.650% | +0.213% | +15.270% | +10.964% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 3.158% | -0.675% | +18.223% | +10.708% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.974% | +0.105% | +7.103% | +6.983% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.227% | +0.067% | +2.272% | +0.464% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 7.002% | -2.631% | +6.059% | +22.559% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 0.782% | +1.973% | -1.865% | +14.516% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 2.570% | +0.648% | +6.258% | +9.334% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 0.876% | +0.945% | +2.941% | +12.582% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.312% | -0.433% | +2.156% | +9.710% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 4.461% | -0.217% | -9.330% | +12.050% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.144% | +0.417% | +4.354% | +12.002% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-05-04 Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From solipsis at pitrou.net Sat May 5 05:10:04 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 05 May 2018 09:10:04 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=14 Message-ID: <20180505091004.1.48AF689AF135DDCB@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_collections leaked [0, 7, 0] memory blocks, sum=7 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [-1, -1, 2] memory blocks, sum=0 test_multiprocessing_spawn leaked [-1, -1, 2] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogzdIIhr', '--timeout', '7200'] From webhook-mailer at python.org Sat May 5 07:09:51 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 05 May 2018 11:09:51 -0000 Subject: [Python-checkins] [2.7] bpo-32362: Fix references to non-existent multiprocessing.Connection() (GH-6223) (GH-6646) Message-ID: https://github.com/python/cpython/commit/4a1bc26832048325aecc01a4783a4984496d52d2 commit: 4a1bc26832048325aecc01a4783a4984496d52d2 branch: 2.7 author: Bo Bayles committer: Serhiy Storchaka date: 2018-05-05T14:09:46+03:00 summary: [2.7] bpo-32362: Fix references to non-existent multiprocessing.Connection() (GH-6223) (GH-6646) (cherry picked from commit 9f3535c9cde8813ce631d6ebe4d790682f594828) Co-authored-by: Bo Bayles files: M Doc/library/multiprocessing.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 81c46c0b637b..2d8660aba9c8 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -803,10 +803,13 @@ Miscellaneous Connection Objects ~~~~~~~~~~~~~~~~~~ +.. currentmodule:: None + Connection objects allow the sending and receiving of picklable objects or strings. They can be thought of as message oriented connected sockets. -Connection objects are usually created using :func:`Pipe` -- see also +Connection objects are usually created using +:func:`Pipe ` -- see also :ref:`multiprocessing-listeners-clients`. .. class:: Connection @@ -926,6 +929,8 @@ For example: Synchronization primitives ~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. currentmodule:: multiprocessing + Generally synchronization primitives are not as necessary in a multiprocess program as they are in a multithreaded program. See the documentation for :mod:`threading` module. @@ -1943,8 +1948,7 @@ Listeners and Clients :synopsis: API for dealing with sockets. Usually message passing between processes is done using queues or by using -:class:`~multiprocessing.Connection` objects returned by -:func:`~multiprocessing.Pipe`. +:class:`Connection` objects returned by :func:`~multiprocessing.Pipe`. However, the :mod:`multiprocessing.connection` module allows some extra flexibility. It basically gives a high level message oriented API for dealing @@ -1972,7 +1976,7 @@ authentication* using the :mod:`hmac` module. .. function:: Client(address[, family[, authenticate[, authkey]]]) Attempt to set up a connection to the listener which is using address - *address*, returning a :class:`~multiprocessing.Connection`. + *address*, returning a :class:`Connection`. The type of the connection is determined by *family* argument, but this can generally be omitted since it can usually be inferred from the format of @@ -2028,8 +2032,8 @@ authentication* using the :mod:`hmac` module. .. method:: accept() Accept a connection on the bound socket or named pipe of the listener - object and return a :class:`~multiprocessing.Connection` object. If - authentication is attempted and fails, then + object and return a :class:`Connection` object. + If authentication is attempted and fails, then :exc:`~multiprocessing.AuthenticationError` is raised. .. method:: close() @@ -2139,7 +2143,7 @@ an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address. Authentication keys ~~~~~~~~~~~~~~~~~~~ -When one uses :meth:`Connection.recv `, the +When one uses :meth:`Connection.recv`, the data received is automatically unpickled. Unfortunately unpickling data from an untrusted source is a security risk. Therefore :class:`Listener` and :func:`Client` use the :mod:`hmac` module From webhook-mailer at python.org Sat May 5 09:10:51 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 05 May 2018 13:10:51 -0000 Subject: [Python-checkins] bpo-32857: Raise error when tkinter after_cancel() is called with None. (GH-5701) (GH-6620) Message-ID: https://github.com/python/cpython/commit/3a04598f63960e72025a91c682aec51b6b460413 commit: 3a04598f63960e72025a91c682aec51b6b460413 branch: 2.7 author: Cheryl Sabella committer: Serhiy Storchaka date: 2018-05-05T16:10:48+03:00 summary: bpo-32857: Raise error when tkinter after_cancel() is called with None. (GH-5701) (GH-6620) (cherry picked from commit 74382a3f175ac285cc924a73fd758e8dc3cc41bb) files: A Lib/lib-tk/test/test_tkinter/test_misc.py A Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst M Lib/lib-tk/Tkinter.py diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py index b226fd5f3529..f46642f5bb99 100644 --- a/Lib/lib-tk/Tkinter.py +++ b/Lib/lib-tk/Tkinter.py @@ -586,6 +586,7 @@ def after(self, ms, func=None, *args): if not func: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) + return None else: def callit(): try: @@ -609,11 +610,13 @@ def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be - given as first parameter.""" + given as first parameter. + """ + if not id: + raise ValueError('id must be a valid identifier returned from ' + 'after or after_idle') try: data = self.tk.call('after', 'info', id) - # In Tk 8.3, splitlist returns: (script, type) - # In Tk 8.4, splitlist may return (script, type) or (script,) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: diff --git a/Lib/lib-tk/test/test_tkinter/test_misc.py b/Lib/lib-tk/test/test_tkinter/test_misc.py new file mode 100644 index 000000000000..796269ede409 --- /dev/null +++ b/Lib/lib-tk/test/test_tkinter/test_misc.py @@ -0,0 +1,122 @@ +import unittest +import Tkinter as tkinter +from test.test_support import requires, run_unittest +from test_ttk.support import AbstractTkTest + +requires('gui') + +class MiscTest(AbstractTkTest, unittest.TestCase): + + def test_after(self): + root = self.root + cbcount = {'count': 0} + + def callback(start=0, step=1): + cbcount['count'] = start + step + + # Without function, sleeps for ms. + self.assertIsNone(root.after(1)) + + # Set up with callback with no args. + cbcount['count'] = 0 + timer1 = root.after(0, callback) + self.assertIn(timer1, root.tk.call('after', 'info')) + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1)) + root.update() # Process all pending events. + self.assertEqual(cbcount['count'], 1) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + + # Set up with callback with args. + cbcount['count'] = 0 + timer1 = root.after(0, callback, 42, 11) + root.update() # Process all pending events. + self.assertEqual(cbcount['count'], 53) + + # Cancel before called. + timer1 = root.after(1000, callback) + self.assertIn(timer1, root.tk.call('after', 'info')) + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1)) + root.after_cancel(timer1) # Cancel this event. + self.assertEqual(cbcount['count'], 53) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + + def test_after_idle(self): + root = self.root + cbcount = {'count': 0} + + def callback(start=0, step=1): + cbcount['count'] = start + step + + # Set up with callback with no args. + cbcount['count'] = 0 + idle1 = root.after_idle(callback) + self.assertIn(idle1, root.tk.call('after', 'info')) + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1)) + root.update_idletasks() # Process all pending events. + self.assertEqual(cbcount['count'], 1) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + + # Set up with callback with args. + cbcount['count'] = 0 + idle1 = root.after_idle(callback, 42, 11) + root.update_idletasks() # Process all pending events. + self.assertEqual(cbcount['count'], 53) + + # Cancel before called. + idle1 = root.after_idle(callback) + self.assertIn(idle1, root.tk.call('after', 'info')) + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1)) + root.after_cancel(idle1) # Cancel this event. + self.assertEqual(cbcount['count'], 53) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + + def test_after_cancel(self): + root = self.root + cbcount = {'count': 0} + + def callback(): + cbcount['count'] += 1 + + timer1 = root.after(5000, callback) + idle1 = root.after_idle(callback) + + # No value for id raises a ValueError. + with self.assertRaises(ValueError): + root.after_cancel(None) + + # Cancel timer event. + cbcount['count'] = 0 + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', timer1)) + root.tk.call(script) + self.assertEqual(cbcount['count'], 1) + root.after_cancel(timer1) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + self.assertEqual(cbcount['count'], 1) + with self.assertRaises(tkinter.TclError): + root.tk.call('after', 'info', timer1) + + # Cancel same event - nothing happens. + root.after_cancel(timer1) + + # Cancel idle event. + cbcount['count'] = 0 + (script, _) = root.tk.splitlist(root.tk.call('after', 'info', idle1)) + root.tk.call(script) + self.assertEqual(cbcount['count'], 1) + root.after_cancel(idle1) + with self.assertRaises(tkinter.TclError): + root.tk.call(script) + self.assertEqual(cbcount['count'], 1) + with self.assertRaises(tkinter.TclError): + root.tk.call('after', 'info', idle1) + + +tests_gui = (MiscTest, ) + +if __name__ == "__main__": + run_unittest(*tests_gui) diff --git a/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst b/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst new file mode 100644 index 000000000000..4ebbde4d1946 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-16-14-37-14.bpo-32857.-XljAx.rst @@ -0,0 +1 @@ +In :mod:`tkinter`, ``after_cancel(None)`` now raises a :exc:`ValueError` instead of canceling the first scheduled function. Patch by Cheryl Sabella. From webhook-mailer at python.org Sat May 5 12:07:35 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 05 May 2018 16:07:35 -0000 Subject: [Python-checkins] bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Message-ID: https://github.com/python/cpython/commit/b2043bbe6034b53f5ad337887f4741b74b70b00d commit: b2043bbe6034b53f5ad337887f4741b74b70b00d branch: master author: Andr?s Delfino committer: Serhiy Storchaka date: 2018-05-05T19:07:32+03:00 summary: bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Also update the list of string prefixes. files: A Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst M Lib/pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index e7a1655b228f..199745ca6fa8 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1747,8 +1747,9 @@ class Helper: } # Either add symbols to this dictionary or to the symbols dictionary # directly: Whichever is easier. They are merged later. + _strprefixes = [p + q for p in ('b', 'f', 'r', 'u') for q in ("'", '"')] _symbols_inverse = { - 'STRINGS' : ("'", "'''", "r'", "b'", '"""', '"', 'r"', 'b"'), + 'STRINGS' : ("'", "'''", '"', '"""', *_strprefixes), 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), @@ -1910,7 +1911,13 @@ def interact(self): if not request: break except (KeyboardInterrupt, EOFError): break - request = replace(request, '"', '', "'", '').strip() + request = request.strip() + + # Make sure significant trailing quoting marks of literals don't + # get deleted while cleaning input + if (len(request) > 2 and request[0] == request[-1] in ("'", '"') + and request[0] not in request[1:-1]): + request = request[1:-1] if request.lower() in ('q', 'quit'): break if request == 'help': self.intro() diff --git a/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst new file mode 100644 index 000000000000..0d284d508f10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst @@ -0,0 +1,2 @@ +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andr?s Delfino. From webhook-mailer at python.org Sat May 5 12:42:59 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 05 May 2018 16:42:59 -0000 Subject: [Python-checkins] bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Message-ID: https://github.com/python/cpython/commit/351782b9927c610ff531100dbdcbbd19d91940a3 commit: 351782b9927c610ff531100dbdcbbd19d91940a3 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-05T09:42:56-07:00 summary: bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Also update the list of string prefixes. (cherry picked from commit b2043bbe6034b53f5ad337887f4741b74b70b00d) Co-authored-by: Andr?s Delfino files: A Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst M Lib/pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index e7a1655b228f..199745ca6fa8 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1747,8 +1747,9 @@ class Helper: } # Either add symbols to this dictionary or to the symbols dictionary # directly: Whichever is easier. They are merged later. + _strprefixes = [p + q for p in ('b', 'f', 'r', 'u') for q in ("'", '"')] _symbols_inverse = { - 'STRINGS' : ("'", "'''", "r'", "b'", '"""', '"', 'r"', 'b"'), + 'STRINGS' : ("'", "'''", '"', '"""', *_strprefixes), 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), @@ -1910,7 +1911,13 @@ def interact(self): if not request: break except (KeyboardInterrupt, EOFError): break - request = replace(request, '"', '', "'", '').strip() + request = request.strip() + + # Make sure significant trailing quoting marks of literals don't + # get deleted while cleaning input + if (len(request) > 2 and request[0] == request[-1] in ("'", '"') + and request[0] not in request[1:-1]): + request = request[1:-1] if request.lower() in ('q', 'quit'): break if request == 'help': self.intro() diff --git a/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst new file mode 100644 index 000000000000..0d284d508f10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst @@ -0,0 +1,2 @@ +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andr?s Delfino. From webhook-mailer at python.org Sat May 5 13:12:22 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 05 May 2018 17:12:22 -0000 Subject: [Python-checkins] bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Message-ID: https://github.com/python/cpython/commit/0ba812b1bee65a6cad16f153a7f5074bc271e0e5 commit: 0ba812b1bee65a6cad16f153a7f5074bc271e0e5 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-05T10:12:19-07:00 summary: bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) Also update the list of string prefixes. (cherry picked from commit b2043bbe6034b53f5ad337887f4741b74b70b00d) Co-authored-by: Andr?s Delfino files: A Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst M Lib/pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 34e2fabf20ee..40ee76044089 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1716,8 +1716,9 @@ class Helper: } # Either add symbols to this dictionary or to the symbols dictionary # directly: Whichever is easier. They are merged later. + _strprefixes = [p + q for p in ('b', 'f', 'r', 'u') for q in ("'", '"')] _symbols_inverse = { - 'STRINGS' : ("'", "'''", "r'", "b'", '"""', '"', 'r"', 'b"'), + 'STRINGS' : ("'", "'''", '"', '"""', *_strprefixes), 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), @@ -1874,7 +1875,13 @@ def interact(self): if not request: break except (KeyboardInterrupt, EOFError): break - request = replace(request, '"', '', "'", '').strip() + request = request.strip() + + # Make sure significant trailing quoting marks of literals don't + # get deleted while cleaning input + if (len(request) > 2 and request[0] == request[-1] in ("'", '"') + and request[0] not in request[1:-1]): + request = request[1:-1] if request.lower() in ('q', 'quit'): break if request == 'help': self.intro() diff --git a/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst new file mode 100644 index 000000000000..0d284d508f10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst @@ -0,0 +1,2 @@ +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andr?s Delfino. From webhook-mailer at python.org Sun May 6 01:46:24 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 06 May 2018 05:46:24 -0000 Subject: [Python-checkins] =?utf-8?q?bpo-20087=3A_Update_locale_alias_map?= =?utf-8?q?ping_with_glibc_2=2E27_supported_locales=2E_=28=D0=9F=D0=A0-670?= =?utf-8?q?8=29?= Message-ID: https://github.com/python/cpython/commit/cedc9b74202d8c1ae39bca261cbb45d42ed54d45 commit: cedc9b74202d8c1ae39bca261cbb45d42ed54d45 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-06T08:46:15+03:00 summary: bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (??-6708) files: A Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst M Lib/locale.py M Lib/test/test_locale.py diff --git a/Lib/locale.py b/Lib/locale.py index 18079e73ad69..876d2eb1e123 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -846,6 +846,16 @@ def getpreferredencoding(do_setlocale = True): # # SS 2014-10-01: # Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 3.6.5 +# and older): +# +# updated 'ca_es at valencia' -> 'ca_ES.ISO8859-15 at valencia' to 'ca_ES.UTF-8 at valencia' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' locale_alias = { 'a3': 'az_AZ.KOI8-C', @@ -856,10 +866,13 @@ def getpreferredencoding(do_setlocale = True): 'aa_et': 'aa_ET.UTF-8', 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', 'ar_ae': 'ar_AE.ISO8859-6', @@ -877,6 +890,7 @@ def getpreferredencoding(do_setlocale = True): 'ar_qa': 'ar_QA.ISO8859-6', 'ar_sa': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', 'ar_sy': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', 'ar_ye': 'ar_YE.ISO8859-6', @@ -888,6 +902,7 @@ def getpreferredencoding(do_setlocale = True): 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', 'be': 'be_BY.CP1251', 'be at latin': 'be_BY.UTF-8 at latin', 'be_bg.utf8': 'bg_BG.UTF-8', @@ -898,13 +913,17 @@ def getpreferredencoding(do_setlocale = True): 'ber_ma': 'ber_MA.UTF-8', 'bg': 'bg_BG.CP1251', 'bg_bg': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', 'bo_cn': 'bo_CN.UTF-8', 'bo_in': 'bo_IN.UTF-8', 'bokmal': 'nb_NO.ISO8859-1', 'bokm\xe5l': 'nb_NO.ISO8859-1', + 'bokm\xef\xbf\xbd': 'nb_NO.ISO8859-1', 'br': 'br_FR.ISO8859-1', 'br_fr': 'br_FR.ISO8859-1', 'brx_in': 'brx_IN.UTF-8', @@ -923,13 +942,17 @@ def getpreferredencoding(do_setlocale = True): 'ca': 'ca_ES.ISO8859-1', 'ca_ad': 'ca_AD.ISO8859-1', 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es at valencia': 'ca_ES.ISO8859-15 at valencia', + 'ca_es at valencia': 'ca_ES.UTF-8 at valencia', 'ca_fr': 'ca_FR.ISO8859-1', 'ca_it': 'ca_IT.ISO8859-1', 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', 'cextend': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', @@ -951,6 +974,7 @@ def getpreferredencoding(do_setlocale = True): 'de_be': 'de_BE.ISO8859-1', 'de_ch': 'de_CH.ISO8859-1', 'de_de': 'de_DE.ISO8859-1', + 'de_it': 'de_IT.ISO8859-1', 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', 'deutsch': 'de_DE.ISO8859-1', @@ -977,10 +1001,12 @@ def getpreferredencoding(do_setlocale = True): 'en_gb': 'en_GB.ISO8859-1', 'en_hk': 'en_HK.ISO8859-1', 'en_ie': 'en_IE.ISO8859-1', + 'en_il': 'en_IL.UTF-8', 'en_in': 'en_IN.ISO8859-1', 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', 'en_sg': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', 'en_us': 'en_US.ISO8859-1', @@ -991,6 +1017,7 @@ def getpreferredencoding(do_setlocale = True): 'en_zw.utf8': 'en_ZS.UTF-8', 'eng_gb': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_US.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', 'english_united-states.437': 'C', @@ -1045,6 +1072,7 @@ def getpreferredencoding(do_setlocale = True): 'fr_fr': 'fr_FR.ISO8859-1', 'fr_lu': 'fr_LU.ISO8859-1', 'fran\xe7ais': 'fr_FR.ISO8859-1', + 'fran\xef\xbf\xbdis': 'fr_FR.ISO8859-1', 'fre_fr': 'fr_FR.ISO8859-1', 'french': 'fr_FR.ISO8859-1', 'french.iso88591': 'fr_CH.ISO8859-1', @@ -1071,12 +1099,14 @@ def getpreferredencoding(do_setlocale = True): 'gv': 'gv_GB.ISO8859-1', 'gv_gb': 'gv_GB.ISO8859-1', 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', 'hebrew': 'he_IL.ISO8859-8', 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', 'hne': 'hne_IN.UTF-8', 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', @@ -1131,7 +1161,8 @@ def getpreferredencoding(do_setlocale = True): 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', - 'kk_kz': 'kk_KZ.RK1048', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', 'km_kh': 'km_KH.UTF-8', @@ -1157,6 +1188,7 @@ def getpreferredencoding(do_setlocale = True): 'li_nl': 'li_NL.UTF-8', 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', 'lo_la.cp1133': 'lo_LA.IBM-CP1133', @@ -1166,13 +1198,18 @@ def getpreferredencoding(do_setlocale = True): 'lt_lt': 'lt_LT.ISO8859-13', 'lv': 'lv_LV.ISO8859-13', 'lv_lv': 'lv_LV.ISO8859-13', + 'lzh_tw': 'lzh_TW.UTF-8', 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', 'mg_mg': 'mg_MG.ISO8859-15', 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', 'ml': 'ml_IN.UTF-8', @@ -1186,7 +1223,7 @@ def getpreferredencoding(do_setlocale = True): 'mt': 'mt_MT.ISO8859-3', 'mt_mt': 'mt_MT.ISO8859-3', 'my_mm': 'my_MM.UTF-8', - 'nan_tw at latin': 'nan_TW.UTF-8 at latin', + 'nan_tw': 'nan_TW.UTF-8', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', 'nds_de': 'nds_DE.UTF-8', @@ -1225,6 +1262,8 @@ def getpreferredencoding(do_setlocale = True): 'pa_in': 'pa_IN.UTF-8', 'pa_pk': 'pa_PK.UTF-8', 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', 'pd_us': 'pd_US.ISO8859-1', @@ -1243,6 +1282,8 @@ def getpreferredencoding(do_setlocale = True): 'pt': 'pt_PT.ISO8859-1', 'pt_br': 'pt_BR.ISO8859-1', 'pt_pt': 'pt_PT.ISO8859-1', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', 'romanian': 'ro_RO.ISO8859-2', @@ -1250,7 +1291,7 @@ def getpreferredencoding(do_setlocale = True): 'ru_ru': 'ru_RU.UTF-8', 'ru_ua': 'ru_UA.KOI8-U', 'rumanian': 'ro_RO.ISO8859-2', - 'russian': 'ru_RU.ISO8859-5', + 'russian': 'ru_RU.KOI8-R', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', 'sa_in': 'sa_IN.UTF-8', @@ -1262,12 +1303,14 @@ def getpreferredencoding(do_setlocale = True): 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8 at latin', + 'sgs_lt': 'sgs_LT.UTF-8', 'sh': 'sr_RS.UTF-8 at latin', 'sh_ba.iso88592 at bosnia': 'sr_CS.ISO8859-2', 'sh_hr': 'sh_HR.ISO8859-2', 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8 at latin', + 'shn_mm': 'shn_MM.UTF-8', 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', @@ -1281,6 +1324,7 @@ def getpreferredencoding(do_setlocale = True): 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', 'so_dj': 'so_DJ.ISO8859-1', 'so_et': 'so_ET.UTF-8', 'so_ke': 'so_KE.ISO8859-1', @@ -1327,6 +1371,7 @@ def getpreferredencoding(do_setlocale = True): 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', 'te': 'te_IN.UTF-8', 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', @@ -1336,6 +1381,7 @@ def getpreferredencoding(do_setlocale = True): 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', 'ti_er': 'ti_ER.UTF-8', 'ti_et': 'ti_ET.UTF-8', 'tig_er': 'tig_ER.UTF-8', @@ -1344,6 +1390,8 @@ def getpreferredencoding(do_setlocale = True): 'tl_ph': 'tl_PH.ISO8859-1', 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', 'tr': 'tr_TR.ISO8859-9', 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', @@ -1386,6 +1434,7 @@ def getpreferredencoding(do_setlocale = True): 'yi_us': 'yi_US.CP1255', 'yo_ng': 'yo_NG.UTF-8', 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index d93b3ad048be..e2c2178ae6cc 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -441,7 +441,7 @@ def test_latin_modifier(self): def test_valencia_modifier(self): self.check('ca_ES.UTF-8 at valencia', 'ca_ES.UTF-8 at valencia') - self.check('ca_ES at valencia', 'ca_ES.ISO8859-15 at valencia') + self.check('ca_ES at valencia', 'ca_ES.UTF-8 at valencia') self.check('ca at valencia', 'ca_ES.ISO8859-1 at valencia') def test_devanagari_modifier(self): diff --git a/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst new file mode 100644 index 000000000000..2342cb781926 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst @@ -0,0 +1 @@ +Updated alias mapping with glibc 2.27 supported locales. From webhook-mailer at python.org Sun May 6 03:20:16 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 06 May 2018 07:20:16 -0000 Subject: [Python-checkins] [3.7] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708) (GH-6713) Message-ID: https://github.com/python/cpython/commit/6049bda21b607acc90bbabcc604997e794e8aee1 commit: 6049bda21b607acc90bbabcc604997e794e8aee1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-05-06T10:20:12+03:00 summary: [3.7] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708) (GH-6713) (cherry picked from commit cedc9b74202d8c1ae39bca261cbb45d42ed54d45) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst M Lib/locale.py M Lib/test/test_locale.py diff --git a/Lib/locale.py b/Lib/locale.py index 18079e73ad69..f3d3973d038c 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -846,6 +846,16 @@ def getpreferredencoding(do_setlocale = True): # # SS 2014-10-01: # Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 3.6.5 +# and older): +# +# updated 'ca_es at valencia' -> 'ca_ES.ISO8859-15 at valencia' to 'ca_ES.UTF-8 at valencia' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' locale_alias = { 'a3': 'az_AZ.KOI8-C', @@ -856,10 +866,13 @@ def getpreferredencoding(do_setlocale = True): 'aa_et': 'aa_ET.UTF-8', 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', 'ar_ae': 'ar_AE.ISO8859-6', @@ -877,6 +890,7 @@ def getpreferredencoding(do_setlocale = True): 'ar_qa': 'ar_QA.ISO8859-6', 'ar_sa': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', 'ar_sy': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', 'ar_ye': 'ar_YE.ISO8859-6', @@ -888,6 +902,7 @@ def getpreferredencoding(do_setlocale = True): 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', 'be': 'be_BY.CP1251', 'be at latin': 'be_BY.UTF-8 at latin', 'be_bg.utf8': 'bg_BG.UTF-8', @@ -898,7 +913,10 @@ def getpreferredencoding(do_setlocale = True): 'ber_ma': 'ber_MA.UTF-8', 'bg': 'bg_BG.CP1251', 'bg_bg': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', 'bo_cn': 'bo_CN.UTF-8', @@ -923,13 +941,17 @@ def getpreferredencoding(do_setlocale = True): 'ca': 'ca_ES.ISO8859-1', 'ca_ad': 'ca_AD.ISO8859-1', 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es at valencia': 'ca_ES.ISO8859-15 at valencia', + 'ca_es at valencia': 'ca_ES.UTF-8 at valencia', 'ca_fr': 'ca_FR.ISO8859-1', 'ca_it': 'ca_IT.ISO8859-1', 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', 'cextend': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', @@ -951,6 +973,7 @@ def getpreferredencoding(do_setlocale = True): 'de_be': 'de_BE.ISO8859-1', 'de_ch': 'de_CH.ISO8859-1', 'de_de': 'de_DE.ISO8859-1', + 'de_it': 'de_IT.ISO8859-1', 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', 'deutsch': 'de_DE.ISO8859-1', @@ -977,10 +1000,12 @@ def getpreferredencoding(do_setlocale = True): 'en_gb': 'en_GB.ISO8859-1', 'en_hk': 'en_HK.ISO8859-1', 'en_ie': 'en_IE.ISO8859-1', + 'en_il': 'en_IL.UTF-8', 'en_in': 'en_IN.ISO8859-1', 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', 'en_sg': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', 'en_us': 'en_US.ISO8859-1', @@ -991,6 +1016,7 @@ def getpreferredencoding(do_setlocale = True): 'en_zw.utf8': 'en_ZS.UTF-8', 'eng_gb': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_US.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', 'english_united-states.437': 'C', @@ -1071,12 +1097,14 @@ def getpreferredencoding(do_setlocale = True): 'gv': 'gv_GB.ISO8859-1', 'gv_gb': 'gv_GB.ISO8859-1', 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', 'hebrew': 'he_IL.ISO8859-8', 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', 'hne': 'hne_IN.UTF-8', 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', @@ -1131,7 +1159,8 @@ def getpreferredencoding(do_setlocale = True): 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', - 'kk_kz': 'kk_KZ.RK1048', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', 'km_kh': 'km_KH.UTF-8', @@ -1157,6 +1186,7 @@ def getpreferredencoding(do_setlocale = True): 'li_nl': 'li_NL.UTF-8', 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', 'lo_la.cp1133': 'lo_LA.IBM-CP1133', @@ -1166,13 +1196,18 @@ def getpreferredencoding(do_setlocale = True): 'lt_lt': 'lt_LT.ISO8859-13', 'lv': 'lv_LV.ISO8859-13', 'lv_lv': 'lv_LV.ISO8859-13', + 'lzh_tw': 'lzh_TW.UTF-8', 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', 'mg_mg': 'mg_MG.ISO8859-15', 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', 'ml': 'ml_IN.UTF-8', @@ -1186,7 +1221,7 @@ def getpreferredencoding(do_setlocale = True): 'mt': 'mt_MT.ISO8859-3', 'mt_mt': 'mt_MT.ISO8859-3', 'my_mm': 'my_MM.UTF-8', - 'nan_tw at latin': 'nan_TW.UTF-8 at latin', + 'nan_tw': 'nan_TW.UTF-8', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', 'nds_de': 'nds_DE.UTF-8', @@ -1225,6 +1260,8 @@ def getpreferredencoding(do_setlocale = True): 'pa_in': 'pa_IN.UTF-8', 'pa_pk': 'pa_PK.UTF-8', 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', 'pd_us': 'pd_US.ISO8859-1', @@ -1243,6 +1280,8 @@ def getpreferredencoding(do_setlocale = True): 'pt': 'pt_PT.ISO8859-1', 'pt_br': 'pt_BR.ISO8859-1', 'pt_pt': 'pt_PT.ISO8859-1', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', 'romanian': 'ro_RO.ISO8859-2', @@ -1250,7 +1289,7 @@ def getpreferredencoding(do_setlocale = True): 'ru_ru': 'ru_RU.UTF-8', 'ru_ua': 'ru_UA.KOI8-U', 'rumanian': 'ro_RO.ISO8859-2', - 'russian': 'ru_RU.ISO8859-5', + 'russian': 'ru_RU.KOI8-R', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', 'sa_in': 'sa_IN.UTF-8', @@ -1262,12 +1301,14 @@ def getpreferredencoding(do_setlocale = True): 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8 at latin', + 'sgs_lt': 'sgs_LT.UTF-8', 'sh': 'sr_RS.UTF-8 at latin', 'sh_ba.iso88592 at bosnia': 'sr_CS.ISO8859-2', 'sh_hr': 'sh_HR.ISO8859-2', 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8 at latin', + 'shn_mm': 'shn_MM.UTF-8', 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', @@ -1281,6 +1322,7 @@ def getpreferredencoding(do_setlocale = True): 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', 'so_dj': 'so_DJ.ISO8859-1', 'so_et': 'so_ET.UTF-8', 'so_ke': 'so_KE.ISO8859-1', @@ -1327,6 +1369,7 @@ def getpreferredencoding(do_setlocale = True): 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', 'te': 'te_IN.UTF-8', 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', @@ -1336,6 +1379,7 @@ def getpreferredencoding(do_setlocale = True): 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', 'ti_er': 'ti_ER.UTF-8', 'ti_et': 'ti_ET.UTF-8', 'tig_er': 'tig_ER.UTF-8', @@ -1344,6 +1388,8 @@ def getpreferredencoding(do_setlocale = True): 'tl_ph': 'tl_PH.ISO8859-1', 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', 'tr': 'tr_TR.ISO8859-9', 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', @@ -1386,6 +1432,7 @@ def getpreferredencoding(do_setlocale = True): 'yi_us': 'yi_US.CP1255', 'yo_ng': 'yo_NG.UTF-8', 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index d93b3ad048be..e2c2178ae6cc 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -441,7 +441,7 @@ def test_latin_modifier(self): def test_valencia_modifier(self): self.check('ca_ES.UTF-8 at valencia', 'ca_ES.UTF-8 at valencia') - self.check('ca_ES at valencia', 'ca_ES.ISO8859-15 at valencia') + self.check('ca_ES at valencia', 'ca_ES.UTF-8 at valencia') self.check('ca at valencia', 'ca_ES.ISO8859-1 at valencia') def test_devanagari_modifier(self): diff --git a/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst new file mode 100644 index 000000000000..2342cb781926 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst @@ -0,0 +1 @@ +Updated alias mapping with glibc 2.27 supported locales. From webhook-mailer at python.org Sun May 6 03:20:44 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 06 May 2018 07:20:44 -0000 Subject: [Python-checkins] [3.6] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708) (GH-6714) Message-ID: https://github.com/python/cpython/commit/b1c70d0ffbb235def1deab62a744ffd9b5253924 commit: b1c70d0ffbb235def1deab62a744ffd9b5253924 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-05-06T10:20:42+03:00 summary: [3.6] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708) (GH-6714) (cherry picked from commit cedc9b74202d8c1ae39bca261cbb45d42ed54d45) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst M Lib/locale.py M Lib/test/test_locale.py diff --git a/Lib/locale.py b/Lib/locale.py index 4de0090ed9dd..e85f34ea1996 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -828,6 +828,16 @@ def getpreferredencoding(do_setlocale = True): # # SS 2014-10-01: # Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 3.6.5 +# and older): +# +# updated 'ca_es at valencia' -> 'ca_ES.ISO8859-15 at valencia' to 'ca_ES.UTF-8 at valencia' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' locale_alias = { 'a3': 'az_AZ.KOI8-C', @@ -838,10 +848,13 @@ def getpreferredencoding(do_setlocale = True): 'aa_et': 'aa_ET.UTF-8', 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', 'ar_ae': 'ar_AE.ISO8859-6', @@ -859,6 +872,7 @@ def getpreferredencoding(do_setlocale = True): 'ar_qa': 'ar_QA.ISO8859-6', 'ar_sa': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', 'ar_sy': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', 'ar_ye': 'ar_YE.ISO8859-6', @@ -870,6 +884,7 @@ def getpreferredencoding(do_setlocale = True): 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', 'be': 'be_BY.CP1251', 'be at latin': 'be_BY.UTF-8 at latin', 'be_bg.utf8': 'bg_BG.UTF-8', @@ -880,7 +895,10 @@ def getpreferredencoding(do_setlocale = True): 'ber_ma': 'ber_MA.UTF-8', 'bg': 'bg_BG.CP1251', 'bg_bg': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', 'bo_cn': 'bo_CN.UTF-8', @@ -905,13 +923,17 @@ def getpreferredencoding(do_setlocale = True): 'ca': 'ca_ES.ISO8859-1', 'ca_ad': 'ca_AD.ISO8859-1', 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es at valencia': 'ca_ES.ISO8859-15 at valencia', + 'ca_es at valencia': 'ca_ES.UTF-8 at valencia', 'ca_fr': 'ca_FR.ISO8859-1', 'ca_it': 'ca_IT.ISO8859-1', 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', 'cextend': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', @@ -933,6 +955,7 @@ def getpreferredencoding(do_setlocale = True): 'de_be': 'de_BE.ISO8859-1', 'de_ch': 'de_CH.ISO8859-1', 'de_de': 'de_DE.ISO8859-1', + 'de_it': 'de_IT.ISO8859-1', 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', 'deutsch': 'de_DE.ISO8859-1', @@ -959,10 +982,12 @@ def getpreferredencoding(do_setlocale = True): 'en_gb': 'en_GB.ISO8859-1', 'en_hk': 'en_HK.ISO8859-1', 'en_ie': 'en_IE.ISO8859-1', + 'en_il': 'en_IL.UTF-8', 'en_in': 'en_IN.ISO8859-1', 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', 'en_sg': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', 'en_us': 'en_US.ISO8859-1', @@ -973,6 +998,7 @@ def getpreferredencoding(do_setlocale = True): 'en_zw.utf8': 'en_ZS.UTF-8', 'eng_gb': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_US.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', 'english_united-states.437': 'C', @@ -1053,12 +1079,14 @@ def getpreferredencoding(do_setlocale = True): 'gv': 'gv_GB.ISO8859-1', 'gv_gb': 'gv_GB.ISO8859-1', 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', 'hebrew': 'he_IL.ISO8859-8', 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', 'hne': 'hne_IN.UTF-8', 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', @@ -1113,7 +1141,8 @@ def getpreferredencoding(do_setlocale = True): 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', - 'kk_kz': 'kk_KZ.RK1048', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', 'km_kh': 'km_KH.UTF-8', @@ -1139,6 +1168,7 @@ def getpreferredencoding(do_setlocale = True): 'li_nl': 'li_NL.UTF-8', 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', 'lo_la.cp1133': 'lo_LA.IBM-CP1133', @@ -1148,13 +1178,18 @@ def getpreferredencoding(do_setlocale = True): 'lt_lt': 'lt_LT.ISO8859-13', 'lv': 'lv_LV.ISO8859-13', 'lv_lv': 'lv_LV.ISO8859-13', + 'lzh_tw': 'lzh_TW.UTF-8', 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', 'mg_mg': 'mg_MG.ISO8859-15', 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', 'ml': 'ml_IN.UTF-8', @@ -1168,7 +1203,7 @@ def getpreferredencoding(do_setlocale = True): 'mt': 'mt_MT.ISO8859-3', 'mt_mt': 'mt_MT.ISO8859-3', 'my_mm': 'my_MM.UTF-8', - 'nan_tw at latin': 'nan_TW.UTF-8 at latin', + 'nan_tw': 'nan_TW.UTF-8', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', 'nds_de': 'nds_DE.UTF-8', @@ -1207,6 +1242,8 @@ def getpreferredencoding(do_setlocale = True): 'pa_in': 'pa_IN.UTF-8', 'pa_pk': 'pa_PK.UTF-8', 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', 'pd_us': 'pd_US.ISO8859-1', @@ -1225,6 +1262,8 @@ def getpreferredencoding(do_setlocale = True): 'pt': 'pt_PT.ISO8859-1', 'pt_br': 'pt_BR.ISO8859-1', 'pt_pt': 'pt_PT.ISO8859-1', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', 'romanian': 'ro_RO.ISO8859-2', @@ -1232,7 +1271,7 @@ def getpreferredencoding(do_setlocale = True): 'ru_ru': 'ru_RU.UTF-8', 'ru_ua': 'ru_UA.KOI8-U', 'rumanian': 'ro_RO.ISO8859-2', - 'russian': 'ru_RU.ISO8859-5', + 'russian': 'ru_RU.KOI8-R', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', 'sa_in': 'sa_IN.UTF-8', @@ -1244,12 +1283,14 @@ def getpreferredencoding(do_setlocale = True): 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8 at latin', + 'sgs_lt': 'sgs_LT.UTF-8', 'sh': 'sr_RS.UTF-8 at latin', 'sh_ba.iso88592 at bosnia': 'sr_CS.ISO8859-2', 'sh_hr': 'sh_HR.ISO8859-2', 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8 at latin', + 'shn_mm': 'shn_MM.UTF-8', 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', @@ -1263,6 +1304,7 @@ def getpreferredencoding(do_setlocale = True): 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', 'so_dj': 'so_DJ.ISO8859-1', 'so_et': 'so_ET.UTF-8', 'so_ke': 'so_KE.ISO8859-1', @@ -1309,6 +1351,7 @@ def getpreferredencoding(do_setlocale = True): 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', 'te': 'te_IN.UTF-8', 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', @@ -1318,6 +1361,7 @@ def getpreferredencoding(do_setlocale = True): 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', 'ti_er': 'ti_ER.UTF-8', 'ti_et': 'ti_ET.UTF-8', 'tig_er': 'tig_ER.UTF-8', @@ -1326,6 +1370,8 @@ def getpreferredencoding(do_setlocale = True): 'tl_ph': 'tl_PH.ISO8859-1', 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', 'tr': 'tr_TR.ISO8859-9', 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', @@ -1368,6 +1414,7 @@ def getpreferredencoding(do_setlocale = True): 'yi_us': 'yi_US.CP1255', 'yo_ng': 'yo_NG.UTF-8', 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 650d7373d8e1..a5ec2c51c55d 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -430,7 +430,7 @@ def test_latin_modifier(self): def test_valencia_modifier(self): self.check('ca_ES.UTF-8 at valencia', 'ca_ES.UTF-8 at valencia') - self.check('ca_ES at valencia', 'ca_ES.ISO8859-15 at valencia') + self.check('ca_ES at valencia', 'ca_ES.UTF-8 at valencia') self.check('ca at valencia', 'ca_ES.ISO8859-1 at valencia') def test_devanagari_modifier(self): diff --git a/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst new file mode 100644 index 000000000000..2342cb781926 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst @@ -0,0 +1 @@ +Updated alias mapping with glibc 2.27 supported locales. From webhook-mailer at python.org Sun May 6 03:51:52 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 06 May 2018 07:51:52 -0000 Subject: [Python-checkins] [2.7] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708). (GH-6717) Message-ID: https://github.com/python/cpython/commit/a55ac801f749a731250f3c7c1db7d546d22ae032 commit: a55ac801f749a731250f3c7c1db7d546d22ae032 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-05-06T10:51:49+03:00 summary: [2.7] bpo-20087: Update locale alias mapping with glibc 2.27 supported locales. (GH-6708). (GH-6717) (cherry picked from commit cedc9b74202d8c1ae39bca261cbb45d42ed54d45) files: A Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst M Lib/locale.py M Lib/test/test_locale.py diff --git a/Lib/locale.py b/Lib/locale.py index 62aad5ae7bf9..51909f81e734 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -798,6 +798,17 @@ def getpreferredencoding(do_setlocale = True): # # SS 2014-10-01: # Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 2.7.15 +# and older): +# +# updated 'ca_es at valencia' -> 'ca_ES.ISO8859-15 at valencia' to 'ca_ES.UTF-8 at valencia' +# updated 'english.iso88591' -> 'en_EN.ISO8859-1' to 'en_US.ISO8859-1' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' locale_alias = { 'a3': 'az_AZ.KOI8-C', @@ -810,11 +821,14 @@ def getpreferredencoding(do_setlocale = True): 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', 'af_za.iso88591': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', 'american.iso88591': 'en_US.ISO8859-1', 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', 'ar_aa.iso88596': 'ar_AA.ISO8859-6', @@ -847,6 +861,7 @@ def getpreferredencoding(do_setlocale = True): 'ar_sa.iso88596': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', 'ar_sd.iso88596': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', 'ar_sy': 'ar_SY.ISO8859-6', 'ar_sy.iso88596': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', @@ -862,6 +877,7 @@ def getpreferredencoding(do_setlocale = True): 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', 'be': 'be_BY.CP1251', 'be at latin': 'be_BY.UTF-8 at latin', 'be_bg.utf8': 'bg_BG.UTF-8', @@ -879,7 +895,10 @@ def getpreferredencoding(do_setlocale = True): 'bg_bg.iso88595': 'bg_BG.ISO8859-5', 'bg_bg.koi8r': 'bg_BG.KOI8-R', 'bg_bg.microsoftcp1251': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', 'bo_cn': 'bo_CN.UTF-8', @@ -921,8 +940,8 @@ def getpreferredencoding(do_setlocale = True): 'ca_es.iso885915': 'ca_ES.ISO8859-15', 'ca_es.iso885915 at euro': 'ca_ES.ISO8859-15', 'ca_es.utf8 at euro': 'ca_ES.UTF-8', - 'ca_es at valencia': 'ca_ES.ISO8859-15 at valencia', 'ca_es at euro': 'ca_ES.ISO8859-15', + 'ca_es at valencia': 'ca_ES.UTF-8 at valencia', 'ca_fr': 'ca_FR.ISO8859-1', 'ca_fr.iso88591': 'ca_FR.ISO8859-1', 'ca_fr.iso885915': 'ca_FR.ISO8859-15', @@ -936,10 +955,14 @@ def getpreferredencoding(do_setlocale = True): 'ca_it.utf8 at euro': 'ca_IT.UTF-8', 'ca_it at euro': 'ca_IT.ISO8859-15', 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', 'cextend': 'en_US.ISO8859-1', 'cextend.en': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', @@ -996,6 +1019,7 @@ def getpreferredencoding(do_setlocale = True): 'de_de.iso885915 at euro': 'de_DE.ISO8859-15', 'de_de.utf8 at euro': 'de_DE.UTF-8', 'de_de at euro': 'de_DE.ISO8859-15', + 'de_it': 'de_IT.ISO8859-1', 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', 'de_lu.iso88591': 'de_LU.ISO8859-1', @@ -1030,6 +1054,8 @@ def getpreferredencoding(do_setlocale = True): 'en_ca': 'en_CA.ISO8859-1', 'en_ca.iso88591': 'en_CA.ISO8859-1', 'en_dk': 'en_DK.ISO8859-1', + 'en_dk.iso88591': 'en_DK.ISO8859-1', + 'en_dk.iso885915': 'en_DK.ISO8859-15', 'en_dl.utf8': 'en_DL.UTF-8', 'en_gb': 'en_GB.ISO8859-1', 'en_gb.88591': 'en_GB.ISO8859-1', @@ -1044,12 +1070,14 @@ def getpreferredencoding(do_setlocale = True): 'en_ie.iso885915 at euro': 'en_IE.ISO8859-15', 'en_ie.utf8 at euro': 'en_IE.UTF-8', 'en_ie at euro': 'en_IE.ISO8859-15', + 'en_il': 'en_IL.UTF-8', 'en_in': 'en_IN.ISO8859-1', 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', 'en_nz.iso88591': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', 'en_ph.iso88591': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', 'en_sg': 'en_SG.ISO8859-1', 'en_sg.iso88591': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', @@ -1073,7 +1101,7 @@ def getpreferredencoding(do_setlocale = True): 'eng_gb': 'en_GB.ISO8859-1', 'eng_gb.8859': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', - 'english.iso88591': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_US.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', 'english_uk.8859': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', @@ -1268,6 +1296,7 @@ def getpreferredencoding(do_setlocale = True): 'gv_gb.iso885915': 'gv_GB.ISO8859-15', 'gv_gb at euro': 'gv_GB.ISO8859-15', 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', 'he_il.cp1255': 'he_IL.CP1255', @@ -1278,6 +1307,7 @@ def getpreferredencoding(do_setlocale = True): 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', 'hne': 'hne_IN.UTF-8', 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', @@ -1361,7 +1391,8 @@ def getpreferredencoding(do_setlocale = True): 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', - 'kk_kz': 'kk_KZ.RK1048', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', 'kl_gl.iso88591': 'kl_GL.ISO8859-1', @@ -1379,6 +1410,7 @@ def getpreferredencoding(do_setlocale = True): 'korean.euc': 'ko_KR.eucKR', 'ks': 'ks_IN.UTF-8', 'ks_in': 'ks_IN.UTF-8', + 'ks_in.utf8 at devanagari': 'ks_IN.UTF-8 at devanagari', 'ks_in at devanagari': 'ks_IN.UTF-8 at devanagari', 'ks_in at devanagari.utf8': 'ks_IN.UTF-8 at devanagari', 'ku_tr': 'ku_TR.ISO8859-9', @@ -1396,6 +1428,7 @@ def getpreferredencoding(do_setlocale = True): 'li_nl': 'li_NL.UTF-8', 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', 'lo_la.cp1133': 'lo_LA.IBM-CP1133', @@ -1409,14 +1442,19 @@ def getpreferredencoding(do_setlocale = True): 'lv_lv': 'lv_LV.ISO8859-13', 'lv_lv.iso885913': 'lv_LV.ISO8859-13', 'lv_lv.iso88594': 'lv_LV.ISO8859-4', + 'lzh_tw': 'lzh_TW.UTF-8', 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', 'mg_mg': 'mg_MG.ISO8859-15', 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', 'mi_nz.iso88591': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', 'mk_mk.cp1251': 'mk_MK.CP1251', @@ -1435,7 +1473,7 @@ def getpreferredencoding(do_setlocale = True): 'mt_mt': 'mt_MT.ISO8859-3', 'mt_mt.iso88593': 'mt_MT.ISO8859-3', 'my_mm': 'my_MM.UTF-8', - 'nan_tw at latin': 'nan_TW.UTF-8 at latin', + 'nan_tw': 'nan_TW.UTF-8', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', 'nb_no.88591': 'nb_NO.ISO8859-1', @@ -1509,6 +1547,8 @@ def getpreferredencoding(do_setlocale = True): 'pa_in': 'pa_IN.UTF-8', 'pa_pk': 'pa_PK.UTF-8', 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', 'pd_de.iso88591': 'pd_DE.ISO8859-1', @@ -1549,6 +1589,8 @@ def getpreferredencoding(do_setlocale = True): 'pt_pt.iso885915 at euro': 'pt_PT.ISO8859-15', 'pt_pt.utf8 at euro': 'pt_PT.UTF-8', 'pt_pt at euro': 'pt_PT.ISO8859-15', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', 'ro_ro.iso88592': 'ro_RO.ISO8859-2', @@ -1565,7 +1607,7 @@ def getpreferredencoding(do_setlocale = True): 'ru_ua.koi8u': 'ru_UA.KOI8-U', 'ru_ua.microsoftcp1251': 'ru_UA.CP1251', 'rumanian': 'ro_RO.ISO8859-2', - 'russian': 'ru_RU.ISO8859-5', + 'russian': 'ru_RU.KOI8-R', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', 'rw_rw.iso88591': 'rw_RW.ISO8859-1', @@ -1575,17 +1617,20 @@ def getpreferredencoding(do_setlocale = True): 'sd': 'sd_IN.UTF-8', 'sd at devanagari': 'sd_IN.UTF-8 at devanagari', 'sd_in': 'sd_IN.UTF-8', + 'sd_in.utf8 at devanagari': 'sd_IN.UTF-8 at devanagari', 'sd_in at devanagari': 'sd_IN.UTF-8 at devanagari', 'sd_in at devanagari.utf8': 'sd_IN.UTF-8 at devanagari', 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8 at latin', + 'sgs_lt': 'sgs_LT.UTF-8', 'sh': 'sr_RS.UTF-8 at latin', 'sh_ba.iso88592 at bosnia': 'sr_CS.ISO8859-2', 'sh_hr': 'sh_HR.ISO8859-2', 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8 at latin', + 'shn_mm': 'shn_MM.UTF-8', 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', @@ -1601,6 +1646,7 @@ def getpreferredencoding(do_setlocale = True): 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', 'so_dj': 'so_DJ.ISO8859-1', 'so_et': 'so_ET.UTF-8', 'so_ke': 'so_KE.ISO8859-1', @@ -1627,6 +1673,7 @@ def getpreferredencoding(do_setlocale = True): 'sr_cs at latn': 'sr_CS.UTF-8 at latin', 'sr_me': 'sr_ME.UTF-8', 'sr_rs': 'sr_RS.UTF-8', + 'sr_rs.utf8 at latn': 'sr_RS.UTF-8 at latin', 'sr_rs at latin': 'sr_RS.UTF-8 at latin', 'sr_rs at latn': 'sr_RS.UTF-8 at latin', 'sr_sp': 'sr_CS.ISO8859-2', @@ -1668,6 +1715,7 @@ def getpreferredencoding(do_setlocale = True): 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', 'te': 'te_IN.UTF-8', 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', @@ -1679,6 +1727,7 @@ def getpreferredencoding(do_setlocale = True): 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', 'ti_er': 'ti_ER.UTF-8', 'ti_et': 'ti_ET.UTF-8', 'tig_er': 'tig_ER.UTF-8', @@ -1689,6 +1738,8 @@ def getpreferredencoding(do_setlocale = True): 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', 'tn_za.iso885915': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', 'tr': 'tr_TR.ISO8859-9', 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', @@ -1750,6 +1801,7 @@ def getpreferredencoding(do_setlocale = True): 'yi_us.microsoftcp1255': 'yi_US.CP1255', 'yo_ng': 'yo_NG.UTF-8', 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 563ddb144fbb..6070882a37f7 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -425,7 +425,7 @@ def test_latin_modifier(self): def test_valencia_modifier(self): self.check('ca_ES.UTF-8 at valencia', 'ca_ES.UTF-8 at valencia') - self.check('ca_ES at valencia', 'ca_ES.ISO8859-15 at valencia') + self.check('ca_ES at valencia', 'ca_ES.UTF-8 at valencia') self.check('ca at valencia', 'ca_ES.ISO8859-1 at valencia') def test_devanagari_modifier(self): diff --git a/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst new file mode 100644 index 000000000000..2342cb781926 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-18-02-24.bpo-20087.lJrvXL.rst @@ -0,0 +1 @@ +Updated alias mapping with glibc 2.27 supported locales. From webhook-mailer at python.org Sun May 6 03:52:41 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 06 May 2018 07:52:41 -0000 Subject: [Python-checkins] Remove mojibake in the locale aliases mapping. (GH-6716) Message-ID: https://github.com/python/cpython/commit/a3f19c3f52ddff85dd52eaa01b77b2d50cc9af3f commit: a3f19c3f52ddff85dd52eaa01b77b2d50cc9af3f branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-06T10:52:38+03:00 summary: Remove mojibake in the locale aliases mapping. (GH-6716) files: M Lib/locale.py M Tools/i18n/makelocalealias.py diff --git a/Lib/locale.py b/Lib/locale.py index 876d2eb1e123..f3d3973d038c 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -923,7 +923,6 @@ def getpreferredencoding(do_setlocale = True): 'bo_in': 'bo_IN.UTF-8', 'bokmal': 'nb_NO.ISO8859-1', 'bokm\xe5l': 'nb_NO.ISO8859-1', - 'bokm\xef\xbf\xbd': 'nb_NO.ISO8859-1', 'br': 'br_FR.ISO8859-1', 'br_fr': 'br_FR.ISO8859-1', 'brx_in': 'brx_IN.UTF-8', @@ -1072,7 +1071,6 @@ def getpreferredencoding(do_setlocale = True): 'fr_fr': 'fr_FR.ISO8859-1', 'fr_lu': 'fr_LU.ISO8859-1', 'fran\xe7ais': 'fr_FR.ISO8859-1', - 'fran\xef\xbf\xbdis': 'fr_FR.ISO8859-1', 'fre_fr': 'fr_FR.ISO8859-1', 'french': 'fr_FR.ISO8859-1', 'french.iso88591': 'fr_CH.ISO8859-1', diff --git a/Tools/i18n/makelocalealias.py b/Tools/i18n/makelocalealias.py index c7ecacec3877..b407a8a643be 100755 --- a/Tools/i18n/makelocalealias.py +++ b/Tools/i18n/makelocalealias.py @@ -19,6 +19,9 @@ def parse(filename): with open(filename, encoding='latin1') as f: lines = list(f) + # Remove mojibake in /usr/share/X11/locale/locale.alias. + # b'\xef\xbf\xbd' == '\ufffd'.encode('utf-8') + lines = [line for line in lines if '\xef\xbf\xbd' not in line] data = {} for line in lines: line = line.strip() From solipsis at pitrou.net Sun May 6 05:12:32 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 06 May 2018 09:12:32 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=1 Message-ID: <20180506091232.1.1D60D0F1D69D1E3C@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_collections leaked [-7, 1, 0] memory blocks, sum=-6 test_functools leaked [0, 3, 1] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/refloginrpmZ', '--timeout', '7200'] From webhook-mailer at python.org Mon May 7 01:44:08 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Mon, 07 May 2018 05:44:08 -0000 Subject: [Python-checkins] [2.7] bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) (GH-6712) Message-ID: https://github.com/python/cpython/commit/c40eeeb5e69df12a5f46edc7ba82ec75c7d1b820 commit: c40eeeb5e69df12a5f46edc7ba82ec75c7d1b820 branch: 2.7 author: Andr?s Delfino committer: Serhiy Storchaka date: 2018-05-07T08:44:03+03:00 summary: [2.7] bpo-33422: Fix quotation marks getting deleted when looking up byte/string literals on pydoc. (GH-6701) (GH-6712) Also update the list of string prefixes. (cherry picked from commit b2043bbe6034b53f5ad337887f4741b74b70b00d) files: A Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst M Lib/pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index b4b190f3f9a6..62cc262ccb83 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1647,8 +1647,9 @@ class Helper: } # Either add symbols to this dictionary or to the symbols dictionary # directly: Whichever is easier. They are merged later. + _strprefixes = tuple(p + q for p in ('b', 'r', 'u') for q in ("'", '"')) _symbols_inverse = { - 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'), + 'STRINGS' : ("'", "'''", '"""', '"') + _strprefixes, 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&', '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'), 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'), @@ -1811,7 +1812,12 @@ def interact(self): if not request: break except (KeyboardInterrupt, EOFError): break - request = strip(replace(request, '"', '', "'", '')) + request = strip(request) + # Make sure significant trailing quotation marks of literals don't + # get deleted while cleaning input + if (len(request) > 2 and request[0] == request[-1] in ("'", '"') + and request[0] not in request[1:-1]): + request = request[1:-1] if lower(request) in ('q', 'quit'): break self.help(request) diff --git a/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst new file mode 100644 index 000000000000..0d284d508f10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-05-09-53-05.bpo-33422.4FtQ0q.rst @@ -0,0 +1,2 @@ +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andr?s Delfino. From solipsis at pitrou.net Mon May 7 05:08:07 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 07 May 2018 09:08:07 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=9 Message-ID: <20180507090807.1.94DBBF4B31CE76AA@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 7, 0] memory blocks, sum=7 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [-2, 2, -2] memory blocks, sum=-2 test_multiprocessing_spawn leaked [-2, 2, 0] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogH_5Sg2', '--timeout', '7200'] From lp_benchmark_robot at intel.com Mon May 7 21:08:56 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 7 May 2018 18:08:56 -0700 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-05-07 Message-ID: Results for project python/master, build date: 2018-05-07 03:03:02-07:00. - commit: a3f19c3 - previous commit: 9d3627e - revision date: 2018-05-06 10:52:38+03:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.667% | +0.216% | +8.508% | +7.477% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 4.250% | -0.197% | +23.585% | +11.498% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 2.256% | -1.052% | +24.798% | +11.532% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 0.949% | +0.202% | +23.852% | +7.603% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 2.933% | +0.341% | +10.109% | +14.107% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.541% | +0.313% | +12.428% | +9.140% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.897% | -0.026% | +9.404% | +9.705% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.724% | -0.191% | -1.578% | +9.329% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 3.314% | +0.018% | +11.206% | +17.030% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 1.568% | -0.005% | +21.783% | +12.026% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.112% | +0.554% | +5.807% | +5.761% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.384% | -0.055% | +7.083% | +3.746% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.083% | +0.153% | +2.718% | +7.010% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.139% | +0.022% | +13.677% | +9.727% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.985% | -0.857% | +12.033% | +8.867% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 5.988% | +1.076% | +4.936% | +11.735% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.985% | -0.306% | +11.109% | +12.166% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 2.608% | -0.007% | +11.398% | +11.528% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.689% | -0.354% | +1.920% | +10.123% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 3.842% | -0.494% | -5.633% | +17.002% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.361% | +0.393% | +18.543% | +11.843% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 3.126% | +0.493% | +47.786% | +10.969% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.354% | +1.200% | +13.320% | +12.777% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.560% | +0.098% | +15.719% | +14.379% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 6.598% | +2.836% | +5.502% | +14.836% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 1.293% | -0.148% | +4.231% | +6.183% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.831% | +0.036% | -0.740% | -0.936% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 0.611% | +0.363% | +6.052% | +7.117% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.311% | -0.396% | -1.509% | +10.857% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 2.968% | -0.504% | -0.154% | +23.811% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.317% | -0.083% | +4.246% | +20.767% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.802% | -0.050% | +6.010% | +19.028% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 5.984% | -1.131% | +10.343% | +11.770% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.060% | +0.016% | +0.254% | +9.991% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.113% | +0.030% | +18.456% | +5.707% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.086% | -0.003% | +5.459% | +5.785% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.953% | -0.328% | +10.115% | +13.328% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.525% | +1.372% | +4.003% | +12.421% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.376% | +0.149% | -1.988% | +13.378% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 1.120% | +1.791% | -2.282% | +4.976% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 1.488% | +0.539% | +3.719% | +8.911% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.382% | +0.036% | +9.559% | +14.232% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.646% | -0.140% | -1.486% | +3.666% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 3.447% | +0.635% | +21.884% | +10.805% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.297% | -0.159% | +4.931% | +5.159% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 1.882% | +0.610% | +14.601% | +6.648% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.593% | +0.086% | -4.584% | +1.323% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.793% | -0.119% | +3.439% | +6.695% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.335% | -0.155% | +6.508% | +6.572% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.486% | +0.318% | +7.722% | +4.694% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 3.411% | -1.322% | -0.844% | +11.275% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 3.075% | -0.248% | +17.128% | +8.434% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 1.490% | -0.043% | +18.058% | +6.485% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 3.928% | +0.066% | +18.935% | +9.187% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 5.629% | +1.276% | +16.351% | +11.547% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 4.403% | -0.139% | +18.109% | +9.755% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 1.294% | -0.306% | +6.819% | +6.048% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 0.776% | +0.312% | +2.576% | +2.579% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 4.303% | +2.728% | +8.622% | +21.852% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 0.815% | +0.057% | -1.807% | +16.402% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 2.344% | +0.038% | +6.294% | +9.539% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 0.892% | -0.313% | +2.637% | +12.716% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 1.913% | +0.425% | +2.572% | +8.928% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 4.170% | +0.201% | -9.111% | +12.550% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.073% | +0.027% | +4.379% | +12.101% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-05-07 Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From webhook-mailer at python.org Tue May 8 00:48:54 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 08 May 2018 04:48:54 -0000 Subject: [Python-checkins] bpo-33441: Make the sigset_t converter available in other modules. (GH-6720) Message-ID: https://github.com/python/cpython/commit/d54cfb160c626626394e2f171d3ccfe03309f34e commit: d54cfb160c626626394e2f171d3ccfe03309f34e branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-08T07:48:50+03:00 summary: bpo-33441: Make the sigset_t converter available in other modules. (GH-6720) * Expose the sigset_t converter via private API _Py_Sigset_Converter(). * Use Argument Clinic for parsing sigset_t in signalmodule.c. * Raise ValueError instead OverflowError for integers out of the C long range. Based on patch by Pablo Galindo Salgado. files: M Lib/test/test_signal.py M Modules/clinic/signalmodule.c.h M Modules/posixmodule.c M Modules/posixmodule.h M Modules/signalmodule.c diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 7ce89f61ab3e..354c3fde168c 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -943,6 +943,10 @@ def test_pthread_sigmask_arguments(self): self.assertRaises(OSError, signal.pthread_sigmask, 1700, []) with self.assertRaises(ValueError): signal.pthread_sigmask(signal.SIG_BLOCK, [signal.NSIG]) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [0]) + with self.assertRaises(ValueError): + signal.pthread_sigmask(signal.SIG_BLOCK, [1<<1000]) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index eca2da10ad33..4d7ac38372f2 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -278,17 +278,17 @@ PyDoc_STRVAR(signal_pthread_sigmask__doc__, {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, METH_FASTCALL, signal_pthread_sigmask__doc__}, static PyObject * -signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask); +signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask); static PyObject * signal_pthread_sigmask(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int how; - PyObject *mask; + sigset_t mask; - if (!_PyArg_ParseStack(args, nargs, "iO:pthread_sigmask", - &how, &mask)) { + if (!_PyArg_ParseStack(args, nargs, "iO&:pthread_sigmask", + &how, _Py_Sigset_Converter, &mask)) { goto exit; } return_value = signal_pthread_sigmask_impl(module, how, mask); @@ -339,6 +339,24 @@ PyDoc_STRVAR(signal_sigwait__doc__, #define SIGNAL_SIGWAIT_METHODDEF \ {"sigwait", (PyCFunction)signal_sigwait, METH_O, signal_sigwait__doc__}, +static PyObject * +signal_sigwait_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwait(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!PyArg_Parse(arg, "O&:sigwait", _Py_Sigset_Converter, &sigset)) { + goto exit; + } + return_value = signal_sigwait_impl(module, sigset); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGWAIT) */ #if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) @@ -379,6 +397,24 @@ PyDoc_STRVAR(signal_sigwaitinfo__doc__, #define SIGNAL_SIGWAITINFO_METHODDEF \ {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, METH_O, signal_sigwaitinfo__doc__}, +static PyObject * +signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset); + +static PyObject * +signal_sigwaitinfo(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + sigset_t sigset; + + if (!PyArg_Parse(arg, "O&:sigwaitinfo", _Py_Sigset_Converter, &sigset)) { + goto exit; + } + return_value = signal_sigwaitinfo_impl(module, sigset); + +exit: + return return_value; +} + #endif /* defined(HAVE_SIGWAITINFO) */ #if defined(HAVE_SIGTIMEDWAIT) @@ -395,19 +431,18 @@ PyDoc_STRVAR(signal_sigtimedwait__doc__, {"sigtimedwait", (PyCFunction)signal_sigtimedwait, METH_FASTCALL, signal_sigtimedwait__doc__}, static PyObject * -signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, +signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, PyObject *timeout_obj); static PyObject * signal_sigtimedwait(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *sigset; + sigset_t sigset; PyObject *timeout_obj; - if (!_PyArg_UnpackStack(args, nargs, "sigtimedwait", - 2, 2, - &sigset, &timeout_obj)) { + if (!_PyArg_ParseStack(args, nargs, "O&O:sigtimedwait", + _Py_Sigset_Converter, &sigset, &timeout_obj)) { goto exit; } return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); @@ -499,4 +534,4 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=f35d79e0cfee3f1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=549f0efdc7405834 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 4ac6e7658999..a9b3917188c6 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1267,6 +1267,65 @@ PyLong_FromPy_off_t(Py_off_t offset) #endif } +#ifdef HAVE_SIGSET_T +/* Convert an iterable of integers to a sigset. + Return 1 on success, return 0 and raise an exception on error. */ +int +_Py_Sigset_Converter(PyObject *obj, void *addr) +{ + sigset_t *mask = (sigset_t *)addr; + PyObject *iterator, *item; + long signum; + int overflow; + + if (sigemptyset(mask)) { + /* Probably only if mask == NULL. */ + PyErr_SetFromErrno(PyExc_OSError); + return 0; + } + + iterator = PyObject_GetIter(obj); + if (iterator == NULL) { + return 0; + } + + while ((item = PyIter_Next(iterator)) != NULL) { + signum = PyLong_AsLongAndOverflow(item, &overflow); + Py_DECREF(item); + if (signum <= 0 || signum >= NSIG) { + if (overflow || signum != -1 || !PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, + "signal number %ld out of range", signum); + } + goto error; + } + if (sigaddset(mask, (int)signum)) { + if (errno != EINVAL) { + /* Probably impossible */ + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } + /* For backwards compatibility, allow idioms such as + * `range(1, NSIG)` but warn about invalid signal numbers + */ + const char msg[] = + "invalid signal number %ld, please use valid_signals()"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { + goto error; + } + } + } + if (!PyErr_Occurred()) { + Py_DECREF(iterator); + return 1; + } + +error: + Py_DECREF(iterator); + return 0; +} +#endif /* HAVE_SIGSET_T */ + #ifdef MS_WINDOWS static int diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 1ec1833825f5..1e00562abc33 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -17,8 +17,17 @@ PyAPI_FUNC(PyObject *) _PyLong_FromGid(gid_t); PyAPI_FUNC(int) _Py_Uid_Converter(PyObject *, void *); PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, void *); #endif /* MS_WINDOWS */ + +#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ + defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) +# define HAVE_SIGSET_T #endif +#ifdef HAVE_SIGSET_T +PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); +#endif /* HAVE_SIGSET_T */ +#endif /* Py_LIMITED_API */ + #ifdef __cplusplus } #endif diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 003bbb60e387..818df7d46e4c 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -59,6 +59,14 @@ module signal [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ +/*[python input] + +class sigset_t_converter(CConverter): + type = 'sigset_t' + converter = '_Py_Sigset_Converter' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/ /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -808,69 +816,6 @@ signal_getitimer_impl(PyObject *module, int which) #endif -#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ - defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -/* Convert an iterable to a sigset. - Return 0 on success, return -1 and raise an exception on error. */ - -static int -iterable_to_sigset(PyObject *iterable, sigset_t *mask) -{ - int result = -1; - PyObject *iterator, *item; - long signum; - - sigemptyset(mask); - - iterator = PyObject_GetIter(iterable); - if (iterator == NULL) - goto error; - - while (1) - { - item = PyIter_Next(iterator); - if (item == NULL) { - if (PyErr_Occurred()) - goto error; - else - break; - } - - signum = PyLong_AsLong(item); - Py_DECREF(item); - if (signum == -1 && PyErr_Occurred()) - goto error; - if (0 < signum && signum < NSIG) { - if (sigaddset(mask, (int)signum)) { - if (errno != EINVAL) { - /* Probably impossible */ - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - /* For backwards compatibility, allow idioms such as - * `range(1, NSIG)` but warn about invalid signal numbers - */ - const char *msg = - "invalid signal number %ld, please use valid_signals()"; - if (PyErr_WarnFormat(PyExc_RuntimeWarning, 1, msg, signum)) { - goto error; - } - } - } - else { - PyErr_Format(PyExc_ValueError, - "signal number %ld out of range", signum); - goto error; - } - } - result = 0; - -error: - Py_XDECREF(iterator); - return result; -} -#endif - #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) static PyObject* sigset_to_set(sigset_t mask) @@ -913,23 +858,20 @@ sigset_to_set(sigset_t mask) signal.pthread_sigmask how: int - mask: object + mask: sigset_t / Fetch and/or change the signal mask of the calling thread. [clinic start generated code]*/ static PyObject * -signal_pthread_sigmask_impl(PyObject *module, int how, PyObject *mask) -/*[clinic end generated code: output=ff640fe092bc9181 input=f3b7d7a61b7b8283]*/ +signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask) +/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/ { - sigset_t newmask, previous; + sigset_t previous; int err; - if (iterable_to_sigset(mask, &newmask)) - return NULL; - - err = pthread_sigmask(how, &newmask, &previous); + err = pthread_sigmask(how, &mask, &previous); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -977,7 +919,7 @@ signal_sigpending_impl(PyObject *module) /*[clinic input] signal.sigwait - sigset: object + sigset: sigset_t / Wait for a signal. @@ -988,17 +930,13 @@ and returns the signal number. [clinic start generated code]*/ static PyObject * -signal_sigwait(PyObject *module, PyObject *sigset) -/*[clinic end generated code: output=557173647424f6e4 input=11af2d82d83c2e94]*/ +signal_sigwait_impl(PyObject *module, sigset_t sigset) +/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/ { - sigset_t set; int err, signum; - if (iterable_to_sigset(sigset, &set)) - return NULL; - Py_BEGIN_ALLOW_THREADS - err = sigwait(&set, &signum); + err = sigwait(&sigset, &signum); Py_END_ALLOW_THREADS if (err) { errno = err; @@ -1113,7 +1051,7 @@ fill_siginfo(siginfo_t *si) /*[clinic input] signal.sigwaitinfo - sigset: object + sigset: sigset_t / Wait synchronously until one of the signals in *sigset* is delivered. @@ -1122,20 +1060,16 @@ Returns a struct_siginfo containing information about the signal. [clinic start generated code]*/ static PyObject * -signal_sigwaitinfo(PyObject *module, PyObject *sigset) -/*[clinic end generated code: output=c40f27b269cd2309 input=f3779a74a991e171]*/ +signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset) +/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/ { - sigset_t set; siginfo_t si; int err; int async_err = 0; - if (iterable_to_sigset(sigset, &set)) - return NULL; - do { Py_BEGIN_ALLOW_THREADS - err = sigwaitinfo(&set, &si); + err = sigwaitinfo(&sigset, &si); Py_END_ALLOW_THREADS } while (err == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -1152,7 +1086,7 @@ signal_sigwaitinfo(PyObject *module, PyObject *sigset) /*[clinic input] signal.sigtimedwait - sigset: object + sigset: sigset_t timeout as timeout_obj: object / @@ -1162,12 +1096,11 @@ The timeout is specified in seconds, with floating point numbers allowed. [clinic start generated code]*/ static PyObject * -signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, +signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, PyObject *timeout_obj) -/*[clinic end generated code: output=f7eff31e679f4312 input=53fd4ea3e3724eb8]*/ +/*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/ { struct timespec ts; - sigset_t set; siginfo_t si; int res; _PyTime_t timeout, deadline, monotonic; @@ -1181,9 +1114,6 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, return NULL; } - if (iterable_to_sigset(sigset, &set)) - return NULL; - deadline = _PyTime_GetMonotonicClock() + timeout; do { @@ -1191,7 +1121,7 @@ signal_sigtimedwait_impl(PyObject *module, PyObject *sigset, return NULL; Py_BEGIN_ALLOW_THREADS - res = sigtimedwait(&set, &si, &ts); + res = sigtimedwait(&sigset, &si, &ts); Py_END_ALLOW_THREADS if (res != -1) From webhook-mailer at python.org Tue May 8 03:09:11 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 08 May 2018 07:09:11 -0000 Subject: [Python-checkins] bpo-33096: Removed unintentionally backported from Python 3 Tkinter files. (GH-6724) Message-ID: https://github.com/python/cpython/commit/903f189b6e528cbe9500014c6f990c6511b38918 commit: 903f189b6e528cbe9500014c6f990c6511b38918 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-05-08T10:09:08+03:00 summary: bpo-33096: Removed unintentionally backported from Python 3 Tkinter files. (GH-6724) This partially reverts commit e80a232f2cfdab584133d9779c83885c5f9f1ba6. files: A Misc/NEWS.d/next/Library/2018-05-08-08-03-34.bpo-33096.0hsFhL.rst D Lib/tkinter/test/test_ttk/test_widgets.py D Lib/tkinter/ttk.py diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py deleted file mode 100644 index 5b0e29cdccaf..000000000000 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ /dev/null @@ -1,1872 +0,0 @@ -import unittest -import tkinter -from tkinter import ttk, TclError -from test.support import requires -import sys - -from tkinter.test.test_ttk.test_functions import MockTclObj -from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, - simulate_mouse_click) -from tkinter.test.widget_tests import (add_standard_options, noconv, - AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, - setUpModule) - -requires('gui') - - -class StandardTtkOptionsTests(StandardOptionsTests): - - def test_class(self): - widget = self.create() - self.assertEqual(widget['class'], '') - errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): - errmsg='Attempt to change read-only option' - self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg) - widget2 = self.create(class_='Foo') - self.assertEqual(widget2['class'], 'Foo') - - def test_padding(self): - widget = self.create() - self.checkParam(widget, 'padding', 0, expected=('0',)) - self.checkParam(widget, 'padding', 5, expected=('5',)) - self.checkParam(widget, 'padding', (5, 6), expected=('5', '6')) - self.checkParam(widget, 'padding', (5, 6, 7), - expected=('5', '6', '7')) - self.checkParam(widget, 'padding', (5, 6, 7, 8), - expected=('5', '6', '7', '8')) - self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p')) - self.checkParam(widget, 'padding', (), expected='') - - def test_style(self): - widget = self.create() - self.assertEqual(widget['style'], '') - errmsg = 'Layout Foo not found' - if hasattr(self, 'default_orient'): - errmsg = ('Layout %s.Foo not found' % - getattr(self, 'default_orient').title()) - self.checkInvalidParam(widget, 'style', 'Foo', - errmsg=errmsg) - widget2 = self.create(class_='Foo') - self.assertEqual(widget2['class'], 'Foo') - # XXX - pass - - -class WidgetTest(AbstractTkTest, unittest.TestCase): - """Tests methods available in every ttk widget.""" - - def setUp(self): - super().setUp() - self.widget = ttk.Button(self.root, width=0, text="Text") - self.widget.pack() - self.widget.wait_visibility() - - - def test_identify(self): - self.widget.update_idletasks() - self.assertEqual(self.widget.identify( - int(self.widget.winfo_width() / 2), - int(self.widget.winfo_height() / 2) - ), "label") - self.assertEqual(self.widget.identify(-1, -1), "") - - self.assertRaises(tkinter.TclError, self.widget.identify, None, 5) - self.assertRaises(tkinter.TclError, self.widget.identify, 5, None) - self.assertRaises(tkinter.TclError, self.widget.identify, 5, '') - - - def test_widget_state(self): - # XXX not sure about the portability of all these tests - self.assertEqual(self.widget.state(), ()) - self.assertEqual(self.widget.instate(['!disabled']), True) - - # changing from !disabled to disabled - self.assertEqual(self.widget.state(['disabled']), ('!disabled', )) - # no state change - self.assertEqual(self.widget.state(['disabled']), ()) - # change back to !disable but also active - self.assertEqual(self.widget.state(['!disabled', 'active']), - ('!active', 'disabled')) - # no state changes, again - self.assertEqual(self.widget.state(['!disabled', 'active']), ()) - self.assertEqual(self.widget.state(['active', '!disabled']), ()) - - def test_cb(arg1, **kw): - return arg1, kw - self.assertEqual(self.widget.instate(['!disabled'], - test_cb, "hi", **{"msg": "there"}), - ('hi', {'msg': 'there'})) - - # attempt to set invalid statespec - currstate = self.widget.state() - self.assertRaises(tkinter.TclError, self.widget.instate, - ['badstate']) - self.assertRaises(tkinter.TclError, self.widget.instate, - ['disabled', 'badstate']) - # verify that widget didn't change its state - self.assertEqual(currstate, self.widget.state()) - - # ensuring that passing None as state doesn't modify current state - self.widget.state(['active', '!disabled']) - self.assertEqual(self.widget.state(), ('active', )) - - -class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - _conv_pixels = noconv - - - at add_standard_options(StandardTtkOptionsTests) -class FrameTest(AbstractToplevelTest, unittest.TestCase): - OPTIONS = ( - 'borderwidth', 'class', 'cursor', 'height', - 'padding', 'relief', 'style', 'takefocus', - 'width', - ) - - def create(self, **kwargs): - return ttk.Frame(self.root, **kwargs) - - - at add_standard_options(StandardTtkOptionsTests) -class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): - OPTIONS = ( - 'borderwidth', 'class', 'cursor', 'height', - 'labelanchor', 'labelwidget', - 'padding', 'relief', 'style', 'takefocus', - 'text', 'underline', 'width', - ) - - def create(self, **kwargs): - return ttk.LabelFrame(self.root, **kwargs) - - def test_labelanchor(self): - widget = self.create() - self.checkEnumParam(widget, 'labelanchor', - 'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws', - errmsg='Bad label anchor specification {}') - self.checkInvalidParam(widget, 'labelanchor', 'center') - - def test_labelwidget(self): - widget = self.create() - label = ttk.Label(self.root, text='Mupp', name='foo') - self.checkParam(widget, 'labelwidget', label, expected='.foo') - label.destroy() - - -class AbstractLabelTest(AbstractWidgetTest): - - def checkImageParam(self, widget, name): - image = tkinter.PhotoImage(master=self.root, name='image1') - image2 = tkinter.PhotoImage(master=self.root, name='image2') - self.checkParam(widget, name, image, expected=('image1',)) - self.checkParam(widget, name, 'image1', expected=('image1',)) - self.checkParam(widget, name, (image,), expected=('image1',)) - self.checkParam(widget, name, (image, 'active', image2), - expected=('image1', 'active', 'image2')) - self.checkParam(widget, name, 'image1 active image2', - expected=('image1', 'active', 'image2')) - self.checkInvalidParam(widget, name, 'spam', - errmsg='image "spam" doesn\'t exist') - - def test_compound(self): - widget = self.create() - self.checkEnumParam(widget, 'compound', - 'none', 'text', 'image', 'center', - 'top', 'bottom', 'left', 'right') - - def test_state(self): - widget = self.create() - self.checkParams(widget, 'state', 'active', 'disabled', 'normal') - - def test_width(self): - widget = self.create() - self.checkParams(widget, 'width', 402, -402, 0) - - - at add_standard_options(StandardTtkOptionsTests) -class LabelTest(AbstractLabelTest, unittest.TestCase): - OPTIONS = ( - 'anchor', 'background', 'borderwidth', - 'class', 'compound', 'cursor', 'font', 'foreground', - 'image', 'justify', 'padding', 'relief', 'state', 'style', - 'takefocus', 'text', 'textvariable', - 'underline', 'width', 'wraplength', - ) - _conv_pixels = noconv - - def create(self, **kwargs): - return ttk.Label(self.root, **kwargs) - - def test_font(self): - widget = self.create() - self.checkParam(widget, 'font', - '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*') - - - at add_standard_options(StandardTtkOptionsTests) -class ButtonTest(AbstractLabelTest, unittest.TestCase): - OPTIONS = ( - 'class', 'command', 'compound', 'cursor', 'default', - 'image', 'padding', 'state', 'style', - 'takefocus', 'text', 'textvariable', - 'underline', 'width', - ) - - def create(self, **kwargs): - return ttk.Button(self.root, **kwargs) - - def test_default(self): - widget = self.create() - self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled') - - def test_invoke(self): - success = [] - btn = ttk.Button(self.root, command=lambda: success.append(1)) - btn.invoke() - self.assertTrue(success) - - - at add_standard_options(StandardTtkOptionsTests) -class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): - OPTIONS = ( - 'class', 'command', 'compound', 'cursor', - 'image', - 'offvalue', 'onvalue', - 'padding', 'state', 'style', - 'takefocus', 'text', 'textvariable', - 'underline', 'variable', 'width', - ) - - def create(self, **kwargs): - return ttk.Checkbutton(self.root, **kwargs) - - def test_offvalue(self): - widget = self.create() - self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string') - - def test_onvalue(self): - widget = self.create() - self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string') - - def test_invoke(self): - success = [] - def cb_test(): - success.append(1) - return "cb test called" - - cbtn = ttk.Checkbutton(self.root, command=cb_test) - # the variable automatically created by ttk.Checkbutton is actually - # undefined till we invoke the Checkbutton - self.assertEqual(cbtn.state(), ('alternate', )) - self.assertRaises(tkinter.TclError, cbtn.tk.globalgetvar, - cbtn['variable']) - - res = cbtn.invoke() - self.assertEqual(res, "cb test called") - self.assertEqual(cbtn['onvalue'], - cbtn.tk.globalgetvar(cbtn['variable'])) - self.assertTrue(success) - - cbtn['command'] = '' - res = cbtn.invoke() - self.assertFalse(str(res)) - self.assertLessEqual(len(success), 1) - self.assertEqual(cbtn['offvalue'], - cbtn.tk.globalgetvar(cbtn['variable'])) - - - at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class EntryTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'background', 'class', 'cursor', - 'exportselection', 'font', 'foreground', - 'invalidcommand', 'justify', - 'show', 'state', 'style', 'takefocus', 'textvariable', - 'validate', 'validatecommand', 'width', 'xscrollcommand', - ) - - def setUp(self): - super().setUp() - self.entry = self.create() - - def create(self, **kwargs): - return ttk.Entry(self.root, **kwargs) - - def test_invalidcommand(self): - widget = self.create() - self.checkCommandParam(widget, 'invalidcommand') - - def test_show(self): - widget = self.create() - self.checkParam(widget, 'show', '*') - self.checkParam(widget, 'show', '') - self.checkParam(widget, 'show', ' ') - - def test_state(self): - widget = self.create() - self.checkParams(widget, 'state', - 'disabled', 'normal', 'readonly') - - def test_validate(self): - widget = self.create() - self.checkEnumParam(widget, 'validate', - 'all', 'key', 'focus', 'focusin', 'focusout', 'none') - - def test_validatecommand(self): - widget = self.create() - self.checkCommandParam(widget, 'validatecommand') - - - def test_bbox(self): - self.assertIsBoundingBox(self.entry.bbox(0)) - self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') - self.assertRaises(tkinter.TclError, self.entry.bbox, None) - - - def test_identify(self): - self.entry.pack() - self.entry.wait_visibility() - self.entry.update_idletasks() - - self.assertEqual(self.entry.identify(5, 5), "textarea") - self.assertEqual(self.entry.identify(-1, -1), "") - - self.assertRaises(tkinter.TclError, self.entry.identify, None, 5) - self.assertRaises(tkinter.TclError, self.entry.identify, 5, None) - self.assertRaises(tkinter.TclError, self.entry.identify, 5, '') - - - def test_validation_options(self): - success = [] - test_invalid = lambda: success.append(True) - - self.entry['validate'] = 'none' - self.entry['validatecommand'] = lambda: False - - self.entry['invalidcommand'] = test_invalid - self.entry.validate() - self.assertTrue(success) - - self.entry['invalidcommand'] = '' - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['invalidcommand'] = test_invalid - self.entry['validatecommand'] = lambda: True - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['validatecommand'] = '' - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['validatecommand'] = True - self.assertRaises(tkinter.TclError, self.entry.validate) - - - def test_validation(self): - validation = [] - def validate(to_insert): - if not 'a' <= to_insert.lower() <= 'z': - validation.append(False) - return False - validation.append(True) - return True - - self.entry['validate'] = 'key' - self.entry['validatecommand'] = self.entry.register(validate), '%S' - - self.entry.insert('end', 1) - self.entry.insert('end', 'a') - self.assertEqual(validation, [False, True]) - self.assertEqual(self.entry.get(), 'a') - - - def test_revalidation(self): - def validate(content): - for letter in content: - if not 'a' <= letter.lower() <= 'z': - return False - return True - - self.entry['validatecommand'] = self.entry.register(validate), '%P' - - self.entry.insert('end', 'avocado') - self.assertEqual(self.entry.validate(), True) - self.assertEqual(self.entry.state(), ()) - - self.entry.delete(0, 'end') - self.assertEqual(self.entry.get(), '') - - self.entry.insert('end', 'a1b') - self.assertEqual(self.entry.validate(), False) - self.assertEqual(self.entry.state(), ('invalid', )) - - self.entry.delete(1) - self.assertEqual(self.entry.validate(), True) - self.assertEqual(self.entry.state(), ()) - - - at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class ComboboxTest(EntryTest, unittest.TestCase): - OPTIONS = ( - 'background', 'class', 'cursor', 'exportselection', - 'font', 'foreground', 'height', 'invalidcommand', - 'justify', 'postcommand', 'show', 'state', 'style', - 'takefocus', 'textvariable', - 'validate', 'validatecommand', 'values', - 'width', 'xscrollcommand', - ) - - def setUp(self): - super().setUp() - self.combo = self.create() - - def create(self, **kwargs): - return ttk.Combobox(self.root, **kwargs) - - def test_height(self): - widget = self.create() - self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i') - - def _show_drop_down_listbox(self): - width = self.combo.winfo_width() - self.combo.event_generate('', x=width - 5, y=5) - self.combo.event_generate('', x=width - 5, y=5) - self.combo.update_idletasks() - - - def test_virtual_event(self): - success = [] - - self.combo['values'] = [1] - self.combo.bind('<>', - lambda evt: success.append(True)) - self.combo.pack() - self.combo.wait_visibility() - - height = self.combo.winfo_height() - self._show_drop_down_listbox() - self.combo.update() - self.combo.event_generate('') - self.combo.update() - - self.assertTrue(success) - - - def test_postcommand(self): - success = [] - - self.combo['postcommand'] = lambda: success.append(True) - self.combo.pack() - self.combo.wait_visibility() - - self._show_drop_down_listbox() - self.assertTrue(success) - - # testing postcommand removal - self.combo['postcommand'] = '' - self._show_drop_down_listbox() - self.assertEqual(len(success), 1) - - - def test_values(self): - def check_get_current(getval, currval): - self.assertEqual(self.combo.get(), getval) - self.assertEqual(self.combo.current(), currval) - - self.assertEqual(self.combo['values'], - () if tcl_version < (8, 5) else '') - check_get_current('', -1) - - self.checkParam(self.combo, 'values', 'mon tue wed thur', - expected=('mon', 'tue', 'wed', 'thur')) - self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur')) - self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string')) - self.checkParam(self.combo, 'values', '', - expected='' if get_tk_patchlevel() < (8, 5, 10) else ()) - - self.combo['values'] = ['a', 1, 'c'] - - self.combo.set('c') - check_get_current('c', 2) - - self.combo.current(0) - check_get_current('a', 0) - - self.combo.set('d') - check_get_current('d', -1) - - # testing values with empty string - self.combo.set('') - self.combo['values'] = (1, 2, '', 3) - check_get_current('', 2) - - # testing values with empty string set through configure - self.combo.configure(values=[1, '', 2]) - self.assertEqual(self.combo['values'], - ('1', '', '2') if self.wantobjects else - '1 {} 2') - - # testing values with spaces - self.combo['values'] = ['a b', 'a\tb', 'a\nb'] - self.assertEqual(self.combo['values'], - ('a b', 'a\tb', 'a\nb') if self.wantobjects else - '{a b} {a\tb} {a\nb}') - - # testing values with special characters - self.combo['values'] = [r'a\tb', '"a"', '} {'] - self.assertEqual(self.combo['values'], - (r'a\tb', '"a"', '} {') if self.wantobjects else - r'a\\tb {"a"} \}\ \{') - - # out of range - self.assertRaises(tkinter.TclError, self.combo.current, - len(self.combo['values'])) - # it expects an integer (or something that can be converted to int) - self.assertRaises(tkinter.TclError, self.combo.current, '') - - # testing creating combobox with empty string in values - combo2 = ttk.Combobox(self.root, values=[1, 2, '']) - self.assertEqual(combo2['values'], - ('1', '2', '') if self.wantobjects else '1 2 {}') - combo2.destroy() - - - at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'cursor', 'height', - 'orient', 'style', 'takefocus', 'width', - ) - - def setUp(self): - super().setUp() - self.paned = self.create() - - def create(self, **kwargs): - return ttk.PanedWindow(self.root, **kwargs) - - def test_orient(self): - widget = self.create() - self.assertEqual(str(widget['orient']), 'vertical') - errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): - errmsg='Attempt to change read-only option' - self.checkInvalidParam(widget, 'orient', 'horizontal', - errmsg=errmsg) - widget2 = self.create(orient='horizontal') - self.assertEqual(str(widget2['orient']), 'horizontal') - - def test_add(self): - # attempt to add a child that is not a direct child of the paned window - label = ttk.Label(self.paned) - child = ttk.Label(label) - self.assertRaises(tkinter.TclError, self.paned.add, child) - label.destroy() - child.destroy() - # another attempt - label = ttk.Label(self.root) - child = ttk.Label(label) - self.assertRaises(tkinter.TclError, self.paned.add, child) - child.destroy() - label.destroy() - - good_child = ttk.Label(self.root) - self.paned.add(good_child) - # re-adding a child is not accepted - self.assertRaises(tkinter.TclError, self.paned.add, good_child) - - other_child = ttk.Label(self.paned) - self.paned.add(other_child) - self.assertEqual(self.paned.pane(0), self.paned.pane(1)) - self.assertRaises(tkinter.TclError, self.paned.pane, 2) - good_child.destroy() - other_child.destroy() - self.assertRaises(tkinter.TclError, self.paned.pane, 0) - - - def test_forget(self): - self.assertRaises(tkinter.TclError, self.paned.forget, None) - self.assertRaises(tkinter.TclError, self.paned.forget, 0) - - self.paned.add(ttk.Label(self.root)) - self.paned.forget(0) - self.assertRaises(tkinter.TclError, self.paned.forget, 0) - - - def test_insert(self): - self.assertRaises(tkinter.TclError, self.paned.insert, None, 0) - self.assertRaises(tkinter.TclError, self.paned.insert, 0, None) - self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0) - - child = ttk.Label(self.root) - child2 = ttk.Label(self.root) - child3 = ttk.Label(self.root) - - self.assertRaises(tkinter.TclError, self.paned.insert, 0, child) - - self.paned.insert('end', child2) - self.paned.insert(0, child) - self.assertEqual(self.paned.panes(), (str(child), str(child2))) - - self.paned.insert(0, child2) - self.assertEqual(self.paned.panes(), (str(child2), str(child))) - - self.paned.insert('end', child3) - self.assertEqual(self.paned.panes(), - (str(child2), str(child), str(child3))) - - # reinserting a child should move it to its current position - panes = self.paned.panes() - self.paned.insert('end', child3) - self.assertEqual(panes, self.paned.panes()) - - # moving child3 to child2 position should result in child2 ending up - # in previous child position and child ending up in previous child3 - # position - self.paned.insert(child2, child3) - self.assertEqual(self.paned.panes(), - (str(child3), str(child2), str(child))) - - - def test_pane(self): - self.assertRaises(tkinter.TclError, self.paned.pane, 0) - - child = ttk.Label(self.root) - self.paned.add(child) - self.assertIsInstance(self.paned.pane(0), dict) - self.assertEqual(self.paned.pane(0, weight=None), - 0 if self.wantobjects else '0') - # newer form for querying a single option - self.assertEqual(self.paned.pane(0, 'weight'), - 0 if self.wantobjects else '0') - self.assertEqual(self.paned.pane(0), self.paned.pane(str(child))) - - self.assertRaises(tkinter.TclError, self.paned.pane, 0, - badoption='somevalue') - - - def test_sashpos(self): - self.assertRaises(tkinter.TclError, self.paned.sashpos, None) - self.assertRaises(tkinter.TclError, self.paned.sashpos, '') - self.assertRaises(tkinter.TclError, self.paned.sashpos, 0) - - child = ttk.Label(self.paned, text='a') - self.paned.add(child, weight=1) - self.assertRaises(tkinter.TclError, self.paned.sashpos, 0) - child2 = ttk.Label(self.paned, text='b') - self.paned.add(child2) - self.assertRaises(tkinter.TclError, self.paned.sashpos, 1) - - self.paned.pack(expand=True, fill='both') - self.paned.wait_visibility() - - curr_pos = self.paned.sashpos(0) - self.paned.sashpos(0, 1000) - self.assertNotEqual(curr_pos, self.paned.sashpos(0)) - self.assertIsInstance(self.paned.sashpos(0), int) - - - at add_standard_options(StandardTtkOptionsTests) -class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): - OPTIONS = ( - 'class', 'command', 'compound', 'cursor', - 'image', - 'padding', 'state', 'style', - 'takefocus', 'text', 'textvariable', - 'underline', 'value', 'variable', 'width', - ) - - def create(self, **kwargs): - return ttk.Radiobutton(self.root, **kwargs) - - def test_value(self): - widget = self.create() - self.checkParams(widget, 'value', 1, 2.3, '', 'any string') - - def test_invoke(self): - success = [] - def cb_test(): - success.append(1) - return "cb test called" - - myvar = tkinter.IntVar(self.root) - cbtn = ttk.Radiobutton(self.root, command=cb_test, - variable=myvar, value=0) - cbtn2 = ttk.Radiobutton(self.root, command=cb_test, - variable=myvar, value=1) - - if self.wantobjects: - conv = lambda x: x - else: - conv = int - - res = cbtn.invoke() - self.assertEqual(res, "cb test called") - self.assertEqual(conv(cbtn['value']), myvar.get()) - self.assertEqual(myvar.get(), - conv(cbtn.tk.globalgetvar(cbtn['variable']))) - self.assertTrue(success) - - cbtn2['command'] = '' - res = cbtn2.invoke() - self.assertEqual(str(res), '') - self.assertLessEqual(len(success), 1) - self.assertEqual(conv(cbtn2['value']), myvar.get()) - self.assertEqual(myvar.get(), - conv(cbtn.tk.globalgetvar(cbtn['variable']))) - - self.assertEqual(str(cbtn['variable']), str(cbtn2['variable'])) - - -class MenubuttonTest(AbstractLabelTest, unittest.TestCase): - OPTIONS = ( - 'class', 'compound', 'cursor', 'direction', - 'image', 'menu', 'padding', 'state', 'style', - 'takefocus', 'text', 'textvariable', - 'underline', 'width', - ) - - def create(self, **kwargs): - return ttk.Menubutton(self.root, **kwargs) - - def test_direction(self): - widget = self.create() - self.checkEnumParam(widget, 'direction', - 'above', 'below', 'left', 'right', 'flush') - - def test_menu(self): - widget = self.create() - menu = tkinter.Menu(widget, name='menu') - self.checkParam(widget, 'menu', menu, conv=str) - menu.destroy() - - - at add_standard_options(StandardTtkOptionsTests) -class ScaleTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'command', 'cursor', 'from', 'length', - 'orient', 'style', 'takefocus', 'to', 'value', 'variable', - ) - _conv_pixels = noconv - default_orient = 'horizontal' - - def setUp(self): - super().setUp() - self.scale = self.create() - self.scale.pack() - self.scale.update() - - def create(self, **kwargs): - return ttk.Scale(self.root, **kwargs) - - def test_from(self): - widget = self.create() - self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False) - - def test_length(self): - widget = self.create() - self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i') - - def test_to(self): - widget = self.create() - self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False) - - def test_value(self): - widget = self.create() - self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False) - - def test_custom_event(self): - failure = [1, 1, 1] # will need to be empty - - funcid = self.scale.bind('<>', lambda evt: failure.pop()) - - self.scale['from'] = 10 - self.scale['from_'] = 10 - self.scale['to'] = 3 - - self.assertFalse(failure) - - failure = [1, 1, 1] - self.scale.configure(from_=2, to=5) - self.scale.configure(from_=0, to=-2) - self.scale.configure(to=10) - - self.assertFalse(failure) - - - def test_get(self): - if self.wantobjects: - conv = lambda x: x - else: - conv = float - - scale_width = self.scale.winfo_width() - self.assertEqual(self.scale.get(scale_width, 0), self.scale['to']) - - self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from'])) - self.assertEqual(self.scale.get(), self.scale['value']) - self.scale['value'] = 30 - self.assertEqual(self.scale.get(), self.scale['value']) - - self.assertRaises(tkinter.TclError, self.scale.get, '', 0) - self.assertRaises(tkinter.TclError, self.scale.get, 0, '') - - - def test_set(self): - if self.wantobjects: - conv = lambda x: x - else: - conv = float - - # set restricts the max/min values according to the current range - max = conv(self.scale['to']) - new_max = max + 10 - self.scale.set(new_max) - self.assertEqual(conv(self.scale.get()), max) - min = conv(self.scale['from']) - self.scale.set(min - 1) - self.assertEqual(conv(self.scale.get()), min) - - # changing directly the variable doesn't impose this limitation tho - var = tkinter.DoubleVar(self.root) - self.scale['variable'] = var - var.set(max + 5) - self.assertEqual(conv(self.scale.get()), var.get()) - self.assertEqual(conv(self.scale.get()), max + 5) - del var - - # the same happens with the value option - self.scale['value'] = max + 10 - self.assertEqual(conv(self.scale.get()), max + 10) - self.assertEqual(conv(self.scale.get()), conv(self.scale['value'])) - - # nevertheless, note that the max/min values we can get specifying - # x, y coords are the ones according to the current range - self.assertEqual(conv(self.scale.get(0, 0)), min) - self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max) - - self.assertRaises(tkinter.TclError, self.scale.set, None) - - - at add_standard_options(StandardTtkOptionsTests) -class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'cursor', 'orient', 'length', - 'mode', 'maximum', 'phase', - 'style', 'takefocus', 'value', 'variable', - ) - _conv_pixels = noconv - default_orient = 'horizontal' - - def create(self, **kwargs): - return ttk.Progressbar(self.root, **kwargs) - - def test_length(self): - widget = self.create() - self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i') - - def test_maximum(self): - widget = self.create() - self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False) - - def test_mode(self): - widget = self.create() - self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate') - - def test_phase(self): - # XXX - pass - - def test_value(self): - widget = self.create() - self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10, - conv=False) - - - at unittest.skipIf(sys.platform == 'darwin', - 'ttk.Scrollbar is special on MacOSX') - at add_standard_options(StandardTtkOptionsTests) -class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'command', 'cursor', 'orient', 'style', 'takefocus', - ) - default_orient = 'vertical' - - def create(self, **kwargs): - return ttk.Scrollbar(self.root, **kwargs) - - - at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class NotebookTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width', - ) - - def setUp(self): - super().setUp() - self.nb = self.create(padding=0) - self.child1 = ttk.Label(self.root) - self.child2 = ttk.Label(self.root) - self.nb.add(self.child1, text='a') - self.nb.add(self.child2, text='b') - - def create(self, **kwargs): - return ttk.Notebook(self.root, **kwargs) - - def test_tab_identifiers(self): - self.nb.forget(0) - self.nb.hide(self.child2) - self.assertRaises(tkinter.TclError, self.nb.tab, self.child1) - self.assertEqual(self.nb.index('end'), 1) - self.nb.add(self.child2) - self.assertEqual(self.nb.index('end'), 1) - self.nb.select(self.child2) - - self.assertTrue(self.nb.tab('current')) - self.nb.add(self.child1, text='a') - - self.nb.pack() - self.nb.wait_visibility() - if sys.platform == 'darwin': - tb_idx = "@20,5" - else: - tb_idx = "@5,5" - self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current')) - - for i in range(5, 100, 5): - try: - if self.nb.tab('@%d, 5' % i, text=None) == 'a': - break - except tkinter.TclError: - pass - - else: - self.fail("Tab with text 'a' not found") - - - def test_add_and_hidden(self): - self.assertRaises(tkinter.TclError, self.nb.hide, -1) - self.assertRaises(tkinter.TclError, self.nb.hide, 'hi') - self.assertRaises(tkinter.TclError, self.nb.hide, None) - self.assertRaises(tkinter.TclError, self.nb.add, None) - self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root), - unknown='option') - - tabs = self.nb.tabs() - self.nb.hide(self.child1) - self.nb.add(self.child1) - self.assertEqual(self.nb.tabs(), tabs) - - child = ttk.Label(self.root) - self.nb.add(child, text='c') - tabs = self.nb.tabs() - - curr = self.nb.index('current') - # verify that the tab gets readded at its previous position - child2_index = self.nb.index(self.child2) - self.nb.hide(self.child2) - self.nb.add(self.child2) - self.assertEqual(self.nb.tabs(), tabs) - self.assertEqual(self.nb.index(self.child2), child2_index) - self.assertEqual(str(self.child2), self.nb.tabs()[child2_index]) - # but the tab next to it (not hidden) is the one selected now - self.assertEqual(self.nb.index('current'), curr + 1) - - - def test_forget(self): - self.assertRaises(tkinter.TclError, self.nb.forget, -1) - self.assertRaises(tkinter.TclError, self.nb.forget, 'hi') - self.assertRaises(tkinter.TclError, self.nb.forget, None) - - tabs = self.nb.tabs() - child1_index = self.nb.index(self.child1) - self.nb.forget(self.child1) - self.assertNotIn(str(self.child1), self.nb.tabs()) - self.assertEqual(len(tabs) - 1, len(self.nb.tabs())) - - self.nb.add(self.child1) - self.assertEqual(self.nb.index(self.child1), 1) - self.assertNotEqual(child1_index, self.nb.index(self.child1)) - - - def test_index(self): - self.assertRaises(tkinter.TclError, self.nb.index, -1) - self.assertRaises(tkinter.TclError, self.nb.index, None) - - self.assertIsInstance(self.nb.index('end'), int) - self.assertEqual(self.nb.index(self.child1), 0) - self.assertEqual(self.nb.index(self.child2), 1) - self.assertEqual(self.nb.index('end'), 2) - - - def test_insert(self): - # moving tabs - tabs = self.nb.tabs() - self.nb.insert(1, tabs[0]) - self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0])) - self.nb.insert(self.child1, self.child2) - self.assertEqual(self.nb.tabs(), tabs) - self.nb.insert('end', self.child1) - self.assertEqual(self.nb.tabs(), (tabs[1], tabs[0])) - self.nb.insert('end', 0) - self.assertEqual(self.nb.tabs(), tabs) - # bad moves - self.assertRaises(tkinter.TclError, self.nb.insert, 2, tabs[0]) - self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0]) - - # new tab - child3 = ttk.Label(self.root) - self.nb.insert(1, child3) - self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1])) - self.nb.forget(child3) - self.assertEqual(self.nb.tabs(), tabs) - self.nb.insert(self.child1, child3) - self.assertEqual(self.nb.tabs(), (str(child3), ) + tabs) - self.nb.forget(child3) - self.assertRaises(tkinter.TclError, self.nb.insert, 2, child3) - self.assertRaises(tkinter.TclError, self.nb.insert, -1, child3) - - # bad inserts - self.assertRaises(tkinter.TclError, self.nb.insert, 'end', None) - self.assertRaises(tkinter.TclError, self.nb.insert, None, 0) - self.assertRaises(tkinter.TclError, self.nb.insert, None, None) - - - def test_select(self): - self.nb.pack() - self.nb.wait_visibility() - - success = [] - tab_changed = [] - - self.child1.bind('', lambda evt: success.append(True)) - self.nb.bind('<>', - lambda evt: tab_changed.append(True)) - - self.assertEqual(self.nb.select(), str(self.child1)) - self.nb.select(self.child2) - self.assertTrue(success) - self.assertEqual(self.nb.select(), str(self.child2)) - - self.nb.update() - self.assertTrue(tab_changed) - - - def test_tab(self): - self.assertRaises(tkinter.TclError, self.nb.tab, -1) - self.assertRaises(tkinter.TclError, self.nb.tab, 'notab') - self.assertRaises(tkinter.TclError, self.nb.tab, None) - - self.assertIsInstance(self.nb.tab(self.child1), dict) - self.assertEqual(self.nb.tab(self.child1, text=None), 'a') - # newer form for querying a single option - self.assertEqual(self.nb.tab(self.child1, 'text'), 'a') - self.nb.tab(self.child1, text='abc') - self.assertEqual(self.nb.tab(self.child1, text=None), 'abc') - self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc') - - - def test_tabs(self): - self.assertEqual(len(self.nb.tabs()), 2) - - self.nb.forget(self.child1) - self.nb.forget(self.child2) - - self.assertEqual(self.nb.tabs(), ()) - - - def test_traversal(self): - self.nb.pack() - self.nb.wait_visibility() - - self.nb.select(0) - - simulate_mouse_click(self.nb, 5, 5) - self.nb.focus_force() - self.nb.event_generate('') - self.assertEqual(self.nb.select(), str(self.child2)) - self.nb.focus_force() - self.nb.event_generate('') - self.assertEqual(self.nb.select(), str(self.child1)) - self.nb.focus_force() - self.nb.event_generate('') - self.assertEqual(self.nb.select(), str(self.child2)) - - self.nb.tab(self.child1, text='a', underline=0) - self.nb.enable_traversal() - self.nb.focus_force() - simulate_mouse_click(self.nb, 5, 5) - if sys.platform == 'darwin': - self.nb.event_generate('') - else: - self.nb.event_generate('') - self.assertEqual(self.nb.select(), str(self.child1)) - - at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class SpinboxTest(EntryTest, unittest.TestCase): - OPTIONS = ( - 'background', 'class', 'command', 'cursor', 'exportselection', - 'font', 'foreground', 'format', 'from', 'increment', - 'invalidcommand', 'justify', 'show', 'state', 'style', - 'takefocus', 'textvariable', 'to', 'validate', 'validatecommand', - 'values', 'width', 'wrap', 'xscrollcommand', - ) - - def setUp(self): - super().setUp() - self.spin = self.create() - self.spin.pack() - - def create(self, **kwargs): - return ttk.Spinbox(self.root, **kwargs) - - def _click_increment_arrow(self): - width = self.spin.winfo_width() - height = self.spin.winfo_height() - x = width - 5 - y = height//2 - 5 - self.spin.event_generate('', x=x, y=y) - self.spin.event_generate('', x=x, y=y) - self.spin.update_idletasks() - - def _click_decrement_arrow(self): - width = self.spin.winfo_width() - height = self.spin.winfo_height() - x = width - 5 - y = height//2 + 4 - self.spin.event_generate('', x=x, y=y) - self.spin.event_generate('', x=x, y=y) - self.spin.update_idletasks() - - def test_command(self): - success = [] - - self.spin['command'] = lambda: success.append(True) - self.spin.update() - self._click_increment_arrow() - self.spin.update() - self.assertTrue(success) - - self._click_decrement_arrow() - self.assertEqual(len(success), 2) - - # testing postcommand removal - self.spin['command'] = '' - self.spin.update_idletasks() - self._click_increment_arrow() - self._click_decrement_arrow() - self.spin.update() - self.assertEqual(len(success), 2) - - def test_to(self): - self.spin['from'] = 0 - self.spin['to'] = 5 - self.spin.set(4) - self.spin.update() - self._click_increment_arrow() # 5 - - self.assertEqual(self.spin.get(), '5') - - self._click_increment_arrow() # 5 - self.assertEqual(self.spin.get(), '5') - - def test_from(self): - self.spin['from'] = 1 - self.spin['to'] = 10 - self.spin.set(2) - self.spin.update() - self._click_decrement_arrow() # 1 - self.assertEqual(self.spin.get(), '1') - self._click_decrement_arrow() # 1 - self.assertEqual(self.spin.get(), '1') - - def test_increment(self): - self.spin['from'] = 0 - self.spin['to'] = 10 - self.spin['increment'] = 4 - self.spin.set(1) - self.spin.update() - - self._click_increment_arrow() # 5 - self.assertEqual(self.spin.get(), '5') - self.spin['increment'] = 2 - self.spin.update() - self._click_decrement_arrow() # 3 - self.assertEqual(self.spin.get(), '3') - - def test_format(self): - self.spin.set(1) - self.spin['format'] = '%10.3f' - self.spin.update() - self._click_increment_arrow() - value = self.spin.get() - - self.assertEqual(len(value), 10) - self.assertEqual(value.index('.'), 6) - - self.spin['format'] = '' - self.spin.update() - self._click_increment_arrow() - value = self.spin.get() - self.assertTrue('.' not in value) - self.assertEqual(len(value), 1) - - def test_wrap(self): - self.spin['to'] = 10 - self.spin['from'] = 1 - self.spin.set(1) - self.spin['wrap'] = True - self.spin.update() - - self._click_decrement_arrow() - self.assertEqual(self.spin.get(), '10') - - self._click_increment_arrow() - self.assertEqual(self.spin.get(), '1') - - self.spin['wrap'] = False - self.spin.update() - - self._click_decrement_arrow() - self.assertEqual(self.spin.get(), '1') - - def test_values(self): - self.assertEqual(self.spin['values'], - () if tcl_version < (8, 5) else '') - self.checkParam(self.spin, 'values', 'mon tue wed thur', - expected=('mon', 'tue', 'wed', 'thur')) - self.checkParam(self.spin, 'values', ('mon', 'tue', 'wed', 'thur')) - self.checkParam(self.spin, 'values', (42, 3.14, '', 'any string')) - self.checkParam( - self.spin, - 'values', - '', - expected='' if get_tk_patchlevel() < (8, 5, 10) else () - ) - - self.spin['values'] = ['a', 1, 'c'] - - # test incrementing / decrementing values - self.spin.set('a') - self.spin.update() - self._click_increment_arrow() - self.assertEqual(self.spin.get(), '1') - - self._click_decrement_arrow() - self.assertEqual(self.spin.get(), 'a') - - # testing values with empty string set through configure - self.spin.configure(values=[1, '', 2]) - self.assertEqual(self.spin['values'], - ('1', '', '2') if self.wantobjects else - '1 {} 2') - - # testing values with spaces - self.spin['values'] = ['a b', 'a\tb', 'a\nb'] - self.assertEqual(self.spin['values'], - ('a b', 'a\tb', 'a\nb') if self.wantobjects else - '{a b} {a\tb} {a\nb}') - - # testing values with special characters - self.spin['values'] = [r'a\tb', '"a"', '} {'] - self.assertEqual(self.spin['values'], - (r'a\tb', '"a"', '} {') if self.wantobjects else - r'a\\tb {"a"} \}\ \{') - - # testing creating spinbox with empty string in values - spin2 = ttk.Spinbox(self.root, values=[1, 2, '']) - self.assertEqual(spin2['values'], - ('1', '2', '') if self.wantobjects else '1 2 {}') - spin2.destroy() - - - at add_standard_options(StandardTtkOptionsTests) -class TreeviewTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'columns', 'cursor', 'displaycolumns', - 'height', 'padding', 'selectmode', 'show', - 'style', 'takefocus', 'xscrollcommand', 'yscrollcommand', - ) - - def setUp(self): - super().setUp() - self.tv = self.create(padding=0) - - def create(self, **kwargs): - return ttk.Treeview(self.root, **kwargs) - - def test_columns(self): - widget = self.create() - self.checkParam(widget, 'columns', 'a b c', - expected=('a', 'b', 'c')) - self.checkParam(widget, 'columns', ('a', 'b', 'c')) - self.checkParam(widget, 'columns', (), - expected='' if get_tk_patchlevel() < (8, 5, 10) else ()) - - def test_displaycolumns(self): - widget = self.create() - widget['columns'] = ('a', 'b', 'c') - self.checkParam(widget, 'displaycolumns', 'b a c', - expected=('b', 'a', 'c')) - self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c')) - self.checkParam(widget, 'displaycolumns', '#all', - expected=('#all',)) - self.checkParam(widget, 'displaycolumns', (2, 1, 0)) - self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'), - errmsg='Invalid column index d') - self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3), - errmsg='Column index 3 out of bounds') - self.checkInvalidParam(widget, 'displaycolumns', (1, -2), - errmsg='Column index -2 out of bounds') - - def test_height(self): - widget = self.create() - self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False) - self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv) - - def test_selectmode(self): - widget = self.create() - self.checkEnumParam(widget, 'selectmode', - 'none', 'browse', 'extended') - - def test_show(self): - widget = self.create() - self.checkParam(widget, 'show', 'tree headings', - expected=('tree', 'headings')) - self.checkParam(widget, 'show', ('tree', 'headings')) - self.checkParam(widget, 'show', ('headings', 'tree')) - self.checkParam(widget, 'show', 'tree', expected=('tree',)) - self.checkParam(widget, 'show', 'headings', expected=('headings',)) - - def test_bbox(self): - self.tv.pack() - self.assertEqual(self.tv.bbox(''), '') - self.tv.wait_visibility() - self.tv.update() - - item_id = self.tv.insert('', 'end') - children = self.tv.get_children() - self.assertTrue(children) - - bbox = self.tv.bbox(children[0]) - self.assertIsBoundingBox(bbox) - - # compare width in bboxes - self.tv['columns'] = ['test'] - self.tv.column('test', width=50) - bbox_column0 = self.tv.bbox(children[0], 0) - root_width = self.tv.column('#0', width=None) - if not self.wantobjects: - root_width = int(root_width) - self.assertEqual(bbox_column0[0], bbox[0] + root_width) - - # verify that bbox of a closed item is the empty string - child1 = self.tv.insert(item_id, 'end') - self.assertEqual(self.tv.bbox(child1), '') - - - def test_children(self): - # no children yet, should get an empty tuple - self.assertEqual(self.tv.get_children(), ()) - - item_id = self.tv.insert('', 'end') - self.assertIsInstance(self.tv.get_children(), tuple) - self.assertEqual(self.tv.get_children()[0], item_id) - - # add item_id and child3 as children of child2 - child2 = self.tv.insert('', 'end') - child3 = self.tv.insert('', 'end') - self.tv.set_children(child2, item_id, child3) - self.assertEqual(self.tv.get_children(child2), (item_id, child3)) - - # child3 has child2 as parent, thus trying to set child2 as a children - # of child3 should result in an error - self.assertRaises(tkinter.TclError, - self.tv.set_children, child3, child2) - - # remove child2 children - self.tv.set_children(child2) - self.assertEqual(self.tv.get_children(child2), ()) - - # remove root's children - self.tv.set_children('') - self.assertEqual(self.tv.get_children(), ()) - - - def test_column(self): - # return a dict with all options/values - self.assertIsInstance(self.tv.column('#0'), dict) - # return a single value of the given option - if self.wantobjects: - self.assertIsInstance(self.tv.column('#0', width=None), int) - # set a new value for an option - self.tv.column('#0', width=10) - # testing new way to get option value - self.assertEqual(self.tv.column('#0', 'width'), - 10 if self.wantobjects else '10') - self.assertEqual(self.tv.column('#0', width=None), - 10 if self.wantobjects else '10') - # check read-only option - self.assertRaises(tkinter.TclError, self.tv.column, '#0', id='X') - - self.assertRaises(tkinter.TclError, self.tv.column, 'invalid') - invalid_kws = [ - {'unknown_option': 'some value'}, {'stretch': 'wrong'}, - {'anchor': 'wrong'}, {'width': 'wrong'}, {'minwidth': 'wrong'} - ] - for kw in invalid_kws: - self.assertRaises(tkinter.TclError, self.tv.column, '#0', - **kw) - - - def test_delete(self): - self.assertRaises(tkinter.TclError, self.tv.delete, '#0') - - item_id = self.tv.insert('', 'end') - item2 = self.tv.insert(item_id, 'end') - self.assertEqual(self.tv.get_children(), (item_id, )) - self.assertEqual(self.tv.get_children(item_id), (item2, )) - - self.tv.delete(item_id) - self.assertFalse(self.tv.get_children()) - - # reattach should fail - self.assertRaises(tkinter.TclError, - self.tv.reattach, item_id, '', 'end') - - # test multiple item delete - item1 = self.tv.insert('', 'end') - item2 = self.tv.insert('', 'end') - self.assertEqual(self.tv.get_children(), (item1, item2)) - - self.tv.delete(item1, item2) - self.assertFalse(self.tv.get_children()) - - - def test_detach_reattach(self): - item_id = self.tv.insert('', 'end') - item2 = self.tv.insert(item_id, 'end') - - # calling detach without items is valid, although it does nothing - prev = self.tv.get_children() - self.tv.detach() # this should do nothing - self.assertEqual(prev, self.tv.get_children()) - - self.assertEqual(self.tv.get_children(), (item_id, )) - self.assertEqual(self.tv.get_children(item_id), (item2, )) - - # detach item with children - self.tv.detach(item_id) - self.assertFalse(self.tv.get_children()) - - # reattach item with children - self.tv.reattach(item_id, '', 'end') - self.assertEqual(self.tv.get_children(), (item_id, )) - self.assertEqual(self.tv.get_children(item_id), (item2, )) - - # move a children to the root - self.tv.move(item2, '', 'end') - self.assertEqual(self.tv.get_children(), (item_id, item2)) - self.assertEqual(self.tv.get_children(item_id), ()) - - # bad values - self.assertRaises(tkinter.TclError, - self.tv.reattach, 'nonexistent', '', 'end') - self.assertRaises(tkinter.TclError, - self.tv.detach, 'nonexistent') - self.assertRaises(tkinter.TclError, - self.tv.reattach, item2, 'otherparent', 'end') - self.assertRaises(tkinter.TclError, - self.tv.reattach, item2, '', 'invalid') - - # multiple detach - self.tv.detach(item_id, item2) - self.assertEqual(self.tv.get_children(), ()) - self.assertEqual(self.tv.get_children(item_id), ()) - - - def test_exists(self): - self.assertEqual(self.tv.exists('something'), False) - self.assertEqual(self.tv.exists(''), True) - self.assertEqual(self.tv.exists({}), False) - - # the following will make a tk.call equivalent to - # tk.call(treeview, "exists") which should result in an error - # in the tcl interpreter since tk requires an item. - self.assertRaises(tkinter.TclError, self.tv.exists, None) - - - def test_focus(self): - # nothing is focused right now - self.assertEqual(self.tv.focus(), '') - - item1 = self.tv.insert('', 'end') - self.tv.focus(item1) - self.assertEqual(self.tv.focus(), item1) - - self.tv.delete(item1) - self.assertEqual(self.tv.focus(), '') - - # try focusing inexistent item - self.assertRaises(tkinter.TclError, self.tv.focus, 'hi') - - - def test_heading(self): - # check a dict is returned - self.assertIsInstance(self.tv.heading('#0'), dict) - - # check a value is returned - self.tv.heading('#0', text='hi') - self.assertEqual(self.tv.heading('#0', 'text'), 'hi') - self.assertEqual(self.tv.heading('#0', text=None), 'hi') - - # invalid option - self.assertRaises(tkinter.TclError, self.tv.heading, '#0', - background=None) - # invalid value - self.assertRaises(tkinter.TclError, self.tv.heading, '#0', - anchor=1) - - def test_heading_callback(self): - def simulate_heading_click(x, y): - simulate_mouse_click(self.tv, x, y) - self.tv.update() - - success = [] # no success for now - - self.tv.pack() - self.tv.wait_visibility() - self.tv.heading('#0', command=lambda: success.append(True)) - self.tv.column('#0', width=100) - self.tv.update() - - # assuming that the coords (5, 5) fall into heading #0 - simulate_heading_click(5, 5) - if not success: - self.fail("The command associated to the treeview heading wasn't " - "invoked.") - - success = [] - commands = self.tv.master._tclCommands - self.tv.heading('#0', command=str(self.tv.heading('#0', command=None))) - self.assertEqual(commands, self.tv.master._tclCommands) - simulate_heading_click(5, 5) - if not success: - self.fail("The command associated to the treeview heading wasn't " - "invoked.") - - # XXX The following raises an error in a tcl interpreter, but not in - # Python - #self.tv.heading('#0', command='I dont exist') - #simulate_heading_click(5, 5) - - - def test_index(self): - # item 'what' doesn't exist - self.assertRaises(tkinter.TclError, self.tv.index, 'what') - - self.assertEqual(self.tv.index(''), 0) - - item1 = self.tv.insert('', 'end') - item2 = self.tv.insert('', 'end') - c1 = self.tv.insert(item1, 'end') - c2 = self.tv.insert(item1, 'end') - self.assertEqual(self.tv.index(item1), 0) - self.assertEqual(self.tv.index(c1), 0) - self.assertEqual(self.tv.index(c2), 1) - self.assertEqual(self.tv.index(item2), 1) - - self.tv.move(item2, '', 0) - self.assertEqual(self.tv.index(item2), 0) - self.assertEqual(self.tv.index(item1), 1) - - # check that index still works even after its parent and siblings - # have been detached - self.tv.detach(item1) - self.assertEqual(self.tv.index(c2), 1) - self.tv.detach(c1) - self.assertEqual(self.tv.index(c2), 0) - - # but it fails after item has been deleted - self.tv.delete(item1) - self.assertRaises(tkinter.TclError, self.tv.index, c2) - - - def test_insert_item(self): - # parent 'none' doesn't exist - self.assertRaises(tkinter.TclError, self.tv.insert, 'none', 'end') - - # open values - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', - open='') - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', - open='please') - self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=True))) - self.assertFalse(self.tv.delete(self.tv.insert('', 'end', open=False))) - - # invalid index - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'middle') - - # trying to duplicate item id is invalid - itemid = self.tv.insert('', 'end', 'first-item') - self.assertEqual(itemid, 'first-item') - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', - 'first-item') - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', - MockTclObj('first-item')) - - # unicode values - value = '\xe1ba' - item = self.tv.insert('', 'end', values=(value, )) - self.assertEqual(self.tv.item(item, 'values'), - (value,) if self.wantobjects else value) - self.assertEqual(self.tv.item(item, values=None), - (value,) if self.wantobjects else value) - - self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None))) - self.assertEqual(self.tv.item(item, values=None), - (value,) if self.wantobjects else value) - - self.assertIsInstance(self.tv.item(item), dict) - - # erase item values - self.tv.item(item, values='') - self.assertFalse(self.tv.item(item, values=None)) - - # item tags - item = self.tv.insert('', 'end', tags=[1, 2, value]) - self.assertEqual(self.tv.item(item, tags=None), - ('1', '2', value) if self.wantobjects else - '1 2 %s' % value) - self.tv.item(item, tags=[]) - self.assertFalse(self.tv.item(item, tags=None)) - self.tv.item(item, tags=(1, 2)) - self.assertEqual(self.tv.item(item, tags=None), - ('1', '2') if self.wantobjects else '1 2') - - # values with spaces - item = self.tv.insert('', 'end', values=('a b c', - '%s %s' % (value, value))) - self.assertEqual(self.tv.item(item, values=None), - ('a b c', '%s %s' % (value, value)) if self.wantobjects else - '{a b c} {%s %s}' % (value, value)) - - # text - self.assertEqual(self.tv.item( - self.tv.insert('', 'end', text="Label here"), text=None), - "Label here") - self.assertEqual(self.tv.item( - self.tv.insert('', 'end', text=value), text=None), - value) - - # test for values which are not None - itemid = self.tv.insert('', 'end', 0) - self.assertEqual(itemid, '0') - itemid = self.tv.insert('', 'end', 0.0) - self.assertEqual(itemid, '0.0') - # this is because False resolves to 0 and element with 0 iid is already present - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', False) - self.assertRaises(tkinter.TclError, self.tv.insert, '', 'end', '') - - - def test_selection(self): - self.assertRaises(TypeError, self.tv.selection, 'spam') - # item 'none' doesn't exist - self.assertRaises(tkinter.TclError, self.tv.selection_set, 'none') - self.assertRaises(tkinter.TclError, self.tv.selection_add, 'none') - self.assertRaises(tkinter.TclError, self.tv.selection_remove, 'none') - self.assertRaises(tkinter.TclError, self.tv.selection_toggle, 'none') - - item1 = self.tv.insert('', 'end') - item2 = self.tv.insert('', 'end') - c1 = self.tv.insert(item1, 'end') - c2 = self.tv.insert(item1, 'end') - c3 = self.tv.insert(item1, 'end') - self.assertEqual(self.tv.selection(), ()) - - self.tv.selection_set(c1, item2) - self.assertEqual(self.tv.selection(), (c1, item2)) - self.tv.selection_set(c2) - self.assertEqual(self.tv.selection(), (c2,)) - - self.tv.selection_add(c1, item2) - self.assertEqual(self.tv.selection(), (c1, c2, item2)) - self.tv.selection_add(item1) - self.assertEqual(self.tv.selection(), (item1, c1, c2, item2)) - self.tv.selection_add() - self.assertEqual(self.tv.selection(), (item1, c1, c2, item2)) - - self.tv.selection_remove(item1, c3) - self.assertEqual(self.tv.selection(), (c1, c2, item2)) - self.tv.selection_remove(c2) - self.assertEqual(self.tv.selection(), (c1, item2)) - self.tv.selection_remove() - self.assertEqual(self.tv.selection(), (c1, item2)) - - self.tv.selection_toggle(c1, c3) - self.assertEqual(self.tv.selection(), (c3, item2)) - self.tv.selection_toggle(item2) - self.assertEqual(self.tv.selection(), (c3,)) - self.tv.selection_toggle() - self.assertEqual(self.tv.selection(), (c3,)) - - self.tv.insert('', 'end', id='with spaces') - self.tv.selection_set('with spaces') - self.assertEqual(self.tv.selection(), ('with spaces',)) - - self.tv.insert('', 'end', id='{brace') - self.tv.selection_set('{brace') - self.assertEqual(self.tv.selection(), ('{brace',)) - - self.tv.insert('', 'end', id='unicode\u20ac') - self.tv.selection_set('unicode\u20ac') - self.assertEqual(self.tv.selection(), ('unicode\u20ac',)) - - self.tv.insert('', 'end', id=b'bytes\xe2\x82\xac') - self.tv.selection_set(b'bytes\xe2\x82\xac') - self.assertEqual(self.tv.selection(), ('bytes\xe2\x82\xac',)) - - self.tv.selection_set() - self.assertEqual(self.tv.selection(), ()) - - # Old interface - self.tv.selection_set((c1, item2)) - self.assertEqual(self.tv.selection(), (c1, item2)) - self.tv.selection_add((c1, item1)) - self.assertEqual(self.tv.selection(), (item1, c1, item2)) - self.tv.selection_remove((item1, c3)) - self.assertEqual(self.tv.selection(), (c1, item2)) - self.tv.selection_toggle((c1, c3)) - self.assertEqual(self.tv.selection(), (c3, item2)) - - - def test_set(self): - self.tv['columns'] = ['A', 'B'] - item = self.tv.insert('', 'end', values=['a', 'b']) - self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'}) - - self.tv.set(item, 'B', 'a') - self.assertEqual(self.tv.item(item, values=None), - ('a', 'a') if self.wantobjects else 'a a') - - self.tv['columns'] = ['B'] - self.assertEqual(self.tv.set(item), {'B': 'a'}) - - self.tv.set(item, 'B', 'b') - self.assertEqual(self.tv.set(item, column='B'), 'b') - self.assertEqual(self.tv.item(item, values=None), - ('b', 'a') if self.wantobjects else 'b a') - - self.tv.set(item, 'B', 123) - self.assertEqual(self.tv.set(item, 'B'), - 123 if self.wantobjects else '123') - self.assertEqual(self.tv.item(item, values=None), - (123, 'a') if self.wantobjects else '123 a') - self.assertEqual(self.tv.set(item), - {'B': 123} if self.wantobjects else {'B': '123'}) - - # inexistent column - self.assertRaises(tkinter.TclError, self.tv.set, item, 'A') - self.assertRaises(tkinter.TclError, self.tv.set, item, 'A', 'b') - - # inexistent item - self.assertRaises(tkinter.TclError, self.tv.set, 'notme') - - - def test_tag_bind(self): - events = [] - item1 = self.tv.insert('', 'end', tags=['call']) - item2 = self.tv.insert('', 'end', tags=['call']) - self.tv.tag_bind('call', '', - lambda evt: events.append(1)) - self.tv.tag_bind('call', '', - lambda evt: events.append(2)) - - self.tv.pack() - self.tv.wait_visibility() - self.tv.update() - - pos_y = set() - found = set() - for i in range(0, 100, 10): - if len(found) == 2: # item1 and item2 already found - break - item_id = self.tv.identify_row(i) - if item_id and item_id not in found: - pos_y.add(i) - found.add(item_id) - - self.assertEqual(len(pos_y), 2) # item1 and item2 y pos - for y in pos_y: - simulate_mouse_click(self.tv, 0, y) - - # by now there should be 4 things in the events list, since each - # item had a bind for two events that were simulated above - self.assertEqual(len(events), 4) - for evt in zip(events[::2], events[1::2]): - self.assertEqual(evt, (1, 2)) - - - def test_tag_configure(self): - # Just testing parameter passing for now - self.assertRaises(TypeError, self.tv.tag_configure) - self.assertRaises(tkinter.TclError, self.tv.tag_configure, - 'test', sky='blue') - self.tv.tag_configure('test', foreground='blue') - self.assertEqual(str(self.tv.tag_configure('test', 'foreground')), - 'blue') - self.assertEqual(str(self.tv.tag_configure('test', foreground=None)), - 'blue') - self.assertIsInstance(self.tv.tag_configure('test'), dict) - - def test_tag_has(self): - item1 = self.tv.insert('', 'end', text='Item 1', tags=['tag1']) - item2 = self.tv.insert('', 'end', text='Item 2', tags=['tag2']) - self.assertRaises(TypeError, self.tv.tag_has) - self.assertRaises(TclError, self.tv.tag_has, 'tag1', 'non-existing') - self.assertTrue(self.tv.tag_has('tag1', item1)) - self.assertFalse(self.tv.tag_has('tag1', item2)) - self.assertFalse(self.tv.tag_has('tag2', item1)) - self.assertTrue(self.tv.tag_has('tag2', item2)) - self.assertFalse(self.tv.tag_has('tag3', item1)) - self.assertFalse(self.tv.tag_has('tag3', item2)) - self.assertEqual(self.tv.tag_has('tag1'), (item1,)) - self.assertEqual(self.tv.tag_has('tag2'), (item2,)) - self.assertEqual(self.tv.tag_has('tag3'), ()) - - - at add_standard_options(StandardTtkOptionsTests) -class SeparatorTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'cursor', 'orient', 'style', 'takefocus', - # 'state'? - ) - default_orient = 'horizontal' - - def create(self, **kwargs): - return ttk.Separator(self.root, **kwargs) - - - at add_standard_options(StandardTtkOptionsTests) -class SizegripTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'class', 'cursor', 'style', 'takefocus', - # 'state'? - ) - - def create(self, **kwargs): - return ttk.Sizegrip(self.root, **kwargs) - -tests_gui = ( - ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest, - FrameTest, LabelFrameTest, LabelTest, MenubuttonTest, - NotebookTest, PanedWindowTest, ProgressbarTest, - RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest, - SizegripTest, SpinboxTest, TreeviewTest, WidgetTest, - ) - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py deleted file mode 100644 index 573544dd84a3..000000000000 --- a/Lib/tkinter/ttk.py +++ /dev/null @@ -1,1660 +0,0 @@ -"""Ttk wrapper. - -This module provides classes to allow using Tk themed widget set. - -Ttk is based on a revised and enhanced version of -TIP #48 (http://tip.tcl.tk/48) specified style engine. - -Its basic idea is to separate, to the extent possible, the code -implementing a widget's behavior from the code implementing its -appearance. Widget class bindings are primarily responsible for -maintaining the widget state and invoking callbacks, all aspects -of the widgets appearance lies at Themes. -""" - -__version__ = "0.3.1" - -__author__ = "Guilherme Polo " - -__all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", - "Labelframe", "LabelFrame", "Menubutton", "Notebook", "Panedwindow", - "PanedWindow", "Progressbar", "Radiobutton", "Scale", "Scrollbar", - "Separator", "Sizegrip", "Spinbox", "Style", "Treeview", - # Extensions - "LabeledScale", "OptionMenu", - # functions - "tclobjs_to_py", "setup_master"] - -import tkinter -from tkinter import _flatten, _join, _stringify, _splitdict - -# Verify if Tk is new enough to not need the Tile package -_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False - -def _load_tile(master): - if _REQUIRE_TILE: - import os - tilelib = os.environ.get('TILE_LIBRARY') - if tilelib: - # append custom tile path to the list of directories that - # Tcl uses when attempting to resolve packages with the package - # command - master.tk.eval( - 'global auto_path; ' - 'lappend auto_path {%s}' % tilelib) - - master.tk.eval('package require tile') # TclError may be raised here - master._tile_loaded = True - -def _format_optvalue(value, script=False): - """Internal function.""" - if script: - # if caller passes a Tcl script to tk.call, all the values need to - # be grouped into words (arguments to a command in Tcl dialect) - value = _stringify(value) - elif isinstance(value, (list, tuple)): - value = _join(value) - return value - -def _format_optdict(optdict, script=False, ignore=None): - """Formats optdict to a tuple to pass it to tk.call. - - E.g. (script=False): - {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns: - ('-foreground', 'blue', '-padding', '1 2 3 4')""" - - opts = [] - for opt, value in optdict.items(): - if not ignore or opt not in ignore: - opts.append("-%s" % opt) - if value is not None: - opts.append(_format_optvalue(value, script)) - - return _flatten(opts) - -def _mapdict_values(items): - # each value in mapdict is expected to be a sequence, where each item - # is another sequence containing a state (or several) and a value - # E.g. (script=False): - # [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])] - # returns: - # ['active selected', 'grey', 'focus', [1, 2, 3, 4]] - opt_val = [] - for *state, val in items: - # hacks for backward compatibility - state[0] # raise IndexError if empty - if len(state) == 1: - # if it is empty (something that evaluates to False), then - # format it to Tcl code to denote the "normal" state - state = state[0] or '' - else: - # group multiple states - state = ' '.join(state) # raise TypeError if not str - opt_val.append(state) - if val is not None: - opt_val.append(val) - return opt_val - -def _format_mapdict(mapdict, script=False): - """Formats mapdict to pass it to tk.call. - - E.g. (script=False): - {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]} - - returns: - - ('-expand', '{active selected} grey focus {1, 2, 3, 4}')""" - - opts = [] - for opt, value in mapdict.items(): - opts.extend(("-%s" % opt, - _format_optvalue(_mapdict_values(value), script))) - - return _flatten(opts) - -def _format_elemcreate(etype, script=False, *args, **kw): - """Formats args and kw according to the given element factory etype.""" - spec = None - opts = () - if etype in ("image", "vsapi"): - if etype == "image": # define an element based on an image - # first arg should be the default image name - iname = args[0] - # next args, if any, are statespec/value pairs which is almost - # a mapdict, but we just need the value - imagespec = _join(_mapdict_values(args[1:])) - spec = "%s %s" % (iname, imagespec) - - else: - # define an element whose visual appearance is drawn using the - # Microsoft Visual Styles API which is responsible for the - # themed styles on Windows XP and Vista. - # Availability: Tk 8.6, Windows XP and Vista. - class_name, part_id = args[:2] - statemap = _join(_mapdict_values(args[2:])) - spec = "%s %s %s" % (class_name, part_id, statemap) - - opts = _format_optdict(kw, script) - - elif etype == "from": # clone an element - # it expects a themename and optionally an element to clone from, - # otherwise it will clone {} (empty element) - spec = args[0] # theme name - if len(args) > 1: # elementfrom specified - opts = (_format_optvalue(args[1], script),) - - if script: - spec = '{%s}' % spec - opts = ' '.join(opts) - - return spec, opts - -def _format_layoutlist(layout, indent=0, indent_size=2): - """Formats a layout list so we can pass the result to ttk::style - layout and ttk::style settings. Note that the layout doesn't have to - be a list necessarily. - - E.g.: - [("Menubutton.background", None), - ("Menubutton.button", {"children": - [("Menubutton.focus", {"children": - [("Menubutton.padding", {"children": - [("Menubutton.label", {"side": "left", "expand": 1})] - })] - })] - }), - ("Menubutton.indicator", {"side": "right"}) - ] - - returns: - - Menubutton.background - Menubutton.button -children { - Menubutton.focus -children { - Menubutton.padding -children { - Menubutton.label -side left -expand 1 - } - } - } - Menubutton.indicator -side right""" - script = [] - - for layout_elem in layout: - elem, opts = layout_elem - opts = opts or {} - fopts = ' '.join(_format_optdict(opts, True, ("children",))) - head = "%s%s%s" % (' ' * indent, elem, (" %s" % fopts) if fopts else '') - - if "children" in opts: - script.append(head + " -children {") - indent += indent_size - newscript, indent = _format_layoutlist(opts['children'], indent, - indent_size) - script.append(newscript) - indent -= indent_size - script.append('%s}' % (' ' * indent)) - else: - script.append(head) - - return '\n'.join(script), indent - -def _script_from_settings(settings): - """Returns an appropriate script, based on settings, according to - theme_settings definition to be used by theme_settings and - theme_create.""" - script = [] - # a script will be generated according to settings passed, which - # will then be evaluated by Tcl - for name, opts in settings.items(): - # will format specific keys according to Tcl code - if opts.get('configure'): # format 'configure' - s = ' '.join(_format_optdict(opts['configure'], True)) - script.append("ttk::style configure %s %s;" % (name, s)) - - if opts.get('map'): # format 'map' - s = ' '.join(_format_mapdict(opts['map'], True)) - script.append("ttk::style map %s %s;" % (name, s)) - - if 'layout' in opts: # format 'layout' which may be empty - if not opts['layout']: - s = 'null' # could be any other word, but this one makes sense - else: - s, _ = _format_layoutlist(opts['layout']) - script.append("ttk::style layout %s {\n%s\n}" % (name, s)) - - if opts.get('element create'): # format 'element create' - eopts = opts['element create'] - etype = eopts[0] - - # find where args end, and where kwargs start - argc = 1 # etype was the first one - while argc < len(eopts) and not hasattr(eopts[argc], 'items'): - argc += 1 - - elemargs = eopts[1:argc] - elemkw = eopts[argc] if argc < len(eopts) and eopts[argc] else {} - spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw) - - script.append("ttk::style element create %s %s %s %s" % ( - name, etype, spec, opts)) - - return '\n'.join(script) - -def _list_from_statespec(stuple): - """Construct a list from the given statespec tuple according to the - accepted statespec accepted by _format_mapdict.""" - nval = [] - for val in stuple: - typename = getattr(val, 'typename', None) - if typename is None: - nval.append(val) - else: # this is a Tcl object - val = str(val) - if typename == 'StateSpec': - val = val.split() - nval.append(val) - - it = iter(nval) - return [_flatten(spec) for spec in zip(it, it)] - -def _list_from_layouttuple(tk, ltuple): - """Construct a list from the tuple returned by ttk::layout, this is - somewhat the reverse of _format_layoutlist.""" - ltuple = tk.splitlist(ltuple) - res = [] - - indx = 0 - while indx < len(ltuple): - name = ltuple[indx] - opts = {} - res.append((name, opts)) - indx += 1 - - while indx < len(ltuple): # grab name's options - opt, val = ltuple[indx:indx + 2] - if not opt.startswith('-'): # found next name - break - - opt = opt[1:] # remove the '-' from the option - indx += 2 - - if opt == 'children': - val = _list_from_layouttuple(tk, val) - - opts[opt] = val - - return res - -def _val_or_dict(tk, options, *args): - """Format options then call Tk command with args and options and return - the appropriate result. - - If no option is specified, a dict is returned. If an option is - specified with the None value, the value for that option is returned. - Otherwise, the function just sets the passed options and the caller - shouldn't be expecting a return value anyway.""" - options = _format_optdict(options) - res = tk.call(*(args + options)) - - if len(options) % 2: # option specified without a value, return its value - return res - - return _splitdict(tk, res, conv=_tclobj_to_py) - -def _convert_stringval(value): - """Converts a value to, hopefully, a more appropriate Python object.""" - value = str(value) - try: - value = int(value) - except (ValueError, TypeError): - pass - - return value - -def _to_number(x): - if isinstance(x, str): - if '.' in x: - x = float(x) - else: - x = int(x) - return x - -def _tclobj_to_py(val): - """Return value converted from Tcl object to Python object.""" - if val and hasattr(val, '__len__') and not isinstance(val, str): - if getattr(val[0], 'typename', None) == 'StateSpec': - val = _list_from_statespec(val) - else: - val = list(map(_convert_stringval, val)) - - elif hasattr(val, 'typename'): # some other (single) Tcl object - val = _convert_stringval(val) - - return val - -def tclobjs_to_py(adict): - """Returns adict with its values converted from Tcl objects to Python - objects.""" - for opt, val in adict.items(): - adict[opt] = _tclobj_to_py(val) - - return adict - -def setup_master(master=None): - """If master is not None, itself is returned. If master is None, - the default master is returned if there is one, otherwise a new - master is created and returned. - - If it is not allowed to use the default root and master is None, - RuntimeError is raised.""" - if master is None: - if tkinter._support_default_root: - master = tkinter._default_root or tkinter.Tk() - else: - raise RuntimeError( - "No master specified and tkinter is " - "configured to not support default root") - return master - - -class Style(object): - """Manipulate style database.""" - - _name = "ttk::style" - - def __init__(self, master=None): - master = setup_master(master) - - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) - - self.master = master - self.tk = self.master.tk - - - def configure(self, style, query_opt=None, **kw): - """Query or sets the default value of the specified option(s) in - style. - - Each key in kw is an option and each value is either a string or - a sequence identifying the value for that option.""" - if query_opt is not None: - kw[query_opt] = None - result = _val_or_dict(self.tk, kw, self._name, "configure", style) - if result or query_opt: - return result - - - def map(self, style, query_opt=None, **kw): - """Query or sets dynamic values of the specified option(s) in - style. - - Each key in kw is an option and each value should be a list or a - tuple (usually) containing statespecs grouped in tuples, or list, - or something else of your preference. A statespec is compound of - one or more states and then a value.""" - if query_opt is not None: - return _list_from_statespec(self.tk.splitlist( - self.tk.call(self._name, "map", style, '-%s' % query_opt))) - - return _splitdict( - self.tk, - self.tk.call(self._name, "map", style, *_format_mapdict(kw)), - conv=_tclobj_to_py) - - - def lookup(self, style, option, state=None, default=None): - """Returns the value specified for option in style. - - If state is specified it is expected to be a sequence of one - or more states. If the default argument is set, it is used as - a fallback value in case no specification for option is found.""" - state = ' '.join(state) if state else '' - - return self.tk.call(self._name, "lookup", style, '-%s' % option, - state, default) - - - def layout(self, style, layoutspec=None): - """Define the widget layout for given style. If layoutspec is - omitted, return the layout specification for given style. - - layoutspec is expected to be a list or an object different than - None that evaluates to False if you want to "turn off" that style. - If it is a list (or tuple, or something else), each item should be - a tuple where the first item is the layout name and the second item - should have the format described below: - - LAYOUTS - - A layout can contain the value None, if takes no options, or - a dict of options specifying how to arrange the element. - The layout mechanism uses a simplified version of the pack - geometry manager: given an initial cavity, each element is - allocated a parcel. Valid options/values are: - - side: whichside - Specifies which side of the cavity to place the - element; one of top, right, bottom or left. If - omitted, the element occupies the entire cavity. - - sticky: nswe - Specifies where the element is placed inside its - allocated parcel. - - children: [sublayout... ] - Specifies a list of elements to place inside the - element. Each element is a tuple (or other sequence) - where the first item is the layout name, and the other - is a LAYOUT.""" - lspec = None - if layoutspec: - lspec = _format_layoutlist(layoutspec)[0] - elif layoutspec is not None: # will disable the layout ({}, '', etc) - lspec = "null" # could be any other word, but this may make sense - # when calling layout(style) later - - return _list_from_layouttuple(self.tk, - self.tk.call(self._name, "layout", style, lspec)) - - - def element_create(self, elementname, etype, *args, **kw): - """Create a new element in the current theme of given etype.""" - spec, opts = _format_elemcreate(etype, False, *args, **kw) - self.tk.call(self._name, "element", "create", elementname, etype, - spec, *opts) - - - def element_names(self): - """Returns the list of elements defined in the current theme.""" - return tuple(n.lstrip('-') for n in self.tk.splitlist( - self.tk.call(self._name, "element", "names"))) - - - def element_options(self, elementname): - """Return the list of elementname's options.""" - return tuple(o.lstrip('-') for o in self.tk.splitlist( - self.tk.call(self._name, "element", "options", elementname))) - - - def theme_create(self, themename, parent=None, settings=None): - """Creates a new theme. - - It is an error if themename already exists. If parent is - specified, the new theme will inherit styles, elements and - layouts from the specified parent theme. If settings are present, - they are expected to have the same syntax used for theme_settings.""" - script = _script_from_settings(settings) if settings else '' - - if parent: - self.tk.call(self._name, "theme", "create", themename, - "-parent", parent, "-settings", script) - else: - self.tk.call(self._name, "theme", "create", themename, - "-settings", script) - - - def theme_settings(self, themename, settings): - """Temporarily sets the current theme to themename, apply specified - settings and then restore the previous theme. - - Each key in settings is a style and each value may contain the - keys 'configure', 'map', 'layout' and 'element create' and they - are expected to have the same format as specified by the methods - configure, map, layout and element_create respectively.""" - script = _script_from_settings(settings) - self.tk.call(self._name, "theme", "settings", themename, script) - - - def theme_names(self): - """Returns a list of all known themes.""" - return self.tk.splitlist(self.tk.call(self._name, "theme", "names")) - - - def theme_use(self, themename=None): - """If themename is None, returns the theme in use, otherwise, set - the current theme to themename, refreshes all widgets and emits - a <> event.""" - if themename is None: - # Starting on Tk 8.6, checking this global is no longer needed - # since it allows doing self.tk.call(self._name, "theme", "use") - return self.tk.eval("return $ttk::currentTheme") - - # using "ttk::setTheme" instead of "ttk::style theme use" causes - # the variable currentTheme to be updated, also, ttk::setTheme calls - # "ttk::style theme use" in order to change theme. - self.tk.call("ttk::setTheme", themename) - - -class Widget(tkinter.Widget): - """Base class for Tk themed widgets.""" - - def __init__(self, master, widgetname, kw=None): - """Constructs a Ttk Widget with the parent master. - - STANDARD OPTIONS - - class, cursor, takefocus, style - - SCROLLABLE WIDGET OPTIONS - - xscrollcommand, yscrollcommand - - LABEL WIDGET OPTIONS - - text, textvariable, underline, image, compound, width - - WIDGET STATES - - active, disabled, focus, pressed, selected, background, - readonly, alternate, invalid - """ - master = setup_master(master) - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) - tkinter.Widget.__init__(self, master, widgetname, kw=kw) - - - def identify(self, x, y): - """Returns the name of the element at position x, y, or the empty - string if the point does not lie within any element. - - x and y are pixel coordinates relative to the widget.""" - return self.tk.call(self._w, "identify", x, y) - - - def instate(self, statespec, callback=None, *args, **kw): - """Test the widget's state. - - If callback is not specified, returns True if the widget state - matches statespec and False otherwise. If callback is specified, - then it will be invoked with *args, **kw if the widget state - matches statespec. statespec is expected to be a sequence.""" - ret = self.tk.getboolean( - self.tk.call(self._w, "instate", ' '.join(statespec))) - if ret and callback: - return callback(*args, **kw) - - return ret - - - def state(self, statespec=None): - """Modify or inquire widget state. - - Widget state is returned if statespec is None, otherwise it is - set according to the statespec flags and then a new state spec - is returned indicating which flags were changed. statespec is - expected to be a sequence.""" - if statespec is not None: - statespec = ' '.join(statespec) - - return self.tk.splitlist(str(self.tk.call(self._w, "state", statespec))) - - -class Button(Widget): - """Ttk Button widget, displays a textual label and/or image, and - evaluates a command when pressed.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Button widget with the parent master. - - STANDARD OPTIONS - - class, compound, cursor, image, state, style, takefocus, - text, textvariable, underline, width - - WIDGET-SPECIFIC OPTIONS - - command, default, width - """ - Widget.__init__(self, master, "ttk::button", kw) - - - def invoke(self): - """Invokes the command associated with the button.""" - return self.tk.call(self._w, "invoke") - - -class Checkbutton(Widget): - """Ttk Checkbutton widget which is either in on- or off-state.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Checkbutton widget with the parent master. - - STANDARD OPTIONS - - class, compound, cursor, image, state, style, takefocus, - text, textvariable, underline, width - - WIDGET-SPECIFIC OPTIONS - - command, offvalue, onvalue, variable - """ - Widget.__init__(self, master, "ttk::checkbutton", kw) - - - def invoke(self): - """Toggles between the selected and deselected states and - invokes the associated command. If the widget is currently - selected, sets the option variable to the offvalue option - and deselects the widget; otherwise, sets the option variable - to the option onvalue. - - Returns the result of the associated command.""" - return self.tk.call(self._w, "invoke") - - -class Entry(Widget, tkinter.Entry): - """Ttk Entry widget displays a one-line text string and allows that - string to be edited by the user.""" - - def __init__(self, master=None, widget=None, **kw): - """Constructs a Ttk Entry widget with the parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus, xscrollcommand - - WIDGET-SPECIFIC OPTIONS - - exportselection, invalidcommand, justify, show, state, - textvariable, validate, validatecommand, width - - VALIDATION MODES - - none, key, focus, focusin, focusout, all - """ - Widget.__init__(self, master, widget or "ttk::entry", kw) - - - def bbox(self, index): - """Return a tuple of (x, y, width, height) which describes the - bounding box of the character given by index.""" - return self._getints(self.tk.call(self._w, "bbox", index)) - - - def identify(self, x, y): - """Returns the name of the element at position x, y, or the - empty string if the coordinates are outside the window.""" - return self.tk.call(self._w, "identify", x, y) - - - def validate(self): - """Force revalidation, independent of the conditions specified - by the validate option. Returns False if validation fails, True - if it succeeds. Sets or clears the invalid state accordingly.""" - return self.tk.getboolean(self.tk.call(self._w, "validate")) - - -class Combobox(Entry): - """Ttk Combobox widget combines a text field with a pop-down list of - values.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Combobox widget with the parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - exportselection, justify, height, postcommand, state, - textvariable, values, width - """ - Entry.__init__(self, master, "ttk::combobox", **kw) - - - def current(self, newindex=None): - """If newindex is supplied, sets the combobox value to the - element at position newindex in the list of values. Otherwise, - returns the index of the current value in the list of values - or -1 if the current value does not appear in the list.""" - if newindex is None: - return self.tk.getint(self.tk.call(self._w, "current")) - return self.tk.call(self._w, "current", newindex) - - - def set(self, value): - """Sets the value of the combobox to value.""" - self.tk.call(self._w, "set", value) - - -class Frame(Widget): - """Ttk Frame widget is a container, used to group other widgets - together.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Frame with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - borderwidth, relief, padding, width, height - """ - Widget.__init__(self, master, "ttk::frame", kw) - - -class Label(Widget): - """Ttk Label widget displays a textual label and/or image.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Label with parent master. - - STANDARD OPTIONS - - class, compound, cursor, image, style, takefocus, text, - textvariable, underline, width - - WIDGET-SPECIFIC OPTIONS - - anchor, background, font, foreground, justify, padding, - relief, text, wraplength - """ - Widget.__init__(self, master, "ttk::label", kw) - - -class Labelframe(Widget): - """Ttk Labelframe widget is a container used to group other widgets - together. It has an optional label, which may be a plain text string - or another widget.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Labelframe with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - labelanchor, text, underline, padding, labelwidget, width, - height - """ - Widget.__init__(self, master, "ttk::labelframe", kw) - -LabelFrame = Labelframe # tkinter name compatibility - - -class Menubutton(Widget): - """Ttk Menubutton widget displays a textual label and/or image, and - displays a menu when pressed.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Menubutton with parent master. - - STANDARD OPTIONS - - class, compound, cursor, image, state, style, takefocus, - text, textvariable, underline, width - - WIDGET-SPECIFIC OPTIONS - - direction, menu - """ - Widget.__init__(self, master, "ttk::menubutton", kw) - - -class Notebook(Widget): - """Ttk Notebook widget manages a collection of windows and displays - a single one at a time. Each child window is associated with a tab, - which the user may select to change the currently-displayed window.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Notebook with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - height, padding, width - - TAB OPTIONS - - state, sticky, padding, text, image, compound, underline - - TAB IDENTIFIERS (tab_id) - - The tab_id argument found in several methods may take any of - the following forms: - - * An integer between zero and the number of tabs - * The name of a child window - * A positional specification of the form "@x,y", which - defines the tab - * The string "current", which identifies the - currently-selected tab - * The string "end", which returns the number of tabs (only - valid for method index) - """ - Widget.__init__(self, master, "ttk::notebook", kw) - - - def add(self, child, **kw): - """Adds a new tab to the notebook. - - If window is currently managed by the notebook but hidden, it is - restored to its previous position.""" - self.tk.call(self._w, "add", child, *(_format_optdict(kw))) - - - def forget(self, tab_id): - """Removes the tab specified by tab_id, unmaps and unmanages the - associated window.""" - self.tk.call(self._w, "forget", tab_id) - - - def hide(self, tab_id): - """Hides the tab specified by tab_id. - - The tab will not be displayed, but the associated window remains - managed by the notebook and its configuration remembered. Hidden - tabs may be restored with the add command.""" - self.tk.call(self._w, "hide", tab_id) - - - def identify(self, x, y): - """Returns the name of the tab element at position x, y, or the - empty string if none.""" - return self.tk.call(self._w, "identify", x, y) - - - def index(self, tab_id): - """Returns the numeric index of the tab specified by tab_id, or - the total number of tabs if tab_id is the string "end".""" - return self.tk.getint(self.tk.call(self._w, "index", tab_id)) - - - def insert(self, pos, child, **kw): - """Inserts a pane at the specified position. - - pos is either the string end, an integer index, or the name of - a managed child. If child is already managed by the notebook, - moves it to the specified position.""" - self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) - - - def select(self, tab_id=None): - """Selects the specified tab. - - The associated child window will be displayed, and the - previously-selected window (if different) is unmapped. If tab_id - is omitted, returns the widget name of the currently selected - pane.""" - return self.tk.call(self._w, "select", tab_id) - - - def tab(self, tab_id, option=None, **kw): - """Query or modify the options of the specific tab_id. - - If kw is not given, returns a dict of the tab option values. If option - is specified, returns the value of that option. Otherwise, sets the - options to the corresponding values.""" - if option is not None: - kw[option] = None - return _val_or_dict(self.tk, kw, self._w, "tab", tab_id) - - - def tabs(self): - """Returns a list of windows managed by the notebook.""" - return self.tk.splitlist(self.tk.call(self._w, "tabs") or ()) - - - def enable_traversal(self): - """Enable keyboard traversal for a toplevel window containing - this notebook. - - This will extend the bindings for the toplevel window containing - this notebook as follows: - - Control-Tab: selects the tab following the currently selected - one - - Shift-Control-Tab: selects the tab preceding the currently - selected one - - Alt-K: where K is the mnemonic (underlined) character of any - tab, will select that tab. - - Multiple notebooks in a single toplevel may be enabled for - traversal, including nested notebooks. However, notebook traversal - only works properly if all panes are direct children of the - notebook.""" - # The only, and good, difference I see is about mnemonics, which works - # after calling this method. Control-Tab and Shift-Control-Tab always - # works (here at least). - self.tk.call("ttk::notebook::enableTraversal", self._w) - - -class Panedwindow(Widget, tkinter.PanedWindow): - """Ttk Panedwindow widget displays a number of subwindows, stacked - either vertically or horizontally.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Panedwindow with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - orient, width, height - - PANE OPTIONS - - weight - """ - Widget.__init__(self, master, "ttk::panedwindow", kw) - - - forget = tkinter.PanedWindow.forget # overrides Pack.forget - - - def insert(self, pos, child, **kw): - """Inserts a pane at the specified positions. - - pos is either the string end, and integer index, or the name - of a child. If child is already managed by the paned window, - moves it to the specified position.""" - self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) - - - def pane(self, pane, option=None, **kw): - """Query or modify the options of the specified pane. - - pane is either an integer index or the name of a managed subwindow. - If kw is not given, returns a dict of the pane option values. If - option is specified then the value for that option is returned. - Otherwise, sets the options to the corresponding values.""" - if option is not None: - kw[option] = None - return _val_or_dict(self.tk, kw, self._w, "pane", pane) - - - def sashpos(self, index, newpos=None): - """If newpos is specified, sets the position of sash number index. - - May adjust the positions of adjacent sashes to ensure that - positions are monotonically increasing. Sash positions are further - constrained to be between 0 and the total size of the widget. - - Returns the new position of sash number index.""" - return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos)) - -PanedWindow = Panedwindow # tkinter name compatibility - - -class Progressbar(Widget): - """Ttk Progressbar widget shows the status of a long-running - operation. They can operate in two modes: determinate mode shows the - amount completed relative to the total amount of work to be done, and - indeterminate mode provides an animated display to let the user know - that something is happening.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Progressbar with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - orient, length, mode, maximum, value, variable, phase - """ - Widget.__init__(self, master, "ttk::progressbar", kw) - - - def start(self, interval=None): - """Begin autoincrement mode: schedules a recurring timer event - that calls method step every interval milliseconds. - - interval defaults to 50 milliseconds (20 steps/second) if omitted.""" - self.tk.call(self._w, "start", interval) - - - def step(self, amount=None): - """Increments the value option by amount. - - amount defaults to 1.0 if omitted.""" - self.tk.call(self._w, "step", amount) - - - def stop(self): - """Stop autoincrement mode: cancels any recurring timer event - initiated by start.""" - self.tk.call(self._w, "stop") - - -class Radiobutton(Widget): - """Ttk Radiobutton widgets are used in groups to show or change a - set of mutually-exclusive options.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Radiobutton with parent master. - - STANDARD OPTIONS - - class, compound, cursor, image, state, style, takefocus, - text, textvariable, underline, width - - WIDGET-SPECIFIC OPTIONS - - command, value, variable - """ - Widget.__init__(self, master, "ttk::radiobutton", kw) - - - def invoke(self): - """Sets the option variable to the option value, selects the - widget, and invokes the associated command. - - Returns the result of the command, or an empty string if - no command is specified.""" - return self.tk.call(self._w, "invoke") - - -class Scale(Widget, tkinter.Scale): - """Ttk Scale widget is typically used to control the numeric value of - a linked variable that varies uniformly over some range.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Scale with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - command, from, length, orient, to, value, variable - """ - Widget.__init__(self, master, "ttk::scale", kw) - - - def configure(self, cnf=None, **kw): - """Modify or query scale options. - - Setting a value for any of the "from", "from_" or "to" options - generates a <> event.""" - if cnf: - kw.update(cnf) - Widget.configure(self, **kw) - if any(['from' in kw, 'from_' in kw, 'to' in kw]): - self.event_generate('<>') - - - def get(self, x=None, y=None): - """Get the current value of the value option, or the value - corresponding to the coordinates x, y if they are specified. - - x and y are pixel coordinates relative to the scale widget - origin.""" - return self.tk.call(self._w, 'get', x, y) - - -class Scrollbar(Widget, tkinter.Scrollbar): - """Ttk Scrollbar controls the viewport of a scrollable widget.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Scrollbar with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - command, orient - """ - Widget.__init__(self, master, "ttk::scrollbar", kw) - - -class Separator(Widget): - """Ttk Separator widget displays a horizontal or vertical separator - bar.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Separator with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus - - WIDGET-SPECIFIC OPTIONS - - orient - """ - Widget.__init__(self, master, "ttk::separator", kw) - - -class Sizegrip(Widget): - """Ttk Sizegrip allows the user to resize the containing toplevel - window by pressing and dragging the grip.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Sizegrip with parent master. - - STANDARD OPTIONS - - class, cursor, state, style, takefocus - """ - Widget.__init__(self, master, "ttk::sizegrip", kw) - - -class Spinbox(Entry): - """Ttk Spinbox is an Entry with increment and decrement arrows - - It is commonly used for number entry or to select from a list of - string values. - """ - - def __init__(self, master=None, **kw): - """Construct a Ttk Spinbox widget with the parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus, validate, - validatecommand, xscrollcommand, invalidcommand - - WIDGET-SPECIFIC OPTIONS - - to, from_, increment, values, wrap, format, command - """ - Entry.__init__(self, master, "ttk::spinbox", **kw) - - - def set(self, value): - """Sets the value of the Spinbox to value.""" - self.tk.call(self._w, "set", value) - - -class Treeview(Widget, tkinter.XView, tkinter.YView): - """Ttk Treeview widget displays a hierarchical collection of items. - - Each item has a textual label, an optional image, and an optional list - of data values. The data values are displayed in successive columns - after the tree label.""" - - def __init__(self, master=None, **kw): - """Construct a Ttk Treeview with parent master. - - STANDARD OPTIONS - - class, cursor, style, takefocus, xscrollcommand, - yscrollcommand - - WIDGET-SPECIFIC OPTIONS - - columns, displaycolumns, height, padding, selectmode, show - - ITEM OPTIONS - - text, image, values, open, tags - - TAG OPTIONS - - foreground, background, font, image - """ - Widget.__init__(self, master, "ttk::treeview", kw) - - - def bbox(self, item, column=None): - """Returns the bounding box (relative to the treeview widget's - window) of the specified item in the form x y width height. - - If column is specified, returns the bounding box of that cell. - If the item is not visible (i.e., if it is a descendant of a - closed item or is scrolled offscreen), returns an empty string.""" - return self._getints(self.tk.call(self._w, "bbox", item, column)) or '' - - - def get_children(self, item=None): - """Returns a tuple of children belonging to item. - - If item is not specified, returns root children.""" - return self.tk.splitlist( - self.tk.call(self._w, "children", item or '') or ()) - - - def set_children(self, item, *newchildren): - """Replaces item's child with newchildren. - - Children present in item that are not present in newchildren - are detached from tree. No items in newchildren may be an - ancestor of item.""" - self.tk.call(self._w, "children", item, newchildren) - - - def column(self, column, option=None, **kw): - """Query or modify the options for the specified column. - - If kw is not given, returns a dict of the column option values. If - option is specified then the value for that option is returned. - Otherwise, sets the options to the corresponding values.""" - if option is not None: - kw[option] = None - return _val_or_dict(self.tk, kw, self._w, "column", column) - - - def delete(self, *items): - """Delete all specified items and all their descendants. The root - item may not be deleted.""" - self.tk.call(self._w, "delete", items) - - - def detach(self, *items): - """Unlinks all of the specified items from the tree. - - The items and all of their descendants are still present, and may - be reinserted at another point in the tree, but will not be - displayed. The root item may not be detached.""" - self.tk.call(self._w, "detach", items) - - - def exists(self, item): - """Returns True if the specified item is present in the tree, - False otherwise.""" - return self.tk.getboolean(self.tk.call(self._w, "exists", item)) - - - def focus(self, item=None): - """If item is specified, sets the focus item to item. Otherwise, - returns the current focus item, or '' if there is none.""" - return self.tk.call(self._w, "focus", item) - - - def heading(self, column, option=None, **kw): - """Query or modify the heading options for the specified column. - - If kw is not given, returns a dict of the heading option values. If - option is specified then the value for that option is returned. - Otherwise, sets the options to the corresponding values. - - Valid options/values are: - text: text - The text to display in the column heading - image: image_name - Specifies an image to display to the right of the column - heading - anchor: anchor - Specifies how the heading text should be aligned. One of - the standard Tk anchor values - command: callback - A callback to be invoked when the heading label is - pressed. - - To configure the tree column heading, call this with column = "#0" """ - cmd = kw.get('command') - if cmd and not isinstance(cmd, str): - # callback not registered yet, do it now - kw['command'] = self.master.register(cmd, self._substitute) - - if option is not None: - kw[option] = None - - return _val_or_dict(self.tk, kw, self._w, 'heading', column) - - - def identify(self, component, x, y): - """Returns a description of the specified component under the - point given by x and y, or the empty string if no such component - is present at that position.""" - return self.tk.call(self._w, "identify", component, x, y) - - - def identify_row(self, y): - """Returns the item ID of the item at position y.""" - return self.identify("row", 0, y) - - - def identify_column(self, x): - """Returns the data column identifier of the cell at position x. - - The tree column has ID #0.""" - return self.identify("column", x, 0) - - - def identify_region(self, x, y): - """Returns one of: - - heading: Tree heading area. - separator: Space between two columns headings; - tree: The tree area. - cell: A data cell. - - * Availability: Tk 8.6""" - return self.identify("region", x, y) - - - def identify_element(self, x, y): - """Returns the element at position x, y. - - * Availability: Tk 8.6""" - return self.identify("element", x, y) - - - def index(self, item): - """Returns the integer index of item within its parent's list - of children.""" - return self.tk.getint(self.tk.call(self._w, "index", item)) - - - def insert(self, parent, index, iid=None, **kw): - """Creates a new item and return the item identifier of the newly - created item. - - parent is the item ID of the parent item, or the empty string - to create a new top-level item. index is an integer, or the value - end, specifying where in the list of parent's children to insert - the new item. If index is less than or equal to zero, the new node - is inserted at the beginning, if index is greater than or equal to - the current number of children, it is inserted at the end. If iid - is specified, it is used as the item identifier, iid must not - already exist in the tree. Otherwise, a new unique identifier - is generated.""" - opts = _format_optdict(kw) - if iid is not None: - res = self.tk.call(self._w, "insert", parent, index, - "-id", iid, *opts) - else: - res = self.tk.call(self._w, "insert", parent, index, *opts) - - return res - - - def item(self, item, option=None, **kw): - """Query or modify the options for the specified item. - - If no options are given, a dict with options/values for the item - is returned. If option is specified then the value for that option - is returned. Otherwise, sets the options to the corresponding - values as given by kw.""" - if option is not None: - kw[option] = None - return _val_or_dict(self.tk, kw, self._w, "item", item) - - - def move(self, item, parent, index): - """Moves item to position index in parent's list of children. - - It is illegal to move an item under one of its descendants. If - index is less than or equal to zero, item is moved to the - beginning, if greater than or equal to the number of children, - it is moved to the end. If item was detached it is reattached.""" - self.tk.call(self._w, "move", item, parent, index) - - reattach = move # A sensible method name for reattaching detached items - - - def next(self, item): - """Returns the identifier of item's next sibling, or '' if item - is the last child of its parent.""" - return self.tk.call(self._w, "next", item) - - - def parent(self, item): - """Returns the ID of the parent of item, or '' if item is at the - top level of the hierarchy.""" - return self.tk.call(self._w, "parent", item) - - - def prev(self, item): - """Returns the identifier of item's previous sibling, or '' if - item is the first child of its parent.""" - return self.tk.call(self._w, "prev", item) - - - def see(self, item): - """Ensure that item is visible. - - Sets all of item's ancestors open option to True, and scrolls - the widget if necessary so that item is within the visible - portion of the tree.""" - self.tk.call(self._w, "see", item) - - - def selection(self): - """Returns the tuple of selected items.""" - return self.tk.splitlist(self.tk.call(self._w, "selection")) - - - def _selection(self, selop, items): - if len(items) == 1 and isinstance(items[0], (tuple, list)): - items = items[0] - - self.tk.call(self._w, "selection", selop, items) - - - def selection_set(self, *items): - """The specified items becomes the new selection.""" - self._selection("set", items) - - - def selection_add(self, *items): - """Add all of the specified items to the selection.""" - self._selection("add", items) - - - def selection_remove(self, *items): - """Remove all of the specified items from the selection.""" - self._selection("remove", items) - - - def selection_toggle(self, *items): - """Toggle the selection state of each specified item.""" - self._selection("toggle", items) - - - def set(self, item, column=None, value=None): - """Query or set the value of given item. - - With one argument, return a dictionary of column/value pairs - for the specified item. With two arguments, return the current - value of the specified column. With three arguments, set the - value of given column in given item to the specified value.""" - res = self.tk.call(self._w, "set", item, column, value) - if column is None and value is None: - return _splitdict(self.tk, res, - cut_minus=False, conv=_tclobj_to_py) - else: - return res - - - def tag_bind(self, tagname, sequence=None, callback=None): - """Bind a callback for the given event sequence to the tag tagname. - When an event is delivered to an item, the callbacks for each - of the item's tags option are called.""" - self._bind((self._w, "tag", "bind", tagname), sequence, callback, add=0) - - - def tag_configure(self, tagname, option=None, **kw): - """Query or modify the options for the specified tagname. - - If kw is not given, returns a dict of the option settings for tagname. - If option is specified, returns the value for that option for the - specified tagname. Otherwise, sets the options to the corresponding - values for the given tagname.""" - if option is not None: - kw[option] = None - return _val_or_dict(self.tk, kw, self._w, "tag", "configure", - tagname) - - - def tag_has(self, tagname, item=None): - """If item is specified, returns 1 or 0 depending on whether the - specified item has the given tagname. Otherwise, returns a list of - all items which have the specified tag. - - * Availability: Tk 8.6""" - if item is None: - return self.tk.splitlist( - self.tk.call(self._w, "tag", "has", tagname)) - else: - return self.tk.getboolean( - self.tk.call(self._w, "tag", "has", tagname, item)) - - -# Extensions - -class LabeledScale(Frame): - """A Ttk Scale widget with a Ttk Label widget indicating its - current value. - - The Ttk Scale can be accessed through instance.scale, and Ttk Label - can be accessed through instance.label""" - - def __init__(self, master=None, variable=None, from_=0, to=10, **kw): - """Construct a horizontal LabeledScale with parent master, a - variable to be associated with the Ttk Scale widget and its range. - If variable is not specified, a tkinter.IntVar is created. - - WIDGET-SPECIFIC OPTIONS - - compound: 'top' or 'bottom' - Specifies how to display the label relative to the scale. - Defaults to 'top'. - """ - self._label_top = kw.pop('compound', 'top') == 'top' - - Frame.__init__(self, master, **kw) - self._variable = variable or tkinter.IntVar(master) - self._variable.set(from_) - self._last_valid = from_ - - self.label = Label(self) - self.scale = Scale(self, variable=self._variable, from_=from_, to=to) - self.scale.bind('<>', self._adjust) - - # position scale and label according to the compound option - scale_side = 'bottom' if self._label_top else 'top' - label_side = 'top' if scale_side == 'bottom' else 'bottom' - self.scale.pack(side=scale_side, fill='x') - tmp = Label(self).pack(side=label_side) # place holder - self.label.place(anchor='n' if label_side == 'top' else 's') - - # update the label as scale or variable changes - self.__tracecb = self._variable.trace_variable('w', self._adjust) - self.bind('', self._adjust) - self.bind('', self._adjust) - - - def destroy(self): - """Destroy this widget and possibly its associated variable.""" - try: - self._variable.trace_vdelete('w', self.__tracecb) - except AttributeError: - pass - else: - del self._variable - super().destroy() - self.label = None - self.scale = None - - - def _adjust(self, *args): - """Adjust the label position according to the scale.""" - def adjust_label(): - self.update_idletasks() # "force" scale redraw - - x, y = self.scale.coords() - if self._label_top: - y = self.scale.winfo_y() - self.label.winfo_reqheight() - else: - y = self.scale.winfo_reqheight() + self.label.winfo_reqheight() - - self.label.place_configure(x=x, y=y) - - from_ = _to_number(self.scale['from']) - to = _to_number(self.scale['to']) - if to < from_: - from_, to = to, from_ - newval = self._variable.get() - if not from_ <= newval <= to: - # value outside range, set value back to the last valid one - self.value = self._last_valid - return - - self._last_valid = newval - self.label['text'] = newval - self.after_idle(adjust_label) - - @property - def value(self): - """Return current scale value.""" - return self._variable.get() - - @value.setter - def value(self, val): - """Set new scale value.""" - self._variable.set(val) - - -class OptionMenu(Menubutton): - """Themed OptionMenu, based after tkinter's OptionMenu, which allows - the user to select a value from a menu.""" - - def __init__(self, master, variable, default=None, *values, **kwargs): - """Construct a themed OptionMenu widget with master as the parent, - the resource textvariable set to variable, the initially selected - value specified by the default parameter, the menu values given by - *values and additional keywords. - - WIDGET-SPECIFIC OPTIONS - - style: stylename - Menubutton style. - direction: 'above', 'below', 'left', 'right', or 'flush' - Menubutton direction. - command: callback - A callback that will be invoked after selecting an item. - """ - kw = {'textvariable': variable, 'style': kwargs.pop('style', None), - 'direction': kwargs.pop('direction', None)} - Menubutton.__init__(self, master, **kw) - self['menu'] = tkinter.Menu(self, tearoff=False) - - self._variable = variable - self._callback = kwargs.pop('command', None) - if kwargs: - raise tkinter.TclError('unknown option -%s' % ( - next(iter(kwargs.keys())))) - - self.set_menu(default, *values) - - - def __getitem__(self, item): - if item == 'menu': - return self.nametowidget(Menubutton.__getitem__(self, item)) - - return Menubutton.__getitem__(self, item) - - - def set_menu(self, default=None, *values): - """Build a new menu of radiobuttons with *values and optionally - a default value.""" - menu = self['menu'] - menu.delete(0, 'end') - for val in values: - menu.add_radiobutton(label=val, - command=tkinter._setit(self._variable, val, self._callback), - variable=self._variable) - - if default: - self._variable.set(default) - - - def destroy(self): - """Destroy this widget and its associated variable.""" - try: - del self._variable - except AttributeError: - pass - super().destroy() diff --git a/Misc/NEWS.d/next/Library/2018-05-08-08-03-34.bpo-33096.0hsFhL.rst b/Misc/NEWS.d/next/Library/2018-05-08-08-03-34.bpo-33096.0hsFhL.rst new file mode 100644 index 000000000000..2fd23c73e3b6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-08-03-34.bpo-33096.0hsFhL.rst @@ -0,0 +1 @@ +Removed unintentionally backported from Python 3 Tkinter files. From solipsis at pitrou.net Tue May 8 05:13:57 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 08 May 2018 09:13:57 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=31 Message-ID: <20180508091357.1.5310E3541535AA19@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [-7, 1, 7] memory blocks, sum=1 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_logging leaked [0, 0, 26] memory blocks, sum=26 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflog5R2DMx', '--timeout', '7200'] From webhook-mailer at python.org Tue May 8 08:45:20 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 08 May 2018 12:45:20 -0000 Subject: [Python-checkins] bpo-33144: Fix choosing random.Random._randbelow implementation. (GH-6563) Message-ID: https://github.com/python/cpython/commit/ec1622d56c80d15740f7f8459c9a79fd55f5d3c7 commit: ec1622d56c80d15740f7f8459c9a79fd55f5d3c7 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-08T15:45:15+03:00 summary: bpo-33144: Fix choosing random.Random._randbelow implementation. (GH-6563) random() takes precedence over getrandbits() if defined later in the class tree. files: M Lib/random.py M Lib/test/test_random.py diff --git a/Lib/random.py b/Lib/random.py index 0ed5511e9f63..1e0dcc87ed4a 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -102,18 +102,16 @@ def __init_subclass__(cls, **kwargs): ranges. """ - if (cls.random is _random.Random.random) or ( - cls.getrandbits is not _random.Random.getrandbits): - # The original random() builtin method has not been overridden - # or a new getrandbits() was supplied. - # The subclass can use the getrandbits-dependent implementation - # of _randbelow(). - cls._randbelow = cls._randbelow_with_getrandbits - else: - # There's an overridden random() method but no new getrandbits(), - # so the subclass can only use the getrandbits-independent - # implementation of _randbelow(). - cls._randbelow = cls._randbelow_without_getrandbits + for c in cls.__mro__: + if '_randbelow' in c.__dict__: + # just inherit it + break + if 'getrandbits' in c.__dict__: + cls._randbelow = cls._randbelow_with_getrandbits + break + if 'random' in c.__dict__: + cls._randbelow = cls._randbelow_without_getrandbits + break def seed(self, a=None, version=2): """Initialize internal state from hashable object. diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index d91908b03d02..e7ef68ba3d26 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -5,7 +5,6 @@ import time import pickle import warnings -import logging from functools import partial from math import log, exp, pi, fsum, sin, factorial from test import support @@ -940,6 +939,7 @@ def test_betavariate_return_zero(self, gammavariate_mock): gammavariate_mock.return_value = 0.0 self.assertEqual(0.0, random.betavariate(2.71828, 3.14159)) + class TestRandomSubclassing(unittest.TestCase): def test_random_subclass_with_kwargs(self): # SF bug #1486663 -- this used to erroneously raise a TypeError @@ -958,30 +958,80 @@ def test_subclasses_overriding_methods(self): # randrange class SubClass1(random.Random): def random(self): - return super().random() + called.add('SubClass1.random') + return random.Random.random(self) def getrandbits(self, n): - logging.getLogger('getrandbits').info('used getrandbits') - return super().getrandbits(n) - with self.assertLogs('getrandbits'): - SubClass1().randrange(42) + called.add('SubClass1.getrandbits') + return random.Random.getrandbits(self, n) + called = set() + SubClass1().randrange(42) + self.assertEqual(called, {'SubClass1.getrandbits'}) # subclass providing only random => can only use random for randrange class SubClass2(random.Random): def random(self): - logging.getLogger('random').info('used random') - return super().random() - with self.assertLogs('random'): - SubClass2().randrange(42) + called.add('SubClass2.random') + return random.Random.random(self) + called = set() + SubClass2().randrange(42) + self.assertEqual(called, {'SubClass2.random'}) # subclass defining getrandbits to complement its inherited random # => can now rely on getrandbits for randrange again class SubClass3(SubClass2): def getrandbits(self, n): - logging.getLogger('getrandbits').info('used getrandbits') - return super().getrandbits(n) - with self.assertLogs('getrandbits'): - SubClass3().randrange(42) + called.add('SubClass3.getrandbits') + return random.Random.getrandbits(self, n) + called = set() + SubClass3().randrange(42) + self.assertEqual(called, {'SubClass3.getrandbits'}) + + # subclass providing only random and inherited getrandbits + # => random takes precedence + class SubClass4(SubClass3): + def random(self): + called.add('SubClass4.random') + return random.Random.random(self) + called = set() + SubClass4().randrange(42) + self.assertEqual(called, {'SubClass4.random'}) + + # Following subclasses don't define random or getrandbits directly, + # but inherit them from classes which are not subclasses of Random + class Mixin1: + def random(self): + called.add('Mixin1.random') + return random.Random.random(self) + class Mixin2: + def getrandbits(self, n): + called.add('Mixin2.getrandbits') + return random.Random.getrandbits(self, n) + + class SubClass5(Mixin1, random.Random): + pass + called = set() + SubClass5().randrange(42) + self.assertEqual(called, {'Mixin1.random'}) + + class SubClass6(Mixin2, random.Random): + pass + called = set() + SubClass6().randrange(42) + self.assertEqual(called, {'Mixin2.getrandbits'}) + + class SubClass7(Mixin1, Mixin2, random.Random): + pass + called = set() + SubClass7().randrange(42) + self.assertEqual(called, {'Mixin1.random'}) + + class SubClass8(Mixin2, Mixin1, random.Random): + pass + called = set() + SubClass8().randrange(42) + self.assertEqual(called, {'Mixin2.getrandbits'}) + class TestModule(unittest.TestCase): def testMagicConstants(self): From webhook-mailer at python.org Tue May 8 14:38:51 2018 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Tue, 08 May 2018 18:38:51 -0000 Subject: [Python-checkins] bpo-32717: Document PEP 560 (GH-6726) Message-ID: https://github.com/python/cpython/commit/bd5f96581bf23f6d05fc106996428a8043b6b084 commit: bd5f96581bf23f6d05fc106996428a8043b6b084 branch: master author: Ivan Levkivskyi committer: GitHub date: 2018-05-08T19:38:41+01:00 summary: bpo-32717: Document PEP 560 (GH-6726) files: M Doc/library/types.rst M Doc/reference/datamodel.rst M Doc/whatsnew/3.7.rst diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 67cd4d702ad4..e17070022cd2 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -59,7 +59,7 @@ Dynamic Type Creation The default value for the ``namespace`` element of the returned tuple has changed. Now an insertion-order-preserving mapping is - used when the metaclass does not have a ``__prepare__`` method, + used when the metaclass does not have a ``__prepare__`` method. .. seealso:: @@ -69,6 +69,23 @@ Dynamic Type Creation :pep:`3115` - Metaclasses in Python 3000 Introduced the ``__prepare__`` namespace hook +.. function:: resolve_bases(bases) + + Resolve MRO entries dynamically as specified by :pep:`560`. + + This function looks for items in *bases* that are not instances of + :class:`type`, and returns a tuple where each such object that has + an ``__mro_entries__`` method is replaced with an unpacked result of + calling this method. If a *bases* item is an instance of :class:`type`, + or it doesn't have an ``__mro_entries__`` method, then it is included in + the return tuple unchanged. + + .. versionadded:: 3.7 + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + Standard Interpreter Types -------------------------- diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 1e93ef4594a9..b4a0dbf95ec0 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1857,11 +1857,27 @@ passed through to all metaclass operations described below. When a class definition is executed, the following steps occur: +* MRO entries are resolved * the appropriate metaclass is determined * the class namespace is prepared * the class body is executed * the class object is created + +Resolving MRO entries +^^^^^^^^^^^^^^^^^^^^^ + +If a base that appears in class definition is not an instance of :class:`type`, +then an ``__mro_entries__`` method is searched on it. If found, it is called +with the original bases tuple. This method must return a tuple of classes that +will be used instead of this base. The tuple may be empty, in such case +the original base is ignored. + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + + Determining the appropriate metaclass ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. index:: @@ -2061,6 +2077,27 @@ case the instance is itself a class. module) to the language. +Emulating generic types +----------------------- + +One can implement the generic class syntax as specified by :pep:`484` +(for example ``List[int]``) by defining a special method + +.. classmethod:: object.__class_getitem__(cls, key) + + Return an object representing the specialization of a generic class + by type arguments found in *key*. + +This method is looked up on the class object itself, and when defined in +the class body, this method is implicitly a class method. Note, this +mechanism is primarily reserved for use with static type hints, other usage +is discouraged. + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + + .. _callable-types: Emulating callable objects diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 408fed4572fa..cc762736a0c7 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -356,6 +356,25 @@ with the correct context in async/await code. PEP written and implemented by Yury Selivanov +PEP 560: Core support for typing module and generic types +--------------------------------------------------------- + +Initially :pep:`484` was designed in such way that it would not introduce *any* +changes to the core CPython interpreter. Now type hints and the :mod:`typing` +module are extensively used by the community, so this restriction is removed. +The PEP introduces two special methods :meth:`__class_getitem__` and +``__mro_entries__``, these methods are now used by most classes and special +constructs in :mod:`typing`. As a result, the speed of various operations +with types increased up to 7 times, the generic types can be used without +metaclass conflicts, and several long standing bugs in :mod:`typing` module are +fixed. + +.. seealso:: + + :pep:`560` -- Core support for typing module and generic types + PEP written and implemented by Ivan Levkivskyi + + New Development Mode: -X dev ---------------------------- From webhook-mailer at python.org Tue May 8 14:52:45 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 08 May 2018 18:52:45 -0000 Subject: [Python-checkins] bpo-32717: Document PEP 560 (GH-6726) Message-ID: https://github.com/python/cpython/commit/101d0d585f99a3b8c8d070b9d4dea15fa3daff62 commit: 101d0d585f99a3b8c8d070b9d4dea15fa3daff62 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T11:52:36-07:00 summary: bpo-32717: Document PEP 560 (GH-6726) (cherry picked from commit bd5f96581bf23f6d05fc106996428a8043b6b084) Co-authored-by: Ivan Levkivskyi files: M Doc/library/types.rst M Doc/reference/datamodel.rst M Doc/whatsnew/3.7.rst diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 67cd4d702ad4..e17070022cd2 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -59,7 +59,7 @@ Dynamic Type Creation The default value for the ``namespace`` element of the returned tuple has changed. Now an insertion-order-preserving mapping is - used when the metaclass does not have a ``__prepare__`` method, + used when the metaclass does not have a ``__prepare__`` method. .. seealso:: @@ -69,6 +69,23 @@ Dynamic Type Creation :pep:`3115` - Metaclasses in Python 3000 Introduced the ``__prepare__`` namespace hook +.. function:: resolve_bases(bases) + + Resolve MRO entries dynamically as specified by :pep:`560`. + + This function looks for items in *bases* that are not instances of + :class:`type`, and returns a tuple where each such object that has + an ``__mro_entries__`` method is replaced with an unpacked result of + calling this method. If a *bases* item is an instance of :class:`type`, + or it doesn't have an ``__mro_entries__`` method, then it is included in + the return tuple unchanged. + + .. versionadded:: 3.7 + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + Standard Interpreter Types -------------------------- diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 1e93ef4594a9..b4a0dbf95ec0 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1857,11 +1857,27 @@ passed through to all metaclass operations described below. When a class definition is executed, the following steps occur: +* MRO entries are resolved * the appropriate metaclass is determined * the class namespace is prepared * the class body is executed * the class object is created + +Resolving MRO entries +^^^^^^^^^^^^^^^^^^^^^ + +If a base that appears in class definition is not an instance of :class:`type`, +then an ``__mro_entries__`` method is searched on it. If found, it is called +with the original bases tuple. This method must return a tuple of classes that +will be used instead of this base. The tuple may be empty, in such case +the original base is ignored. + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + + Determining the appropriate metaclass ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. index:: @@ -2061,6 +2077,27 @@ case the instance is itself a class. module) to the language. +Emulating generic types +----------------------- + +One can implement the generic class syntax as specified by :pep:`484` +(for example ``List[int]``) by defining a special method + +.. classmethod:: object.__class_getitem__(cls, key) + + Return an object representing the specialization of a generic class + by type arguments found in *key*. + +This method is looked up on the class object itself, and when defined in +the class body, this method is implicitly a class method. Note, this +mechanism is primarily reserved for use with static type hints, other usage +is discouraged. + +.. seealso:: + + :pep:`560` - Core support for typing module and generic types + + .. _callable-types: Emulating callable objects diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index afa0bc2b6071..8425731b842c 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -356,6 +356,25 @@ with the correct context in async/await code. PEP written and implemented by Yury Selivanov +PEP 560: Core support for typing module and generic types +--------------------------------------------------------- + +Initially :pep:`484` was designed in such way that it would not introduce *any* +changes to the core CPython interpreter. Now type hints and the :mod:`typing` +module are extensively used by the community, so this restriction is removed. +The PEP introduces two special methods :meth:`__class_getitem__` and +``__mro_entries__``, these methods are now used by most classes and special +constructs in :mod:`typing`. As a result, the speed of various operations +with types increased up to 7 times, the generic types can be used without +metaclass conflicts, and several long standing bugs in :mod:`typing` module are +fixed. + +.. seealso:: + + :pep:`560` -- Core support for typing module and generic types + PEP written and implemented by Ivan Levkivskyi + + New Development Mode: -X dev ---------------------------- From webhook-mailer at python.org Tue May 8 18:00:29 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 08 May 2018 22:00:29 -0000 Subject: [Python-checkins] Fix typo in __mul__ and __rmul__ docstring (GH-6674) Message-ID: https://github.com/python/cpython/commit/0904f766e116c269675317e11368a4d29eef0bc6 commit: 0904f766e116c269675317e11368a4d29eef0bc6 branch: master author: Grant Jenks committer: Serhiy Storchaka date: 2018-05-09T01:00:19+03:00 summary: Fix typo in __mul__ and __rmul__ docstring (GH-6674) files: M Objects/typeobject.c diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1dd534866b4d..a7a9d7bf9fc3 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6938,9 +6938,9 @@ static slotdef slotdefs[] = { SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, - "__mul__($self, value, /)\n--\n\nReturn self*value.n"), + "__mul__($self, value, /)\n--\n\nReturn self*value."), SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, - "__rmul__($self, value, /)\n--\n\nReturn self*value."), + "__rmul__($self, value, /)\n--\n\nReturn value*self."), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, From webhook-mailer at python.org Tue May 8 21:23:50 2018 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Wed, 09 May 2018 01:23:50 -0000 Subject: [Python-checkins] bpo-28556: Minor fixes for typing module (GH-6732) Message-ID: https://github.com/python/cpython/commit/43d12a6bd82bd09ac189069fe1eb40cdbc10a58c commit: 43d12a6bd82bd09ac189069fe1eb40cdbc10a58c branch: master author: Ivan Levkivskyi committer: GitHub date: 2018-05-09T02:23:46+01:00 summary: bpo-28556: Minor fixes for typing module (GH-6732) This also fixes https://bugs.python.org/issue33420 files: A Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 390fe60fcc10..46bab5eba6db 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1324,6 +1324,72 @@ class D(C): with self.assertRaises(Exception): D[T] + def test_new_with_args(self): + + class A(Generic[T]): + pass + + class B: + def __new__(cls, arg): + # call object + obj = super().__new__(cls) + obj.arg = arg + return obj + + # mro: C, A, Generic, B, object + class C(A, B): + pass + + c = C('foo') + self.assertEqual(c.arg, 'foo') + + def test_new_with_args2(self): + + class A: + def __init__(self, arg): + self.from_a = arg + # call object + super().__init__() + + # mro: C, Generic, A, object + class C(Generic[T], A): + def __init__(self, arg): + self.from_c = arg + # call Generic + super().__init__(arg) + + c = C('foo') + self.assertEqual(c.from_a, 'foo') + self.assertEqual(c.from_c, 'foo') + + def test_new_no_args(self): + + class A(Generic[T]): + pass + + class B: + def __new__(cls): + # call object + obj = super().__new__(cls) + obj.from_b = 'b' + return obj + + # mro: C, A, Generic, B, object + class C(A, B): + def __init__(self, arg): + self.arg = arg + + def __new__(cls, arg): + # call A + obj = super().__new__(cls) + obj.from_c = 'c' + return obj + + c = C('foo') + self.assertEqual(c.arg, 'foo') + self.assertEqual(c.from_b, 'b') + self.assertEqual(c.from_c, 'c') + class ClassVarTests(BaseTestCase): @@ -1737,6 +1803,8 @@ def test_get_type_hints_classes(self): self.assertEqual(gth(HasForeignBaseClass), {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 'some_b': mod_generics_cache.B}) + self.assertEqual(gth(XRepr.__new__), + {'x': int, 'y': int}) self.assertEqual(gth(mod_generics_cache.B), {'my_inner_a1': mod_generics_cache.B.A, 'my_inner_a2': mod_generics_cache.B.A, diff --git a/Lib/typing.py b/Lib/typing.py index 83296073b914..89b73db15837 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -607,7 +607,8 @@ def __reduce__(self): # * __parameters__ is a tuple of unique free type parameters of a generic # type, for example, Dict[T, T].__parameters__ == (T,); # * __origin__ keeps a reference to a type that was subscripted, -# e.g., Union[T, int].__origin__ == Union; +# e.g., Union[T, int].__origin__ == Union, or the non-generic version of +# the type. # * __args__ is a tuple of all arguments used in subscripting, # e.g., Dict[T, int].__args__ == (T, int). @@ -835,7 +836,11 @@ def __new__(cls, *args, **kwds): if cls is Generic: raise TypeError("Type Generic cannot be instantiated; " "it can be used only as a base class") - return super().__new__(cls) + if super().__new__ is object.__new__: + obj = super().__new__(cls) + else: + obj = super().__new__(cls, *args, **kwds) + return obj @_tp_cache def __class_getitem__(cls, params): @@ -1385,6 +1390,7 @@ def __new__(cls, typename, bases, ns): "follow default field(s) {default_names}" .format(field_name=field_name, default_names=', '.join(defaults_dict.keys()))) + nm_tpl.__new__.__annotations__ = collections.OrderedDict(types) nm_tpl.__new__.__defaults__ = tuple(defaults) nm_tpl._field_defaults = defaults_dict # update from user namespace without overriding special namedtuple attributes diff --git a/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst new file mode 100644 index 000000000000..8ed4658211fb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst @@ -0,0 +1,3 @@ +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius ?arka and Chad Dombrova. From lp_benchmark_robot at intel.com Tue May 8 21:29:47 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 8 May 2018 18:29:47 -0700 Subject: [Python-checkins] [1 up, 64 flat] Results for Python (master branch) 2018-05-08 Message-ID: Results for project python/master, build date: 2018-05-08 03:03:02-07:00. - commit: d54cfb1 - previous commit: a3f19c3 - revision date: 2018-05-08 07:48:50+03:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.572% | +1.306% | +9.703% | +6.466% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.134% | +0.658% | +24.088% | +13.709% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.925% | +0.904% | +25.478% | +13.045% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.447% | -1.878% | +22.422% | +12.602% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.856% | +1.190% | +11.179% | +14.647% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 2.541% | -0.364% | +12.109% | +11.074% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.538% | -0.528% | +8.925% | +8.628% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.542% | +1.486% | -0.069% | +7.510% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 3.727% | +2.067% | +13.041% | +15.531% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 4.512% | -1.446% | +20.652% | +13.956% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.379% | -0.345% | +5.482% | +7.297% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.661% | +0.086% | +7.163% | +5.138% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.073% | -0.265% | +2.460% | +7.338% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.157% | +0.666% | +14.252% | +10.454% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 2.269% | -0.887% | +11.253% | +10.404% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 5.753% | +1.001% | +5.888% | +10.383% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.424% | +0.871% | +11.883% | +11.227% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 2.806% | +1.022% | +12.304% | +9.043% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 2.108% | +1.451% | +3.342% | +8.452% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 4.237% | +1.555% | -3.990% | +16.036% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.493% | -2.009% | +16.907% | +13.928% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.731% | -0.585% | +47.480% | +12.809% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.577% | -0.967% | +12.481% | +13.533% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.521% | +1.859% | +17.286% | +13.380% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 6.268% | -5.467% | +0.335% | +18.394% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 0.642% | +0.427% | +4.640% | +5.813% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.607% | +1.559% | +0.831% | +0.209% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 0.628% | -0.334% | +5.738% | +8.103% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.322% | +1.993% | +0.514% | +11.710% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.211% | -0.289% | -0.444% | +22.818% | +-----+------------------------+--------+------------+------------+------------+ | :-) | pickle_dict| 0.599% | +3.311% | +7.416% | +13.907% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.923% | +1.047% | +6.994% | +15.660% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 5.292% | +1.307% | +11.515% | +11.301% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.137% | -0.192% | +0.063% | +10.404% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.125% | +0.472% | +18.840% | +5.200% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.088% | +0.352% | +5.792% | +5.522% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 1.378% | -0.472% | +9.690% | +14.068% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.050% | +2.235% | +6.149% | +7.947% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.505% | +1.211% | -0.753% | +12.060% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 1.348% | -2.164% | -4.495% | +5.618% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 2.527% | +1.942% | +5.589% | +6.259% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.528% | +0.046% | +9.601% | +15.361% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.520% | -0.744% | -2.242% | +3.623% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 4.006% | +0.948% | +22.625% | +12.292% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.126% | +0.522% | +5.427% | +2.119% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 1.300% | +0.649% | +15.155% | +9.328% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.601% | +2.064% | -2.426% | -2.415% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.698% | +0.709% | +4.124% | +4.435% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.824% | +1.310% | +7.733% | +4.686% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.318% | +0.479% | +8.164% | +4.057% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 5.665% | +1.614% | +0.784% | +8.649% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 3.431% | +0.484% | +17.530% | +7.459% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 1.416% | +0.426% | +18.407% | +6.004% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 3.992% | +0.026% | +18.956% | +8.018% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.067% | -0.183% | +16.198% | +9.543% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 5.050% | +1.452% | +19.298% | +10.885% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.998% | +0.506% | +7.290% | +5.997% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 0.950% | +0.058% | +2.633% | +2.475% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 3.948% | +1.675% | +10.153% | +19.424% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 7.442% | -2.649% | -4.504% | +19.127% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 1.407% | +1.298% | +7.510% | +7.338% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.497% | -0.231% | +2.412% | +12.383% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.776% | +1.247% | +3.787% | +8.404% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 2.789% | +2.127% | -6.790% | +10.351% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.040% | -0.040% | +4.341% | +11.299% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/1-up-64-flat-results-for-python-master-branch-2018-05-08 Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From webhook-mailer at python.org Tue May 8 21:44:19 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 01:44:19 -0000 Subject: [Python-checkins] bpo-28556: Minor fixes for typing module (GH-6732) Message-ID: https://github.com/python/cpython/commit/3c28a6387b48bad3fcae47906bc166d02a2f8ed2 commit: 3c28a6387b48bad3fcae47906bc166d02a2f8ed2 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T18:44:09-07:00 summary: bpo-28556: Minor fixes for typing module (GH-6732) This also fixes https://bugs.python.org/issue33420 (cherry picked from commit 43d12a6bd82bd09ac189069fe1eb40cdbc10a58c) Co-authored-by: Ivan Levkivskyi files: A Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 390fe60fcc10..46bab5eba6db 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1324,6 +1324,72 @@ class D(C): with self.assertRaises(Exception): D[T] + def test_new_with_args(self): + + class A(Generic[T]): + pass + + class B: + def __new__(cls, arg): + # call object + obj = super().__new__(cls) + obj.arg = arg + return obj + + # mro: C, A, Generic, B, object + class C(A, B): + pass + + c = C('foo') + self.assertEqual(c.arg, 'foo') + + def test_new_with_args2(self): + + class A: + def __init__(self, arg): + self.from_a = arg + # call object + super().__init__() + + # mro: C, Generic, A, object + class C(Generic[T], A): + def __init__(self, arg): + self.from_c = arg + # call Generic + super().__init__(arg) + + c = C('foo') + self.assertEqual(c.from_a, 'foo') + self.assertEqual(c.from_c, 'foo') + + def test_new_no_args(self): + + class A(Generic[T]): + pass + + class B: + def __new__(cls): + # call object + obj = super().__new__(cls) + obj.from_b = 'b' + return obj + + # mro: C, A, Generic, B, object + class C(A, B): + def __init__(self, arg): + self.arg = arg + + def __new__(cls, arg): + # call A + obj = super().__new__(cls) + obj.from_c = 'c' + return obj + + c = C('foo') + self.assertEqual(c.arg, 'foo') + self.assertEqual(c.from_b, 'b') + self.assertEqual(c.from_c, 'c') + class ClassVarTests(BaseTestCase): @@ -1737,6 +1803,8 @@ def test_get_type_hints_classes(self): self.assertEqual(gth(HasForeignBaseClass), {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 'some_b': mod_generics_cache.B}) + self.assertEqual(gth(XRepr.__new__), + {'x': int, 'y': int}) self.assertEqual(gth(mod_generics_cache.B), {'my_inner_a1': mod_generics_cache.B.A, 'my_inner_a2': mod_generics_cache.B.A, diff --git a/Lib/typing.py b/Lib/typing.py index 83296073b914..89b73db15837 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -607,7 +607,8 @@ def __reduce__(self): # * __parameters__ is a tuple of unique free type parameters of a generic # type, for example, Dict[T, T].__parameters__ == (T,); # * __origin__ keeps a reference to a type that was subscripted, -# e.g., Union[T, int].__origin__ == Union; +# e.g., Union[T, int].__origin__ == Union, or the non-generic version of +# the type. # * __args__ is a tuple of all arguments used in subscripting, # e.g., Dict[T, int].__args__ == (T, int). @@ -835,7 +836,11 @@ def __new__(cls, *args, **kwds): if cls is Generic: raise TypeError("Type Generic cannot be instantiated; " "it can be used only as a base class") - return super().__new__(cls) + if super().__new__ is object.__new__: + obj = super().__new__(cls) + else: + obj = super().__new__(cls, *args, **kwds) + return obj @_tp_cache def __class_getitem__(cls, params): @@ -1385,6 +1390,7 @@ def __new__(cls, typename, bases, ns): "follow default field(s) {default_names}" .format(field_name=field_name, default_names=', '.join(defaults_dict.keys()))) + nm_tpl.__new__.__annotations__ = collections.OrderedDict(types) nm_tpl.__new__.__defaults__ = tuple(defaults) nm_tpl._field_defaults = defaults_dict # update from user namespace without overriding special namedtuple attributes diff --git a/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst new file mode 100644 index 000000000000..8ed4658211fb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-08-16-43-42.bpo-28556._xr5mp.rst @@ -0,0 +1,3 @@ +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius ?arka and Chad Dombrova. From webhook-mailer at python.org Wed May 9 00:16:38 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 09 May 2018 04:16:38 -0000 Subject: [Python-checkins] closes bpo-33445: fail properly in test_cprofile() (GH-6727) Message-ID: https://github.com/python/cpython/commit/ac9240b9be31d073d1b2e50ce53481ff0fc9ed23 commit: ac9240b9be31d073d1b2e50ce53481ff0fc9ed23 branch: master author: jdemeyer committer: Benjamin Peterson date: 2018-05-08T21:16:35-07:00 summary: closes bpo-33445: fail properly in test_cprofile() (GH-6727) files: M Lib/test/test_profile.py diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index 1fc3c4266965..a9982663175a 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -51,13 +51,18 @@ def test_cprofile(self): results = self.do_profiling() expected = self.get_expected_output() self.assertEqual(results[0], 1000) + fail = [] for i, method in enumerate(self.methodnames): - if results[i+1] != expected[method]: - print("Stats.%s output for %s doesn't fit expectation!" % - (method, self.profilerclass.__name__)) - print('\n'.join(unified_diff( - results[i+1].split('\n'), - expected[method].split('\n')))) + a = expected[method] + b = results[i+1] + if a != b: + fail.append(f"\nStats.{method} output for " + f"{self.profilerclass.__name__} " + "does not fit expectation:") + fail.extend(unified_diff(a.split('\n'), b.split('\n'), + lineterm="")) + if fail: + self.fail("\n".join(fail)) def test_calling_conventions(self): # Issue #5330: profile and cProfile wouldn't report C functions called From webhook-mailer at python.org Wed May 9 00:38:03 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 04:38:03 -0000 Subject: [Python-checkins] closes bpo-33445: fail properly in test_cprofile() (GH-6727) Message-ID: https://github.com/python/cpython/commit/263523ae217e1af580628b4fe0609194823a51aa commit: 263523ae217e1af580628b4fe0609194823a51aa branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T21:38:00-07:00 summary: closes bpo-33445: fail properly in test_cprofile() (GH-6727) (cherry picked from commit ac9240b9be31d073d1b2e50ce53481ff0fc9ed23) Co-authored-by: jdemeyer files: M Lib/test/test_profile.py diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index 1fc3c4266965..a9982663175a 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -51,13 +51,18 @@ def test_cprofile(self): results = self.do_profiling() expected = self.get_expected_output() self.assertEqual(results[0], 1000) + fail = [] for i, method in enumerate(self.methodnames): - if results[i+1] != expected[method]: - print("Stats.%s output for %s doesn't fit expectation!" % - (method, self.profilerclass.__name__)) - print('\n'.join(unified_diff( - results[i+1].split('\n'), - expected[method].split('\n')))) + a = expected[method] + b = results[i+1] + if a != b: + fail.append(f"\nStats.{method} output for " + f"{self.profilerclass.__name__} " + "does not fit expectation:") + fail.extend(unified_diff(a.split('\n'), b.split('\n'), + lineterm="")) + if fail: + self.fail("\n".join(fail)) def test_calling_conventions(self): # Issue #5330: profile and cProfile wouldn't report C functions called From webhook-mailer at python.org Wed May 9 00:59:57 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 04:59:57 -0000 Subject: [Python-checkins] closes bpo-33445: fail properly in test_cprofile() (GH-6727) Message-ID: https://github.com/python/cpython/commit/c925108b991b9c5f0402feb0e7f725ee3ac7da11 commit: c925108b991b9c5f0402feb0e7f725ee3ac7da11 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T21:59:50-07:00 summary: closes bpo-33445: fail properly in test_cprofile() (GH-6727) (cherry picked from commit ac9240b9be31d073d1b2e50ce53481ff0fc9ed23) Co-authored-by: jdemeyer files: M Lib/test/test_profile.py diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index 1fc3c4266965..a9982663175a 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -51,13 +51,18 @@ def test_cprofile(self): results = self.do_profiling() expected = self.get_expected_output() self.assertEqual(results[0], 1000) + fail = [] for i, method in enumerate(self.methodnames): - if results[i+1] != expected[method]: - print("Stats.%s output for %s doesn't fit expectation!" % - (method, self.profilerclass.__name__)) - print('\n'.join(unified_diff( - results[i+1].split('\n'), - expected[method].split('\n')))) + a = expected[method] + b = results[i+1] + if a != b: + fail.append(f"\nStats.{method} output for " + f"{self.profilerclass.__name__} " + "does not fit expectation:") + fail.extend(unified_diff(a.split('\n'), b.split('\n'), + lineterm="")) + if fail: + self.fail("\n".join(fail)) def test_calling_conventions(self): # Issue #5330: profile and cProfile wouldn't report C functions called From webhook-mailer at python.org Wed May 9 01:49:57 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 05:49:57 -0000 Subject: [Python-checkins] Fix typo in __mul__ and __rmul__ docstring (GH-6674) Message-ID: https://github.com/python/cpython/commit/a0ff51964f85f446e1eb13c59297b17bd2f435c6 commit: a0ff51964f85f446e1eb13c59297b17bd2f435c6 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T22:49:47-07:00 summary: Fix typo in __mul__ and __rmul__ docstring (GH-6674) (cherry picked from commit 0904f766e116c269675317e11368a4d29eef0bc6) Co-authored-by: Grant Jenks files: M Objects/typeobject.c diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1dd534866b4d..a7a9d7bf9fc3 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6938,9 +6938,9 @@ static slotdef slotdefs[] = { SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, - "__mul__($self, value, /)\n--\n\nReturn self*value.n"), + "__mul__($self, value, /)\n--\n\nReturn self*value."), SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, - "__rmul__($self, value, /)\n--\n\nReturn self*value."), + "__rmul__($self, value, /)\n--\n\nReturn value*self."), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, From webhook-mailer at python.org Wed May 9 01:50:00 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 05:50:00 -0000 Subject: [Python-checkins] Fix typo in __mul__ and __rmul__ docstring (GH-6674) Message-ID: https://github.com/python/cpython/commit/7f4f94d474d16b5817df2b05c9678436c08f5efa commit: 7f4f94d474d16b5817df2b05c9678436c08f5efa branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-08T22:49:57-07:00 summary: Fix typo in __mul__ and __rmul__ docstring (GH-6674) (cherry picked from commit 0904f766e116c269675317e11368a4d29eef0bc6) Co-authored-by: Grant Jenks files: M Objects/typeobject.c diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e843204f10a6..69b1878fd8f2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6740,9 +6740,9 @@ static slotdef slotdefs[] = { SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, - "__mul__($self, value, /)\n--\n\nReturn self*value.n"), + "__mul__($self, value, /)\n--\n\nReturn self*value."), SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, - "__rmul__($self, value, /)\n--\n\nReturn self*value."), + "__rmul__($self, value, /)\n--\n\nReturn value*self."), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, From webhook-mailer at python.org Wed May 9 03:25:29 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 09 May 2018 07:25:29 -0000 Subject: [Python-checkins] Fix superfluous if in documentation. (GH-6728) Message-ID: https://github.com/python/cpython/commit/b3c369861b22268dac003eb995951726c972e5ee commit: b3c369861b22268dac003eb995951726c972e5ee branch: master author: Julien Palard committer: Serhiy Storchaka date: 2018-05-09T10:25:22+03:00 summary: Fix superfluous if in documentation. (GH-6728) files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index c3b638572338..2d15001bffa7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -734,7 +734,7 @@ are always available. They are listed here in alphabetical order. :meth:`x.__int__() `. If *x* defines :meth:`x.__trunc__() ` but not :meth:`x.__int__() `, then return - if :meth:`x.__trunc__() `. For floating point numbers, + :meth:`x.__trunc__() `. For floating point numbers, this truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, From webhook-mailer at python.org Wed May 9 04:10:05 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 08:10:05 -0000 Subject: [Python-checkins] Fix superfluous if in documentation. (GH-6728) Message-ID: https://github.com/python/cpython/commit/c587235f210b18d6f7f31e746fa5e5e259320c83 commit: c587235f210b18d6f7f31e746fa5e5e259320c83 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-09T01:10:02-07:00 summary: Fix superfluous if in documentation. (GH-6728) (cherry picked from commit b3c369861b22268dac003eb995951726c972e5ee) Co-authored-by: Julien Palard files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index c3b638572338..2d15001bffa7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -734,7 +734,7 @@ are always available. They are listed here in alphabetical order. :meth:`x.__int__() `. If *x* defines :meth:`x.__trunc__() ` but not :meth:`x.__int__() `, then return - if :meth:`x.__trunc__() `. For floating point numbers, + :meth:`x.__trunc__() `. For floating point numbers, this truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, From webhook-mailer at python.org Wed May 9 04:10:15 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 08:10:15 -0000 Subject: [Python-checkins] Fix superfluous if in documentation. (GH-6728) Message-ID: https://github.com/python/cpython/commit/6079b607d3fad319f84f0a0174eece44ee6a69b7 commit: 6079b607d3fad319f84f0a0174eece44ee6a69b7 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-09T01:10:12-07:00 summary: Fix superfluous if in documentation. (GH-6728) (cherry picked from commit b3c369861b22268dac003eb995951726c972e5ee) Co-authored-by: Julien Palard files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 9cb6b0e1b5ca..56c1377d1734 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -720,7 +720,7 @@ are always available. They are listed here in alphabetical order. :meth:`x.__int__() `. If *x* defines :meth:`x.__trunc__() ` but not :meth:`x.__int__() `, then return - if :meth:`x.__trunc__() `. For floating point numbers, + :meth:`x.__trunc__() `. For floating point numbers, this truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, From webhook-mailer at python.org Wed May 9 04:10:58 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 09 May 2018 08:10:58 -0000 Subject: [Python-checkins] bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) Message-ID: https://github.com/python/cpython/commit/ddb6215a55b0218b621d5cb755e9dfac8dab231a commit: ddb6215a55b0218b621d5cb755e9dfac8dab231a branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-09T11:10:55+03:00 summary: bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 3d57020dabe8..6cdc6c8419af 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -148,14 +148,14 @@ where *encoding* is one of the valid :mod:`codecs` supported by Python. For example, to declare that Windows-1252 encoding is to be used, the first line of your source code file should be:: - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- One exception to the *first line* rule is when the source code starts with a :ref:`UNIX "shebang" line `. In this case, the encoding declaration should be added as the second line of the file. For example:: #!/usr/bin/env python3 - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- .. rubric:: Footnotes From webhook-mailer at python.org Wed May 9 04:54:42 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 08:54:42 -0000 Subject: [Python-checkins] bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) Message-ID: https://github.com/python/cpython/commit/8ffff34ea12ca6478d73a337ce52f33660f6f174 commit: 8ffff34ea12ca6478d73a337ce52f33660f6f174 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-09T01:54:38-07:00 summary: bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) (cherry picked from commit ddb6215a55b0218b621d5cb755e9dfac8dab231a) Co-authored-by: Serhiy Storchaka files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index bf7ce7764171..a2766e8810a5 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -148,14 +148,14 @@ where *encoding* is one of the valid :mod:`codecs` supported by Python. For example, to declare that Windows-1252 encoding is to be used, the first line of your source code file should be:: - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- One exception to the *first line* rule is when the source code starts with a :ref:`UNIX "shebang" line `. In this case, the encoding declaration should be added as the second line of the file. For example:: #!/usr/bin/env python3 - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- .. rubric:: Footnotes From webhook-mailer at python.org Wed May 9 05:00:24 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 09:00:24 -0000 Subject: [Python-checkins] bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) Message-ID: https://github.com/python/cpython/commit/fa40fc0593012893e447875632e9ed3df277561f commit: fa40fc0593012893e447875632e9ed3df277561f branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-09T02:00:13-07:00 summary: bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738) (cherry picked from commit ddb6215a55b0218b621d5cb755e9dfac8dab231a) Co-authored-by: Serhiy Storchaka files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 3bd100d46a12..d04f7cefa0df 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -148,14 +148,14 @@ where *encoding* is one of the valid :mod:`codecs` supported by Python. For example, to declare that Windows-1252 encoding is to be used, the first line of your source code file should be:: - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- One exception to the *first line* rule is when the source code starts with a :ref:`UNIX "shebang" line `. In this case, the encoding declaration should be added as the second line of the file. For example:: #!/usr/bin/env python3 - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- .. rubric:: Footnotes From solipsis at pitrou.net Wed May 9 05:12:30 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 09 May 2018 09:12:30 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=14 Message-ID: <20180509091230.1.4D596DF0F1AD3FF4@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_collections leaked [0, 7, 0] memory blocks, sum=7 test_functools leaked [0, 3, 1] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflog9MNS5c', '--timeout', '7200'] From webhook-mailer at python.org Wed May 9 05:35:38 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 09 May 2018 09:35:38 -0000 Subject: [Python-checkins] [2.7] bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738). (GH-6744) Message-ID: https://github.com/python/cpython/commit/d7e783b17feaedbe0f5b30467cb7f43cefadf904 commit: d7e783b17feaedbe0f5b30467cb7f43cefadf904 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-05-09T12:35:28+03:00 summary: [2.7] bpo-13525: Fix incorrect encoding name in the tutorial example. (GH-6738). (GH-6744) (cherry picked from commit ddb6215a55b0218b621d5cb755e9dfac8dab231a) files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 6c8609fabaeb..b727be00ab8a 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -137,12 +137,12 @@ where *encoding* is one of the valid :mod:`codecs` supported by Python. For example, to declare that Windows-1252 encoding is to be used, the first line of your source code file should be:: - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- One exception to the *first line* rule is when the source code starts with a :ref:`UNIX "shebang" line `. In this case, the encoding declaration should be added as the second line of the file. For example:: #!/usr/bin/env python - # -*- coding: cp-1252 -*- + # -*- coding: cp1252 -*- From webhook-mailer at python.org Wed May 9 05:39:35 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 09 May 2018 09:39:35 -0000 Subject: [Python-checkins] bpo-33311: Do not display parameters displayed in parentheses for module call. (GH-6677) Message-ID: https://github.com/python/cpython/commit/8cf4b34b3665b8bb39ea7111e6b5c3410899d3e4 commit: 8cf4b34b3665b8bb39ea7111e6b5c3410899d3e4 branch: master author: sblondon committer: Serhiy Storchaka date: 2018-05-09T12:39:32+03:00 summary: bpo-33311: Do not display parameters displayed in parentheses for module call. (GH-6677) files: A Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst M Lib/cgitb.py diff --git a/Lib/cgitb.py b/Lib/cgitb.py index 0f5f32c0fade..4f81271be3ca 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -124,8 +124,9 @@ def html(einfo, context=5): args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': - call = 'in ' + strong(pydoc.html.escape(func)) + \ - inspect.formatargvalues(args, varargs, varkw, locals, + call = 'in ' + strong(pydoc.html.escape(func)) + if func != "": + call += inspect.formatargvalues(args, varargs, varkw, locals, formatvalue=lambda value: '=' + pydoc.html.repr(value)) highlight = {} @@ -207,8 +208,9 @@ def text(einfo, context=5): args, varargs, varkw, locals = inspect.getargvalues(frame) call = '' if func != '?': - call = 'in ' + func + \ - inspect.formatargvalues(args, varargs, varkw, locals, + call = 'in ' + func + if func != "": + call += inspect.formatargvalues(args, varargs, varkw, locals, formatvalue=lambda value: '=' + pydoc.text.repr(value)) highlight = {} diff --git a/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst b/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst new file mode 100644 index 000000000000..d0218de373ca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-01-22-33-14.bpo-33311.8YPB-k.rst @@ -0,0 +1,2 @@ +Text and html output generated by cgitb does not display parentheses if the +current call is done directly in the module. Patch by St?phane Blondon. From webhook-mailer at python.org Wed May 9 06:14:44 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 09 May 2018 10:14:44 -0000 Subject: [Python-checkins] bpo-33038: Fix gzip.GzipFile for file objects with a non-string name attribute. (GH-6095) Message-ID: https://github.com/python/cpython/commit/afe5f633e49e0e873d42088ae56819609c803ba0 commit: afe5f633e49e0e873d42088ae56819609c803ba0 branch: 2.7 author: Bo Bayles committer: Serhiy Storchaka date: 2018-05-09T13:14:40+03:00 summary: bpo-33038: Fix gzip.GzipFile for file objects with a non-string name attribute. (GH-6095) files: A Misc/NEWS.d/next/Library/2018-03-10-20-14-36.bpo-33038.yA6CP5.rst M Lib/gzip.py M Lib/test/test_gzip.py M Misc/ACKS diff --git a/Lib/gzip.py b/Lib/gzip.py index 07c6db493b0b..76ace394f482 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -95,9 +95,8 @@ def __init__(self, filename=None, mode=None, if filename is None: # Issue #13781: os.fdopen() creates a fileobj with a bogus name # attribute. Avoid saving this in the gzip header's filename field. - if hasattr(fileobj, 'name') and fileobj.name != '': - filename = fileobj.name - else: + filename = getattr(fileobj, 'name', '') + if not isinstance(filename, basestring) or filename == '': filename = '' if mode is None: if hasattr(fileobj, 'mode'): mode = fileobj.mode diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 902d93fe043f..cdb1af5c3d13 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -6,6 +6,7 @@ import os import io import struct +import tempfile gzip = test_support.import_module('gzip') data1 = """ int length=DEFAULTALLOC, err = Z_OK; @@ -331,6 +332,12 @@ def test_fileobj_from_fdopen(self): with gzip.GzipFile(fileobj=f, mode="w") as g: self.assertEqual(g.name, "") + def test_fileobj_from_io_open(self): + fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT) + with io.open(fd, "wb") as f: + with gzip.GzipFile(fileobj=f, mode="w") as g: + self.assertEqual(g.name, "") + def test_fileobj_mode(self): gzip.GzipFile(self.filename, "wb").close() with open(self.filename, "r+b") as f: @@ -359,6 +366,14 @@ def test_read_with_extra(self): with gzip.GzipFile(fileobj=io.BytesIO(gzdata)) as f: self.assertEqual(f.read(), b'Test') + def test_fileobj_without_name(self): + # Issue #33038: GzipFile should not assume that file objects that have + # a .name attribute use a non-None value. + with tempfile.SpooledTemporaryFile() as f: + with gzip.GzipFile(fileobj=f, mode='wb') as archive: + archive.write(b'data') + self.assertEqual(archive.name, '') + def test_main(verbose=None): test_support.run_unittest(TestGzip) diff --git a/Misc/ACKS b/Misc/ACKS index 580b0c5bf76d..458f31e6a6b7 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -94,6 +94,7 @@ Michael R Bax Anthony Baxter Mike Bayer Samuel L. Bayer +Bo Bayles Donald Beaudry David Beazley Carlo Beccarini diff --git a/Misc/NEWS.d/next/Library/2018-03-10-20-14-36.bpo-33038.yA6CP5.rst b/Misc/NEWS.d/next/Library/2018-03-10-20-14-36.bpo-33038.yA6CP5.rst new file mode 100644 index 000000000000..22d394b85ab7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-10-20-14-36.bpo-33038.yA6CP5.rst @@ -0,0 +1,2 @@ +gzip.GzipFile no longer produces an AttributeError exception when used with +a file object with a non-string name attribute. Patch by Bo Bayles. From webhook-mailer at python.org Wed May 9 17:39:00 2018 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 09 May 2018 21:39:00 -0000 Subject: [Python-checkins] bpo-21983: Fix a crash in ctypes.cast() when passed a ctypes structured data type (GH-3859) Message-ID: https://github.com/python/cpython/commit/d518d8bc8d5dac1a1270612f424d33e0e5afc2b5 commit: d518d8bc8d5dac1a1270612f424d33e0e5afc2b5 branch: master author: Oren Milman committer: Steve Dower date: 2018-05-09T14:38:56-07:00 summary: bpo-21983: Fix a crash in ctypes.cast() when passed a ctypes structured data type (GH-3859) files: A Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst M Lib/ctypes/test/test_cast.py M Modules/_ctypes/_ctypes.c diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py index 187d2bde143d..6878f9732826 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/ctypes/test/test_cast.py @@ -82,5 +82,18 @@ def test_wchar_p(self): self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, "hiho") + def test_bad_type_arg(self): + # The type argument must be a ctypes pointer type. + array_type = c_byte * sizeof(c_int) + array = array_type() + self.assertRaises(TypeError, cast, array, None) + self.assertRaises(TypeError, cast, array, array_type) + class Struct(Structure): + _fields_ = [("a", c_int)] + self.assertRaises(TypeError, cast, array, Struct) + class MyUnion(Union): + _fields_ = [("a", c_int)] + self.assertRaises(TypeError, cast, array, MyUnion) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst new file mode 100644 index 000000000000..88a03685073c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst @@ -0,0 +1,2 @@ +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 93e8d8d42330..5bf49acb6c2d 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5319,7 +5319,7 @@ cast_check_pointertype(PyObject *arg) if (PyCFuncPtrTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); - if (dict) { + if (dict != NULL && dict->proto != NULL) { if (PyUnicode_Check(dict->proto) && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) { /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ From webhook-mailer at python.org Wed May 9 18:28:01 2018 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 09 May 2018 22:28:01 -0000 Subject: [Python-checkins] bpo-21983: Fix a crash in ctypes.cast() when passed a ctypes structured data type (GH-3859) Message-ID: https://github.com/python/cpython/commit/8ac158a6dfb86880e22003afe0ff39ec31b0a094 commit: 8ac158a6dfb86880e22003afe0ff39ec31b0a094 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2018-05-09T15:27:59-07:00 summary: bpo-21983: Fix a crash in ctypes.cast() when passed a ctypes structured data type (GH-3859) (cherry picked from commit d518d8bc8d5dac1a1270612f424d33e0e5afc2b5) Co-authored-by: Oren Milman files: A Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst M Lib/ctypes/test/test_cast.py M Modules/_ctypes/_ctypes.c diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py index 187d2bde143d..6878f9732826 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/ctypes/test/test_cast.py @@ -82,5 +82,18 @@ def test_wchar_p(self): self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, "hiho") + def test_bad_type_arg(self): + # The type argument must be a ctypes pointer type. + array_type = c_byte * sizeof(c_int) + array = array_type() + self.assertRaises(TypeError, cast, array, None) + self.assertRaises(TypeError, cast, array, array_type) + class Struct(Structure): + _fields_ = [("a", c_int)] + self.assertRaises(TypeError, cast, array, Struct) + class MyUnion(Union): + _fields_ = [("a", c_int)] + self.assertRaises(TypeError, cast, array, MyUnion) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst new file mode 100644 index 000000000000..88a03685073c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst @@ -0,0 +1,2 @@ +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 258e805870b1..2c0a769d8724 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5327,7 +5327,7 @@ cast_check_pointertype(PyObject *arg) if (PyCFuncPtrTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); - if (dict) { + if (dict != NULL && dict->proto != NULL) { if (PyUnicode_Check(dict->proto) && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) { /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */ From lp_benchmark_robot at intel.com Wed May 9 20:51:49 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 9 May 2018 17:51:49 -0700 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-05-09 Message-ID: <6a734355-2991-4628-9bd8-746498a20897@orsmsx153.amr.corp.intel.com> Results for project python/master, build date: 2018-05-09 03:03:02-07:00. - commit: 8cf4b34 - previous commit: d54cfb1 - revision date: 2018-05-09 12:39:32+03:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.595% | -0.257% | +9.471% | +6.950% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.426% | -0.362% | +23.813% | +9.597% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.677% | +0.379% | +25.761% | +8.461% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.140% | +0.016% | +22.435% | +9.691% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 2.866% | -0.398% | +10.825% | +12.090% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.851% | +0.005% | +12.113% | +9.581% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.811% | +0.253% | +9.156% | +9.968% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.536% | -0.134% | -0.203% | +7.148% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 1.466% | +0.547% | +13.517% | +15.466% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 3.243% | +1.813% | +22.091% | +12.300% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.199% | +0.086% | +5.562% | +5.893% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.820% | -0.054% | +7.113% | +5.258% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.366% | -0.044% | +2.417% | +7.391% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.328% | +0.197% | +14.421% | +9.417% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.693% | -0.101% | +11.164% | +9.817% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 6.421% | -0.894% | +5.047% | +11.766% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.485% | -0.028% | +11.859% | +11.480% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 2.787% | -0.160% | +12.163% | +10.334% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.841% | -0.242% | +3.108% | +8.889% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 7.141% | -1.121% | -5.156% | +17.338% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.760% | +0.373% | +17.216% | +14.227% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.772% | +0.708% | +47.852% | +13.084% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.429% | +0.105% | +12.573% | +14.616% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.579% | -0.167% | +17.148% | +14.133% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 6.939% | +0.074% | +0.409% | +18.709% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 0.654% | -0.082% | +4.561% | +5.973% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.672% | +0.118% | +0.948% | +0.899% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 0.928% | -0.050% | +5.691% | +6.550% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.366% | +0.233% | +0.745% | +10.217% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.270% | -0.538% | -0.984% | +21.031% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.342% | +0.055% | +7.467% | +18.033% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 5.085% | -0.439% | +6.585% | +19.051% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 4.379% | +0.044% | +11.553% | +10.664% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.212% | -0.025% | +0.038% | +10.611% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.119% | -0.034% | +18.812% | +5.319% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.091% | +0.010% | +5.801% | +5.531% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.960% | +0.374% | +10.028% | +14.352% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 4.816% | -0.168% | +5.991% | +10.032% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.172% | +0.183% | -0.569% | +12.153% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.339% | -0.273% | -4.780% | +5.803% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 2.430% | +1.015% | +6.546% | +3.438% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.349% | -0.325% | +9.307% | +14.573% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.483% | +0.042% | -2.198% | +5.204% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 3.064% | -0.142% | +22.515% | +11.896% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 1.860% | -0.302% | +5.141% | +6.148% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 1.536% | -0.219% | +14.970% | +9.777% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.529% | +0.182% | -2.239% | -2.383% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.515% | +0.096% | +4.217% | +3.728% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.900% | +0.332% | +8.039% | +5.206% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.924% | -0.477% | +7.726% | +5.259% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 4.528% | -0.839% | -0.049% | +9.744% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 3.446% | -0.094% | +17.452% | +7.416% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 1.614% | -0.039% | +18.375% | +6.419% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 4.097% | +0.467% | +19.334% | +8.035% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.257% | +0.072% | +16.258% | +11.437% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 3.809% | +0.849% | +19.983% | +6.930% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 1.074% | -0.001% | +7.289% | +7.192% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.780% | -0.221% | +2.417% | +2.772% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 4.072% | -0.814% | +9.422% | +21.118% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 0.848% | +1.137% | -3.316% | +17.417% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 0.825% | +0.389% | +7.870% | +7.552% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.140% | +0.179% | +2.588% | +12.472% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.364% | -0.045% | +3.743% | +7.549% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 3.740% | -0.401% | -7.218% | +9.651% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.360% | -0.116% | +4.230% | +11.375% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-05-09 Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From webhook-mailer at python.org Thu May 10 04:27:34 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 10 May 2018 08:27:34 -0000 Subject: [Python-checkins] bpo-20171: Convert the _curses and _curses_panel modules to Argument Clinic. (GH-4251) Message-ID: https://github.com/python/cpython/commit/b00854caa080cec613496d3a5e1b0891c9ff83e6 commit: b00854caa080cec613496d3a5e1b0891c9ff83e6 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-05-10T11:27:23+03:00 summary: bpo-20171: Convert the _curses and _curses_panel modules to Argument Clinic. (GH-4251) files: A Modules/clinic/_curses_panel.c.h M Include/py_curses.h M Modules/_curses_panel.c M Modules/_cursesmodule.c M Modules/clinic/_cursesmodule.c.h diff --git a/Include/py_curses.h b/Include/py_curses.h index 0eebc362a15e..2702b37ea7cf 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -91,65 +91,6 @@ static void **PyCurses_API; static const char catchall_ERR[] = "curses function returned ERR"; static const char catchall_NULL[] = "curses function returned NULL"; -/* Function Prototype Macros - They are ugly but very, very useful. ;-) - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing - */ - -#define NoArgNoReturnFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyCursesCheckERR(X(), # X); } - -#define NoArgOrFlagNoReturnFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \ -{ \ - int flag = 0; \ - PyCursesInitialised \ - switch(PyTuple_Size(args)) { \ - case 0: \ - return PyCursesCheckERR(X(), # X); \ - case 1: \ - if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \ - if (flag) return PyCursesCheckERR(X(), # X); \ - else return PyCursesCheckERR(no ## X (), # X); \ - default: \ - PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \ - return NULL; } } - -#define NoArgReturnIntFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyLong_FromLong((long) X()); } - - -#define NoArgReturnStringFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - return PyBytes_FromString(X()); } - -#define NoArgTrueFalseFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - if (X () == FALSE) { \ - Py_RETURN_FALSE; \ - } \ - Py_RETURN_TRUE; } - -#define NoArgNoReturnVoidFunction(X) \ -static PyObject *PyCurses_ ## X (PyObject *self) \ -{ \ - PyCursesInitialised \ - X(); \ - Py_RETURN_NONE; } - #ifdef __cplusplus } #endif diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index a98d2bf3f85f..609718f65f15 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -162,38 +162,69 @@ find_po(PANEL *pan) return temp->po; } -/* Function Prototype Macros - They are ugly but very, very useful. ;-) - - X - function name - TYPE - parameter Type - ERGSTR - format string for construction of the return value - PARSESTR - format string for argument parsing */ - -#define Panel_NoArgNoReturnFunction(X) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ -{ return PyCursesCheckERR(X(self->pan), # X); } - -#define Panel_NoArgTrueFalseFunction(X) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ -{ \ - if (X (self->pan) == FALSE) { Py_RETURN_FALSE; } \ - else { Py_RETURN_TRUE; } } - -#define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ -static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ -{ \ - TYPE arg1, arg2; \ - if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ - return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } +/*[clinic input] +module _curses_panel +class _curses_panel.panel "PyCursesPanelObject *" "&PyCursesPanel_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f4ef263ca850a31]*/ + +#include "clinic/_curses_panel.c.h" /* ------------- PANEL routines --------------- */ -Panel_NoArgNoReturnFunction(bottom_panel) -Panel_NoArgNoReturnFunction(hide_panel) -Panel_NoArgNoReturnFunction(show_panel) -Panel_NoArgNoReturnFunction(top_panel) -Panel_NoArgTrueFalseFunction(panel_hidden) -Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") +/*[clinic input] +_curses_panel.panel.bottom + +Push the panel to the bottom of the stack. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=7aa7d14d7e1d1ce6 input=b6c920c071b61e2e]*/ +{ + return PyCursesCheckERR(bottom_panel(self->pan), "bottom"); +} + +/*[clinic input] +_curses_panel.panel.hide + +Hide the panel. + +This does not delete the object, it just makes the window on screen invisible. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_hide_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=a7bbbd523e1eab49 input=f6ab884e99386118]*/ +{ + return PyCursesCheckERR(hide_panel(self->pan), "hide"); +} + +/*[clinic input] +_curses_panel.panel.show + +Display the panel (which might have been hidden). +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_show_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=6b4553ab45c97769 input=57b167bbefaa3755]*/ +{ + return PyCursesCheckERR(show_panel(self->pan), "show"); +} + +/*[clinic input] +_curses_panel.panel.top + +Push panel to the top of the stack. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_top_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=0f5f2f8cdd2d1777 input=be33975ec3ca0e9a]*/ +{ + return PyCursesCheckERR(top_panel(self->pan), "top"); +} /* Allocation and deallocation of Panel Objects */ @@ -234,8 +265,15 @@ PyCursesPanel_Dealloc(PyCursesPanelObject *po) /* panel_above(NULL) returns the bottom panel in the stack. To get this behaviour we use curses.panel.bottom_panel(). */ +/*[clinic input] +_curses_panel.panel.above + +Return the panel above the current panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_above(PyCursesPanelObject *self) +_curses_panel_panel_above_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=70ac06d25fd3b4da input=c059994022976788]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -258,8 +296,15 @@ PyCursesPanel_above(PyCursesPanelObject *self) /* panel_below(NULL) returns the top panel in the stack. To get this behaviour we use curses.panel.top_panel(). */ +/*[clinic input] +_curses_panel.panel.below + +Return the panel below the current panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_below(PyCursesPanelObject *self) +_curses_panel_panel_below_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=282861122e06e3de input=cc08f61936d297c6]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -280,28 +325,70 @@ PyCursesPanel_below(PyCursesPanelObject *self) return (PyObject *)po; } +/*[clinic input] +_curses_panel.panel.hidden + +Return True if the panel is hidden (not visible), False otherwise. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_window(PyCursesPanelObject *self) +_curses_panel_panel_hidden_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=66eebd1ab4501a71 input=453d4b4fce25e21a]*/ +{ + if (panel_hidden(self->pan)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +/*[clinic input] +_curses_panel.panel.move + + y: int + x: int + / + +Move the panel to the screen coordinates (y, x). +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x) +/*[clinic end generated code: output=d867535a89777415 input=e0b36b78acc03fba]*/ +{ + return PyCursesCheckERR(move_panel(self->pan, y, x), "move_panel"); +} + +/*[clinic input] +_curses_panel.panel.window + +Return the window object associated with the panel. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_panel_window_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/ { Py_INCREF(self->wo); return (PyObject *)self->wo; } +/*[clinic input] +_curses_panel.panel.replace + + win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + / + +Change the window associated with the panel to the window win. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) +_curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyCursesWindowObject *win) +/*[clinic end generated code: output=2253a95f7b287255 input=4b1c4283987d9dfa]*/ { PyCursesPanelObject *po; - PyCursesWindowObject *temp; int rtn; - if (PyTuple_Size(args) != 1) { - PyErr_SetString(PyExc_TypeError, "replace requires one argument"); - return NULL; - } - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - po = find_po(self->pan); if (po == NULL) { PyErr_SetString(PyExc_RuntimeError, @@ -309,18 +396,28 @@ PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) return NULL; } - rtn = replace_panel(self->pan, temp->win); + rtn = replace_panel(self->pan, win->win); if (rtn == ERR) { PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); return NULL; } - Py_INCREF(temp); - Py_SETREF(po->wo, temp); + Py_INCREF(win); + Py_SETREF(po->wo, win); Py_RETURN_NONE; } +/*[clinic input] +_curses_panel.panel.set_userptr + + obj: object + / + +Set the panel?s user pointer to obj. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) +_curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyObject *obj) +/*[clinic end generated code: output=6fb145b3af88cf4a input=2056be1cd148b05c]*/ { PyObject *oldobj; int rc; @@ -336,8 +433,15 @@ PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) return PyCursesCheckERR(rc, "set_panel_userptr"); } +/*[clinic input] +_curses_panel.panel.userptr + +Return the user pointer for the panel. +[clinic start generated code]*/ + static PyObject * -PyCursesPanel_userptr(PyCursesPanelObject *self) +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self) +/*[clinic end generated code: output=e849c307b5dc9237 input=f78b7a47aef0fd50]*/ { PyObject *obj; PyCursesInitialised; @@ -355,18 +459,18 @@ PyCursesPanel_userptr(PyCursesPanelObject *self) /* Module interface */ static PyMethodDef PyCursesPanel_Methods[] = { - {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, - {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, - {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, - {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, - {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, - {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, - {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, - {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, - {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, - {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, - {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, - {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, + _CURSES_PANEL_PANEL_ABOVE_METHODDEF + _CURSES_PANEL_PANEL_BELOW_METHODDEF + _CURSES_PANEL_PANEL_BOTTOM_METHODDEF + _CURSES_PANEL_PANEL_HIDDEN_METHODDEF + _CURSES_PANEL_PANEL_HIDE_METHODDEF + _CURSES_PANEL_PANEL_MOVE_METHODDEF + _CURSES_PANEL_PANEL_REPLACE_METHODDEF + _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF + _CURSES_PANEL_PANEL_SHOW_METHODDEF + _CURSES_PANEL_PANEL_TOP_METHODDEF + _CURSES_PANEL_PANEL_USERPTR_METHODDEF + _CURSES_PANEL_PANEL_WINDOW_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -379,7 +483,7 @@ static PyType_Slot PyCursesPanel_Type_slots[] = { }; static PyType_Spec PyCursesPanel_Type_spec = { - "_curses_panel.curses panel", + "_curses_panel.panel", sizeof(PyCursesPanelObject), 0, Py_TPFLAGS_DEFAULT, @@ -390,8 +494,15 @@ static PyType_Spec PyCursesPanel_Type_spec = { panel of the stack, so it's renamed to bottom_panel(). panel.above() *requires* a panel object in the first place which may be undesirable. */ +/*[clinic input] +_curses_panel.bottom_panel + +Return the bottom panel in the panel stack. +[clinic start generated code]*/ + static PyObject * -PyCurses_bottom_panel(PyObject *self) +_curses_panel_bottom_panel_impl(PyObject *module) +/*[clinic end generated code: output=3aba9f985f4c2bd0 input=634c2a8078b3d7e4]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -414,15 +525,20 @@ PyCurses_bottom_panel(PyObject *self) return (PyObject *)po; } +/*[clinic input] +_curses_panel.new_panel + + win: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + / + +Return a panel object, associating it with the given window win. +[clinic start generated code]*/ + static PyObject * -PyCurses_new_panel(PyObject *self, PyObject *args) +_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win) +/*[clinic end generated code: output=45e948e0176a9bd2 input=74d4754e0ebe4800]*/ { - PyCursesWindowObject *win; - PANEL *pan; - - if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) - return NULL; - pan = new_panel(win->win); + PANEL *pan = new_panel(win->win); if (pan == NULL) { PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); return NULL; @@ -435,8 +551,15 @@ PyCurses_new_panel(PyObject *self, PyObject *args) of the stack, so it's renamed to top_panel(). panel.below() *requires* a panel object in the first place which may be undesirable. */ +/*[clinic input] +_curses_panel.top_panel + +Return the top panel in the panel stack. +[clinic start generated code]*/ + static PyObject * -PyCurses_top_panel(PyObject *self) +_curses_panel_top_panel_impl(PyObject *module) +/*[clinic end generated code: output=86704988bea8508e input=e62d6278dba39e79]*/ { PANEL *pan; PyCursesPanelObject *po; @@ -459,7 +582,17 @@ PyCurses_top_panel(PyObject *self) return (PyObject *)po; } -static PyObject *PyCurses_update_panels(PyObject *self) +/*[clinic input] +_curses_panel.update_panels + +Updates the virtual screen after changes in the panel stack. + +This does not call curses.doupdate(), so you?ll have to do this yourself. +[clinic start generated code]*/ + +static PyObject * +_curses_panel_update_panels_impl(PyObject *module) +/*[clinic end generated code: output=2f3b4c2e03d90ded input=a127069202b0a097]*/ { PyCursesInitialised; update_panels(); @@ -470,10 +603,10 @@ static PyObject *PyCurses_update_panels(PyObject *self) /* List of functions defined in the module */ static PyMethodDef PyCurses_methods[] = { - {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, - {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, - {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, - {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, + _CURSES_PANEL_BOTTOM_PANEL_METHODDEF + _CURSES_PANEL_NEW_PANEL_METHODDEF + _CURSES_PANEL_TOP_PANEL_METHODDEF + _CURSES_PANEL_UPDATE_PANELS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -523,6 +656,9 @@ PyInit__curses_panel(void) PyDict_SetItemString(d, "version", v); PyDict_SetItemString(d, "__version__", v); Py_DECREF(v); + + Py_INCREF(_curses_panelstate(m)->PyCursesPanel_Type); + PyModule_AddObject(m, "panel", (PyObject *)_curses_panelstate(m)->PyCursesPanel_Type); return m; fail: Py_XDECREF(m); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 7936aef0cc90..fe4c9d15c2f2 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -135,12 +135,10 @@ typedef chtype attr_t; /* No attr_t type is available */ #endif /*[clinic input] -module curses -class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" +module _curses +class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=88c860abdbb50e0c]*/ - -#include "clinic/_cursesmodule.c.h" +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=43265c372c2887d6]*/ /* Definition of exception curses.error */ @@ -423,8 +421,7 @@ PyTypeObject PyCursesWindow_Type; static PyObject * PyCursesWindow_ ## X \ (PyCursesWindowObject *self) \ { \ - if (X (self->win) == FALSE) { Py_RETURN_FALSE; } \ - else { Py_RETURN_TRUE; } } + return PyBool_FromLong(X(self->win)); } #define Window_NoArgNoReturnVoidFunction(X) \ static PyObject * PyCursesWindow_ ## X \ @@ -562,26 +559,25 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo) /* Addch, Addstr, Addnstr */ /*[clinic input] - -curses.window.addch +_curses.window.addch [ y: int - Y-coordinate. + Y-coordinate. x: int - X-coordinate. + X-coordinate. ] ch: object - Character to add. + Character to add. [ - attr: long - Attributes for the character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. ] / -Paint character ch at (y, x) with attributes attr. +Paint the character. Paint character ch at (y, x) with attributes attr, overwriting any character previously painted at that location. @@ -590,13 +586,12 @@ current settings for the window object. [clinic start generated code]*/ static PyObject * -curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, - int x, PyObject *ch, int group_right_1, long attr) -/*[clinic end generated code: output=99f7f85078ec06c3 input=5a41efb34a2de338]*/ +_curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr) +/*[clinic end generated code: output=00f4c37af3378f45 input=95ce131578458196]*/ { - PyCursesWindowObject *cwself = (PyCursesWindowObject *)self; int coordinates_group = group_left_1; - int attr_group = group_right_1; int rtn; int type; chtype cch = 0; @@ -606,31 +601,28 @@ curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, #endif const char *funcname; - if (!attr_group) - attr = A_NORMAL; - #ifdef HAVE_NCURSESW - type = PyCurses_ConvertToCchar_t(cwself, ch, &cch, wstr); + type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr); if (type == 2) { funcname = "add_wch"; wstr[1] = L'\0'; setcchar(&wcval, wstr, attr, 0, NULL); if (coordinates_group) - rtn = mvwadd_wch(cwself->win,y,x, &wcval); + rtn = mvwadd_wch(self->win,y,x, &wcval); else { - rtn = wadd_wch(cwself->win, &wcval); + rtn = wadd_wch(self->win, &wcval); } } else #else - type = PyCurses_ConvertToCchar_t(cwself, ch, &cch); + type = PyCurses_ConvertToCchar_t(self, ch, &cch); #endif if (type == 1) { funcname = "addch"; if (coordinates_group) - rtn = mvwaddch(cwself->win,y,x, cch | attr); + rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr); else { - rtn = waddch(cwself->win, cch | attr); + rtn = waddch(self->win, cch | (attr_t) attr); } } else { @@ -639,62 +631,64 @@ curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.addstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to add. + + [ + attr: long + Attributes for characters. + ] + / + +Paint the string. + +Paint the string str at (y, x) with attributes attr, +overwriting anything previously on the display. +By default, the character position and attributes are the +current settings for the window object. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr) +/*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/ { int rtn; - int x, y; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;str", &strobj)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;int,int,str", &y, &x, &strobj)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;int,int,str,attr", &y, &x, &strobj, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments"); - return NULL; - } #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); (void)wattrset(self->win,attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "addwstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddwstr(self->win,y,x,wstr); else rtn = waddwstr(self->win,wstr); @@ -705,73 +699,79 @@ PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "addstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddstr(self->win,y,x,str); else rtn = waddstr(self->win,str); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.addnstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to add. + + n: int + Maximal number of characters. + + [ + attr: long + Attributes for characters. + ] + / + +Paint at most n characters of the string. + +Paint at most n characters of the string str at (y, x) with +attributes attr, overwriting anything previously on the display. +By default, the character position and attributes are the +current settings for the window object. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/ { - int rtn, x, y, n; + int rtn; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n)) - return NULL; - use_xy = TRUE; - break; - case 5: - if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments"); - return NULL; - } #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); (void)wattrset(self->win,attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "addnwstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddnwstr(self->win,y,x,wstr,n); else rtn = waddnwstr(self->win,wstr,n); @@ -782,125 +782,172 @@ PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "addnstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwaddnstr(self->win,y,x,str,n); else rtn = waddnstr(self->win,str,n); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.bkgd + + ch: object + Background character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Background attributes. + / + +Set the background property of the window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args) +_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr) +/*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/ { - PyObject *temp; chtype bkgd; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments"); - return NULL; - } - if (!PyCurses_ConvertToChtype(self, temp, &bkgd)) + if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) return NULL; return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd"); } +/*[clinic input] +_curses.window.attroff + + attr: long + / + +Remove attribute attr from the "background" set. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args) +_curses_window_attroff_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff"); + return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff"); } +/*[clinic input] +_curses.window.attron + + attr: long + / + +Add attribute attr from the "background" set. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args) +_curses_window_attron_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron"); + return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron"); } +/*[clinic input] +_curses.window.attrset + + attr: long + / + +Set the "background" set of attributes. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args) +_curses_window_attrset_impl(PyCursesWindowObject *self, long attr) +/*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/ { - long lattr; - if (!PyArg_ParseTuple(args,"l;attr", &lattr)) - return NULL; - return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset"); + return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset"); } +/*[clinic input] +_curses.window.bkgdset + + ch: object + Background character. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Background attributes. + / + +Set the window's background. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args) +_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, + long attr) +/*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/ { - PyObject *temp; chtype bkgd; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments"); - return NULL; - } - if (!PyCurses_ConvertToChtype(self, temp, &bkgd)) + if (!PyCurses_ConvertToChtype(self, ch, &bkgd)) return NULL; wbkgdset(self->win, bkgd | attr); return PyCursesCheckERR(0, "bkgdset"); } +/*[clinic input] +_curses.window.border + + ls: object(c_default="NULL") = _curses.ACS_VLINE + Left side. + rs: object(c_default="NULL") = _curses.ACS_VLINE + Right side. + ts: object(c_default="NULL") = _curses.ACS_HLINE + Top side. + bs: object(c_default="NULL") = _curses.ACS_HLINE + Bottom side. + tl: object(c_default="NULL") = _curses.ACS_ULCORNER + Upper-left corner. + tr: object(c_default="NULL") = _curses.ACS_URCORNER + Upper-right corner. + bl: object(c_default="NULL") = _curses.ACS_LLCORNER + Bottom-left corner. + br: object(c_default="NULL") = _curses.ACS_LRCORNER + Bottom-right corner. + / + +Draw a border around the edges of the window. + +Each parameter specifies the character to use for a specific part of the +border. The characters can be specified as integers or as one-character +strings. A 0 value for any parameter will cause the default character to be +used for that parameter. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) +_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, + PyObject *rs, PyObject *ts, PyObject *bs, + PyObject *tl, PyObject *tr, PyObject *bl, + PyObject *br) +/*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/ { - PyObject *temp[8]; chtype ch[8]; int i; /* Clear the array of parameters */ - for(i=0; i<8; i++) { - temp[i] = NULL; + for(i=0; i<8; i++) ch[i] = 0; - } - if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br", - &temp[0], &temp[1], &temp[2], &temp[3], - &temp[4], &temp[5], &temp[6], &temp[7])) +#define CONVERTTOCHTYPE(obj, i) \ + if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \ return NULL; - for(i=0; i<8; i++) { - if (temp[i] != NULL && !PyCurses_ConvertToChtype(self, temp[i], &ch[i])) - return NULL; - } + CONVERTTOCHTYPE(ls, 0); + CONVERTTOCHTYPE(rs, 1); + CONVERTTOCHTYPE(ts, 2); + CONVERTTOCHTYPE(bs, 3); + CONVERTTOCHTYPE(tl, 4); + CONVERTTOCHTYPE(tr, 5); + CONVERTTOCHTYPE(bl, 6); + CONVERTTOCHTYPE(br, 7); + +#undef CONVERTTOCHTYPE wborder(self->win, ch[0], ch[1], ch[2], ch[3], @@ -908,20 +955,34 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_curses.window.box + + [ + verch: object(c_default="_PyLong_Zero") = 0 + Left and right side. + horch: object(c_default="_PyLong_Zero") = 0 + Top and bottom side. + ] + / + +Draw a border around the edges of the window. + +Similar to border(), but both ls and rs are verch and both ts and bs are +horch. The default corner characters are always used by this function. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args) +_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, + PyObject *verch, PyObject *horch) +/*[clinic end generated code: output=f3fcb038bb287192 input=465a121741c1efdf]*/ { - PyObject *temp1, *temp2; - chtype ch1=0,ch2=0; - switch(PyTuple_Size(args)){ - case 0: break; - default: - if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2)) - return NULL; - if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) { + chtype ch1 = 0, ch2 = 0; + if (group_right_1) { + if (!PyCurses_ConvertToChtype(self, verch, &ch1)) { return NULL; } - if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) { + if (!PyCurses_ConvertToChtype(self, horch, &ch2)) { return NULL; } } @@ -949,6 +1010,32 @@ int py_mvwdelch(WINDOW *w, int y, int x) /* chgat, added by Fabian Kreutz */ #ifdef HAVE_CURSES_WCHGAT +/*[-clinic input] +_curses.window.chgat + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + n: int = -1 + Number of characters. + + attr: long + Attributes for characters. + / + +Set the attributes of characters. + +Set the attributes of num characters at the current cursor position, or at +position (y, x) if supplied. If no value of num is given or num = -1, the +attribute will be set on all the characters to the end of the line. This +function does not move the cursor. The changed line will be touched using +the touchline() method so that the contents will be redisplayed by the next +window refresh. +[-clinic start generated code]*/ static PyObject * PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) { @@ -991,7 +1078,7 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) color = (short)((attr >> 8) & 0xff); attr = attr - (color << 8); - if (use_xy == TRUE) { + if (use_xy) { rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); touchline(self->win,y,1); } else { @@ -1003,50 +1090,61 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.window.delch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Delete any character at (y, x). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/ { - int rtn; - int x, y; - - switch (PyTuple_Size(args)) { - case 0: - rtn = wdelch(self->win); - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x)) - return NULL; - rtn = py_mvwdelch(self->win,y,x); - break; - default: - PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments"); - return NULL; + if (!group_right_1) { + return PyCursesCheckERR(wdelch(self->win), "wdelch"); + } + else { + return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch"); } - return PyCursesCheckERR(rtn, "[mv]wdelch"); } +/*[clinic input] +_curses.window.derwin + + [ + nlines: int = 0 + Height. + ncols: int = 0 + Width. + ] + begin_y: int + Top side y-coordinate. + begin_x: int + Left side x-coordinate. + / + +Create a sub-window (window-relative coordinates). + +derwin() is the same as calling subwin(), except that begin_y and begin_x +are relative to the origin of the window, rather than relative to the entire +screen. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args) +_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x) +/*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/ { WINDOW *win; - int nlines, ncols, begin_y, begin_x; - - nlines = 0; - ncols = 0; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments"); - return NULL; - } win = derwin(self->win,nlines,ncols,begin_y,begin_x); @@ -1058,112 +1156,145 @@ PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } -static PyObject * -PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args) -{ - PyObject *temp; - chtype ch; - attr_t attr = A_NORMAL; - long lattr; +/*[clinic input] +_curses.window.echochar - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - default: - PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments"); + ch: object + Character to add. + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + / - return NULL; - } +Add character ch with attribute attr, and refresh. +[clinic start generated code]*/ + +static PyObject * +_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, + long attr) +/*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/ +{ + chtype ch_; - if (!PyCurses_ConvertToChtype(self, temp, &ch)) + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; #ifdef py_is_pad if (py_is_pad(self->win)) { - return PyCursesCheckERR(pechochar(self->win, ch | attr), + return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr), "echochar"); } else #endif - return PyCursesCheckERR(wechochar(self->win, ch | attr), + return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr), "echochar"); } #ifdef NCURSES_MOUSE_VERSION -static PyObject * -PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args) -{ - int x, y; - if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x)) - return NULL; +/*[clinic input] +_curses.window.enclose -> long - return PyLong_FromLong( wenclose(self->win,y,x) ); -} -#endif + y: int + Y-coordinate. + x: int + X-coordinate. + / -static PyObject * -PyCursesWindow_GetBkgd(PyCursesWindowObject *self) +Return True if the screen-relative coordinates are enclosed by the window. +[clinic start generated code]*/ + +static long +_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x) +/*[clinic end generated code: output=5251c961cbe3df63 input=dfe1d9d4d05d8642]*/ { - return PyLong_FromLong((long) getbkgd(self->win)); + return wenclose(self->win, y, x); } +#endif -static PyObject * -PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args) +/*[clinic input] +_curses.window.getbkgd -> long + +Return the window's current background character/attribute pair. +[clinic start generated code]*/ + +static long +_curses_window_getbkgd_impl(PyCursesWindowObject *self) +/*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/ +{ + return (long) getbkgd(self->win); +} + +/*[clinic input] +_curses.window.getch -> int + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a character code from terminal keyboard. + +The integer returned does not have to be in ASCII range: function keys, +keypad keys and so on return numbers higher than 256. In no-delay mode, -1 +is returned if there is no input, else getch() waits until a key is pressed. +[clinic start generated code]*/ + +static int +_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/ { - int x, y; int rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { rtn = wgetch(self->win); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = mvwgetch(self->win,y,x); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments"); - return NULL; } - return PyLong_FromLong((long)rtn); + else { + rtn = mvwgetch(self->win, y, x); + } + Py_END_ALLOW_THREADS + + return rtn; } +/*[clinic input] +_curses.window.getkey + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a character (string) from terminal keyboard. + +Returning a string instead of an integer, as getch() does. Function keys, +keypad keys and other special keys return a multibyte string containing the +key name. In no-delay mode, an exception is raised if there is no input. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args) +_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/ { - int x, y; int rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { rtn = wgetch(self->win); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = mvwgetch(self->win,y,x); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments"); - return NULL; } + else { + rtn = mvwgetch(self->win, y, x); + } + Py_END_ALLOW_THREADS + if (rtn == ERR) { /* getch() returns ERR in nodelay mode */ PyErr_CheckSignals(); @@ -1187,30 +1318,40 @@ PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args) } #ifdef HAVE_NCURSESW +/*[clinic input] +_curses.window.get_wch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Get a wide character from terminal keyboard. + +Return a character for most keys, or an integer for function keys, +keypad keys, and other special keys. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/ { - int x, y; int ct; wint_t rtn; - switch (PyTuple_Size(args)) { - case 0: - Py_BEGIN_ALLOW_THREADS - ct = wget_wch(self->win,&rtn); - Py_END_ALLOW_THREADS - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - Py_BEGIN_ALLOW_THREADS - ct = mvwget_wch(self->win,y,x,&rtn); - Py_END_ALLOW_THREADS - break; - default: - PyErr_SetString(PyExc_TypeError, "get_wch requires 0 or 2 arguments"); - return NULL; + Py_BEGIN_ALLOW_THREADS + if (!group_right_1) { + ct = wget_wch(self->win ,&rtn); + } + else { + ct = mvwget_wch(self->win, y, x, &rtn); } + Py_END_ALLOW_THREADS + if (ct == ERR) { if (PyErr_CheckSignals()) return NULL; @@ -1226,6 +1367,22 @@ PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args) } #endif +/*[-clinic input] +_curses.window.getstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + n: int = 1023 + Maximal number of characters. + / + +Read a string from the user, with primitive line editing capacity. +[-clinic start generated code]*/ + static PyObject * PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) { @@ -1288,118 +1445,148 @@ PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args) return PyBytes_FromString(rtn); } +/*[clinic input] +_curses.window.hline + + [ + y: int + Starting Y-coordinate. + x: int + Starting X-coordinate. + ] + + ch: object + Character to draw. + n: int + Line length. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the characters. + ] + / + +Display a horizontal line. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args) +_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/ { - PyObject *temp; - chtype ch; - int n, x, y, code = OK; - attr_t attr = A_NORMAL; - long lattr; + chtype ch_; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) - return NULL; - attr = lattr; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) - return NULL; - code = wmove(self->win, y, x); - break; - case 5: - if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &lattr)) - return NULL; - attr = lattr; - code = wmove(self->win, y, x); - break; - default: - PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments"); + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + if (group_left_1) { + if (wmove(self->win, y, x) == ERR) { + return PyCursesCheckERR(ERR, "wmove"); + } } - - if (code != ERR) { - if (!PyCurses_ConvertToChtype(self, temp, &ch)) - return NULL; - return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline"); - } else - return PyCursesCheckERR(code, "wmove"); + return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline"); } +/*[clinic input] +_curses.window.insch + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + ch: object + Character to insert. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + ] + / + +Insert a character before the current or specified position. + +All characters to the right of the cursor are shifted one position right, with +the rightmost characters on the line being lost. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args) +_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr) +/*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/ { - int rtn, x, y, use_xy = FALSE; - PyObject *temp; - chtype ch = 0; - attr_t attr = A_NORMAL; - long lattr; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O;ch or int", &temp)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr)) - return NULL; - attr = lattr; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr)) - return NULL; - attr = lattr; - use_xy = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insch requires 1 to 4 arguments"); - return NULL; - } + int rtn; + chtype ch_ = 0; - if (!PyCurses_ConvertToChtype(self, temp, &ch)) + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; - if (use_xy == TRUE) - rtn = mvwinsch(self->win,y,x, ch | attr); + if (!group_left_1) { + rtn = winsch(self->win, ch_ | (attr_t)attr); + } else { - rtn = winsch(self->win, ch | attr); + rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr); } + return PyCursesCheckERR(rtn, "insch"); } -static PyObject * -PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) +/*[clinic input] +_curses.window.inch -> unsigned_long + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + / + +Return the character at the given position in the window. + +The bottom 8 bits are the character proper, and upper bits are the attributes. +[clinic start generated code]*/ + +static unsigned long +_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x) +/*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/ { - int x, y; unsigned long rtn; - switch (PyTuple_Size(args)) { - case 0: + if (!group_right_1) { rtn = winch(self->win); - break; - case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) - return NULL; - rtn = mvwinch(self->win,y,x); - break; - default: - PyErr_SetString(PyExc_TypeError, "inch requires 0 to 2 arguments"); - return NULL; } - return PyLong_FromUnsignedLong(rtn); + else { + rtn = mvwinch(self->win, y, x); + } + + return rtn; } +/*[-clinic input] +_curses.window.instr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + n: int = 1023 + Maximal number of characters. + / + +Return a string of characters, extracted from the window. + +Return a string of characters, extracted from the window starting at the +current cursor position, or at y, x if specified. Attributes are stripped +from the characters. If n is specified, instr() returns a string at most +n characters long (exclusive of the trailing NUL). +[-clinic start generated code]*/ static PyObject * PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) { @@ -1443,64 +1630,66 @@ PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args) return PyBytes_FromString(rtn); } +/*[clinic input] +_curses.window.insstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to insert. + + [ + attr: long + Attributes for characters. + ] + / + +Insert the string before the current or specified position. + +Insert a character string (as many characters as will fit on the line) +before the character under the cursor. All characters to the right of +the cursor are shifted right, with the rightmost characters on the line +being lost. The cursor position does not change (after moving to y, x, +if specified). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr) +/*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/ { int rtn; - int x, y; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"O;str", &strobj)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 3: - if (!PyArg_ParseTuple(args,"iiO;y,x,str", &y, &x, &strobj)) - return NULL; - use_xy = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOl;y,x,str,attr", &y, &x, &strobj, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments"); - return NULL; - } - #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); - (void)wattrset(self->win,attr); + (void)wattrset(self->win, (attr_t)attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "inswstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwins_wstr(self->win,y,x,wstr); else rtn = wins_wstr(self->win,wstr); @@ -1511,74 +1700,81 @@ PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "insstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwinsstr(self->win,y,x,str); else rtn = winsstr(self->win,str); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.insnstr + + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + + str: object + String to insert. + + n: int + Maximal number of characters. + + [ + attr: long + Attributes for characters. + ] + / + +Insert at most n characters of the string. + +Insert a character string (as many characters as will fit on the line) +before the character under the cursor, up to n characters. If n is zero +or negative, the entire string is inserted. All characters to the right +of the cursor are shifted right, with the rightmost characters on the line +being lost. The cursor position does not change (after moving to y, x, if +specified). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args) +_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/ { - int rtn, x, y, n; + int rtn; int strtype; - PyObject *strobj, *bytesobj = NULL; + PyObject *bytesobj = NULL; #ifdef HAVE_NCURSESW wchar_t *wstr = NULL; #endif - attr_t attr = A_NORMAL , attr_old = A_NORMAL; - long lattr; - int use_xy = FALSE, use_attr = FALSE; + attr_t attr_old = A_NORMAL; + int use_xy = group_left_1, use_attr = group_right_1; const char *funcname; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_attr = TRUE; - break; - case 4: - if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n)) - return NULL; - use_xy = TRUE; - break; - case 5: - if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr)) - return NULL; - attr = lattr; - use_xy = use_attr = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments"); - return NULL; - } - #ifdef HAVE_NCURSESW - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr); #else - strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL); + strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL); #endif if (strtype == 0) return NULL; - if (use_attr == TRUE) { + if (use_attr) { attr_old = getattrs(self->win); - (void)wattrset(self->win,attr); + (void)wattrset(self->win, (attr_t)attr); } #ifdef HAVE_NCURSESW if (strtype == 2) { funcname = "insn_wstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwins_nwstr(self->win,y,x,wstr,n); else rtn = wins_nwstr(self->win,wstr,n); @@ -1589,160 +1785,226 @@ PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args) { char *str = PyBytes_AS_STRING(bytesobj); funcname = "insnstr"; - if (use_xy == TRUE) + if (use_xy) rtn = mvwinsnstr(self->win,y,x,str,n); else rtn = winsnstr(self->win,str,n); Py_DECREF(bytesobj); } - if (use_attr == TRUE) + if (use_attr) (void)wattrset(self->win,attr_old); return PyCursesCheckERR(rtn, funcname); } +/*[clinic input] +_curses.window.is_linetouched + + line: int + Line number. + / + +Return True if the specified line was modified, otherwise return False. + +Raise a curses.error exception if line is not valid for the given window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args) +_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line) +/*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/ { - int line, erg; - if (!PyArg_ParseTuple(args,"i;line", &line)) - return NULL; + int erg; erg = is_linetouched(self->win, line); if (erg == ERR) { PyErr_SetString(PyExc_TypeError, "is_linetouched: line number outside of boundaries"); return NULL; - } else - if (erg == FALSE) { - Py_RETURN_FALSE; - } else { - Py_RETURN_TRUE; - } + } + return PyBool_FromLong(erg); } -static PyObject * -PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args) -{ - int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; - int rtn; +#ifdef py_is_pad +/*[clinic input] +_curses.window.noutrefresh -#ifndef py_is_pad - if (0) + [ + pminrow: int + pmincol: int + sminrow: int + smincol: int + smaxrow: int + smaxcol: int + ] + / + +Mark for refresh but wait. + +This function updates the data structure representing the desired state of the +window, but does not force an update of the physical screen. To accomplish +that, call doupdate(). +[clinic start generated code]*/ + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self, + int group_right_1, int pminrow, int pmincol, + int sminrow, int smincol, int smaxrow, + int smaxcol) +/*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/ #else - if (py_is_pad(self->win)) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = pnoutrefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "pnoutrefresh"); - default: - PyErr_SetString(PyCursesError, - "noutrefresh() called for a pad " - "requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":noutrefresh")) - return NULL; +/*[clinic input] +_curses.window.noutrefresh - Py_BEGIN_ALLOW_THREADS - rtn = wnoutrefresh(self->win); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "wnoutrefresh"); - } -} +Mark for refresh but wait. + +This function updates the data structure representing the desired state of the +window, but does not force an update of the physical screen. To accomplish +that, call doupdate(). +[clinic start generated code]*/ static PyObject * -PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args) +_curses_window_noutrefresh_impl(PyCursesWindowObject *self) +/*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/ +#endif { - PyCursesWindowObject *temp; - int use_copywin = FALSE; - int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; int rtn; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - break; - case 7: - if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int", - &PyCursesWindow_Type, &temp, &sminrow, &smincol, - &dminrow, &dmincol, &dmaxrow, &dmaxcol)) +#ifdef py_is_pad + if (py_is_pad(self->win)) { + if (!group_right_1) { + PyErr_SetString(PyCursesError, + "noutrefresh() called for a pad " + "requires 6 arguments"); return NULL; - use_copywin = TRUE; - break; - default: + } + Py_BEGIN_ALLOW_THREADS + rtn = pnoutrefresh(self->win, pminrow, pmincol, + sminrow, smincol, smaxrow, smaxcol); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "pnoutrefresh"); + } + if (group_right_1) { PyErr_SetString(PyExc_TypeError, - "overlay requires one or seven arguments"); + "noutrefresh() takes no arguments (6 given)"); return NULL; } +#endif + Py_BEGIN_ALLOW_THREADS + rtn = wnoutrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "wnoutrefresh"); +} + +/*[clinic input] +_curses.window.overlay + + destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + + [ + sminrow: int + smincol: int + dminrow: int + dmincol: int + dmaxrow: int + dmaxcol: int + ] + / + +Overlay the window on top of destwin. + +The windows need not be the same size, only the overlapping region is copied. +This copy is non-destructive, which means that the current background +character does not overwrite the old contents of destwin. + +To get fine-grained control over the copied region, the second form of +overlay() can be used. sminrow and smincol are the upper-left coordinates +of the source window, and the other variables mark a rectangle in the +destination window. +[clinic start generated code]*/ - if (use_copywin == TRUE) { - rtn = copywin(self->win, temp->win, sminrow, smincol, +static PyObject * +_curses_window_overlay_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, int group_right_1, + int sminrow, int smincol, int dminrow, + int dmincol, int dmaxrow, int dmaxcol) +/*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/ +{ + int rtn; + + if (group_right_1) { + rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, TRUE); return PyCursesCheckERR(rtn, "copywin"); } else { - rtn = overlay(self->win, temp->win); + rtn = overlay(self->win, destwin->win); return PyCursesCheckERR(rtn, "overlay"); } } +/*[clinic input] +_curses.window.overwrite + + destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type") + + [ + sminrow: int + smincol: int + dminrow: int + dmincol: int + dmaxrow: int + dmaxcol: int + ] + / + +Overwrite the window on top of destwin. + +The windows need not be the same size, in which case only the overlapping +region is copied. This copy is destructive, which means that the current +background character overwrites the old contents of destwin. + +To get fine-grained control over the copied region, the second form of +overwrite() can be used. sminrow and smincol are the upper-left coordinates +of the source window, the other variables mark a rectangle in the destination +window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args) +_curses_window_overwrite_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, + int group_right_1, int sminrow, int smincol, + int dminrow, int dmincol, int dmaxrow, + int dmaxcol) +/*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/ { - PyCursesWindowObject *temp; - int use_copywin = FALSE; - int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; int rtn; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O!;window object", - &PyCursesWindow_Type, &temp)) - return NULL; - break; - case 7: - if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int", - &PyCursesWindow_Type, &temp, &sminrow, &smincol, - &dminrow, &dmincol, &dmaxrow, &dmaxcol)) - return NULL; - use_copywin = TRUE; - break; - default: - PyErr_SetString(PyExc_TypeError, - "overwrite requires one or seven arguments"); - return NULL; - } - - if (use_copywin == TRUE) { - rtn = copywin(self->win, temp->win, sminrow, smincol, + if (group_right_1) { + rtn = copywin(self->win, destwin->win, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, FALSE); return PyCursesCheckERR(rtn, "copywin"); } else { - rtn = overwrite(self->win, temp->win); + rtn = overwrite(self->win, destwin->win); return PyCursesCheckERR(rtn, "overwrite"); } } +/*[clinic input] +_curses.window.putwin + + file: object + / + +Write all data associated with the window into the provided file object. + +This information can be later retrieved using the getwin() function. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) +_curses_window_putwin(PyCursesWindowObject *self, PyObject *file) +/*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/ { /* We have to simulate this by writing to a temporary FILE*, - then reading back, then writing to the argument stream. */ + then reading back, then writing to the argument file. */ FILE *fp; PyObject *res = NULL; @@ -1763,7 +2025,7 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) if (n <= 0) break; Py_DECREF(res); - res = _PyObject_CallMethodId(stream, &PyId_write, "y#", buf, n); + res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); if (res == NULL) break; } @@ -1773,88 +2035,137 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) return res; } +/*[clinic input] +_curses.window.redrawln + + beg: int + Starting line number. + num: int + The number of lines. + / + +Mark the specified lines corrupted. + +They should be completely redrawn on the next refresh() call. +[clinic start generated code]*/ + +static PyObject * +_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num) +/*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/ +{ + return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); +} + +/*[clinic input] +_curses.window.refresh + + [ + pminrow: int + pmincol: int + sminrow: int + smincol: int + smaxrow: int + smaxcol: int + ] + / + +Update the display immediately. + +Synchronize actual screen with previous drawing/deleting methods. +The 6 optional arguments can only be specified when the window is a pad +created with newpad(). The additional parameters are needed to indicate +what part of the pad and screen are involved. pminrow and pmincol specify +the upper left-hand corner of the rectangle to be displayed in the pad. +sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to +be displayed on the screen. The lower right-hand corner of the rectangle to +be displayed in the pad is calculated from the screen coordinates, since the +rectangles must be the same size. Both rectangles must be entirely contained +within their respective structures. Negative values of pminrow, pmincol, +sminrow, or smincol are treated as if they were zero. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args) +_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, + int pminrow, int pmincol, int sminrow, + int smincol, int smaxrow, int smaxcol) +/*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/ { - int beg, num; - if (!PyArg_ParseTuple(args, "ii;beg,num", &beg, &num)) + int rtn; + +#ifdef py_is_pad + if (py_is_pad(self->win)) { + if (!group_right_1) { + PyErr_SetString(PyCursesError, + "refresh() for a pad requires 6 arguments"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + rtn = prefresh(self->win, pminrow, pmincol, + sminrow, smincol, smaxrow, smaxcol); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "prefresh"); + } +#endif + if (group_right_1) { + PyErr_SetString(PyExc_TypeError, + "refresh() takes no arguments (6 given)"); return NULL; - return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln"); + } + Py_BEGIN_ALLOW_THREADS + rtn = wrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "prefresh"); } -static PyObject * -PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args) -{ - int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; - int rtn; +/*[clinic input] +_curses.window.setscrreg -#ifndef py_is_pad - if (0) -#else - if (py_is_pad(self->win)) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - rtn = prefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "prefresh"); - default: - PyErr_SetString(PyCursesError, - "refresh() for a pad requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":refresh")) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = wrefresh(self->win); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "prefresh"); - } -} + top: int + First line number. + bottom: int + Last line number. + / + +Define a software scrolling region. + +All scrolling actions will take place in this region. +[clinic start generated code]*/ static PyObject * -PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args) +_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, + int bottom) +/*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/ { - int x, y; - if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x)) - return NULL; - return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg"); + return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg"); } +/*[clinic input] +_curses.window.subwin + + [ + nlines: int = 0 + Height. + ncols: int = 0 + Width. + ] + begin_y: int + Top side y-coordinate. + begin_x: int + Left side x-coordinate. + / + +Create a sub-window (screen-relative coordinates). + +By default, the sub-window will extend from the specified position to the +lower right corner of the window. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args) +_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x) +/*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/ { WINDOW *win; - int nlines, ncols, begin_y, begin_x; - - nlines = 0; - ncols = 0; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments"); - return NULL; - } /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ #ifdef py_is_pad @@ -1873,84 +2184,101 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, self->encoding); } +/*[clinic input] +_curses.window.scroll + + [ + lines: int = 1 + Number of lines to scroll. + ] + / + +Scroll the screen or scrolling region. + +Scroll upward if the argument is positive and downward if it is negative. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args) +_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, + int lines) +/*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/ { - int nlines; - switch(PyTuple_Size(args)) { - case 0: + if (!group_right_1) { return PyCursesCheckERR(scroll(self->win), "scroll"); - case 1: - if (!PyArg_ParseTuple(args, "i;nlines", &nlines)) - return NULL; - return PyCursesCheckERR(wscrl(self->win, nlines), "scroll"); - default: - PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments"); - return NULL; + } + else { + return PyCursesCheckERR(wscrl(self->win, lines), "scroll"); } } +/*[clinic input] +_curses.window.touchline + + start: int + count: int + [ + changed: bool(accept={int}) = True + ] + / + +Pretend count lines have been changed, starting with line start. + +If changed is supplied, it specifies whether the affected lines are marked +as having been changed (changed=True) or unchanged (changed=False). +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args) +_curses_window_touchline_impl(PyCursesWindowObject *self, int start, + int count, int group_right_1, int changed) +/*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ { - int st, cnt, val; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt)) - return NULL; - return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline"); - case 3: - if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val)) - return NULL; - return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline"); - default: - PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments"); - return NULL; + if (!group_right_1) { + return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); + } + else { + return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline"); } } +/*[clinic input] +_curses.window.vline + + [ + y: int + Starting Y-coordinate. + x: int + Starting X-coordinate. + ] + + ch: object + Character to draw. + n: int + Line length. + + [ + attr: long(c_default="A_NORMAL") = _curses.A_NORMAL + Attributes for the character. + ] + / + +Display a vertical line. +[clinic start generated code]*/ + static PyObject * -PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args) +_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr) +/*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/ { - PyObject *temp; - chtype ch; - int n, x, y, code = OK; - attr_t attr = A_NORMAL; - long lattr; + chtype ch_; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n)) - return NULL; - break; - case 3: - if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr)) - return NULL; - attr = lattr; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n)) - return NULL; - code = wmove(self->win, y, x); - break; - case 5: - if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", - &y, &x, &temp, &n, &lattr)) - return NULL; - attr = lattr; - code = wmove(self->win, y, x); - break; - default: - PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments"); + if (!PyCurses_ConvertToChtype(self, ch, &ch_)) return NULL; + if (group_left_1) { + if (wmove(self->win, y, x) == ERR) + return PyCursesCheckERR(ERR, "wmove"); } - - if (code != ERR) { - if (!PyCurses_ConvertToChtype(self, temp, &ch)) - return NULL; - return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline"); - } else - return PyCursesCheckERR(code, "wmove"); + return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline"); } static PyObject * @@ -1991,59 +2319,56 @@ PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value) return 0; } +#include "clinic/_cursesmodule.c.h" static PyMethodDef PyCursesWindow_Methods[] = { - CURSES_WINDOW_ADDCH_METHODDEF - {"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS}, - {"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS}, - {"attroff", (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS}, - {"attron", (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS}, - {"attrset", (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS}, - {"bkgd", (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS}, + _CURSES_WINDOW_ADDCH_METHODDEF + _CURSES_WINDOW_ADDNSTR_METHODDEF + _CURSES_WINDOW_ADDSTR_METHODDEF + _CURSES_WINDOW_ATTROFF_METHODDEF + _CURSES_WINDOW_ATTRON_METHODDEF + _CURSES_WINDOW_ATTRSET_METHODDEF + _CURSES_WINDOW_BKGD_METHODDEF #ifdef HAVE_CURSES_WCHGAT {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS}, #endif - {"bkgdset", (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS}, - {"border", (PyCFunction)PyCursesWindow_Border, METH_VARARGS}, - {"box", (PyCFunction)PyCursesWindow_Box, METH_VARARGS}, + _CURSES_WINDOW_BKGDSET_METHODDEF + _CURSES_WINDOW_BORDER_METHODDEF + _CURSES_WINDOW_BOX_METHODDEF {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS}, {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS}, {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS}, {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS}, {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS}, - {"delch", (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS}, + _CURSES_WINDOW_DELCH_METHODDEF {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS}, - {"derwin", (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS}, - {"echochar", (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"enclose", (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS}, -#endif + _CURSES_WINDOW_DERWIN_METHODDEF + _CURSES_WINDOW_ECHOCHAR_METHODDEF + _CURSES_WINDOW_ENCLOSE_METHODDEF {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS}, {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS}, - {"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS}, - {"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS}, - {"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS}, -#ifdef HAVE_NCURSESW - {"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS}, -#endif + _CURSES_WINDOW_GETBKGD_METHODDEF + _CURSES_WINDOW_GETCH_METHODDEF + _CURSES_WINDOW_GETKEY_METHODDEF + _CURSES_WINDOW_GET_WCH_METHODDEF {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS}, {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS}, {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS}, {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS}, - {"hline", (PyCFunction)PyCursesWindow_Hline, METH_VARARGS}, + _CURSES_WINDOW_HLINE_METHODDEF {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS}, {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS}, #ifdef HAVE_CURSES_IMMEDOK {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS}, #endif - {"inch", (PyCFunction)PyCursesWindow_InCh, METH_VARARGS}, - {"insch", (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS}, + _CURSES_WINDOW_INCH_METHODDEF + _CURSES_WINDOW_INSCH_METHODDEF {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS}, {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS}, - {"insnstr", (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS}, - {"insstr", (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS}, + _CURSES_WINDOW_INSNSTR_METHODDEF + _CURSES_WINDOW_INSSTR_METHODDEF {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS}, - {"is_linetouched", (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS}, + _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS}, {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS}, {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS}, @@ -2052,34 +2377,33 @@ static PyMethodDef PyCursesWindow_Methods[] = { {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS}, {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, - {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, - {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, - {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, - METH_VARARGS}, - {"putwin", (PyCFunction)PyCursesWindow_PutWin, METH_O}, - {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine, METH_VARARGS}, + _CURSES_WINDOW_NOUTREFRESH_METHODDEF + _CURSES_WINDOW_OVERLAY_METHODDEF + _CURSES_WINDOW_OVERWRITE_METHODDEF + _CURSES_WINDOW_PUTWIN_METHODDEF + _CURSES_WINDOW_REDRAWLN_METHODDEF {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS}, - {"refresh", (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS}, + _CURSES_WINDOW_REFRESH_METHODDEF #ifndef STRICT_SYSV_CURSES {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS}, #endif - {"scroll", (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS}, + _CURSES_WINDOW_SCROLL_METHODDEF {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS}, - {"setscrreg", (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS}, + _CURSES_WINDOW_SETSCRREG_METHODDEF {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS}, {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS}, - {"subpad", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS}, - {"subwin", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS}, + {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, + _CURSES_WINDOW_SUBWIN_METHODDEF {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS}, #ifdef HAVE_CURSES_SYNCOK {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS}, #endif {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS}, {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS}, - {"touchline", (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS}, + _CURSES_WINDOW_TOUCHLINE_METHODDEF {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS}, {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS}, - {"vline", (PyCFunction)PyCursesWindow_Vline, METH_VARARGS}, + _CURSES_WINDOW_VLINE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2127,47 +2451,63 @@ PyTypeObject PyCursesWindow_Type = { PyCursesWindow_getsets, /* tp_getset */ }; +/* Function Prototype Macros - They are ugly but very, very useful. ;-) + + X - function name + TYPE - parameter Type + ERGSTR - format string for construction of the return value + PARSESTR - format string for argument parsing + */ + +#define NoArgNoReturnFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyCursesCheckERR(X(), # X); } + +#define NoArgOrFlagNoReturnFunctionBody(X, flag) \ +{ \ + PyCursesInitialised \ + if (flag) \ + return PyCursesCheckERR(X(), # X); \ + else \ + return PyCursesCheckERR(no ## X(), # X); \ +} + +#define NoArgReturnIntFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyLong_FromLong((long) X()); } + + +#define NoArgReturnStringFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyBytes_FromString(X()); } + +#define NoArgTrueFalseFunctionBody(X) \ +{ \ + PyCursesInitialised \ + return PyBool_FromLong(X()); } + +#define NoArgNoReturnVoidFunctionBody(X) \ +{ \ + PyCursesInitialised \ + X(); \ + Py_RETURN_NONE; } + /********************************************************************* Global Functions **********************************************************************/ -NoArgNoReturnFunction(beep) -NoArgNoReturnFunction(def_prog_mode) -NoArgNoReturnFunction(def_shell_mode) -NoArgNoReturnFunction(doupdate) -NoArgNoReturnFunction(endwin) -NoArgNoReturnFunction(flash) -NoArgNoReturnFunction(nocbreak) -NoArgNoReturnFunction(noecho) -NoArgNoReturnFunction(nonl) -NoArgNoReturnFunction(noraw) -NoArgNoReturnFunction(reset_prog_mode) -NoArgNoReturnFunction(reset_shell_mode) -NoArgNoReturnFunction(resetty) -NoArgNoReturnFunction(savetty) - -NoArgOrFlagNoReturnFunction(cbreak) -NoArgOrFlagNoReturnFunction(echo) -NoArgOrFlagNoReturnFunction(nl) -NoArgOrFlagNoReturnFunction(raw) - -NoArgReturnIntFunction(baudrate) -NoArgReturnIntFunction(termattrs) - -NoArgReturnStringFunction(termname) -NoArgReturnStringFunction(longname) - -NoArgTrueFalseFunction(can_change_color) -NoArgTrueFalseFunction(has_colors) -NoArgTrueFalseFunction(has_ic) -NoArgTrueFalseFunction(has_il) -NoArgTrueFalseFunction(isendwin) -NoArgNoReturnVoidFunction(flushinp) -NoArgNoReturnVoidFunction(noqiflush) - #ifdef HAVE_CURSES_FILTER +/*[clinic input] +_curses.filter + +[clinic start generated code]*/ + static PyObject * -PyCurses_filter(PyObject *self) +_curses_filter_impl(PyObject *module) +/*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/ { /* not checking for PyCursesInitialised here since filter() must be called before initscr() */ @@ -2176,17 +2516,83 @@ PyCurses_filter(PyObject *self) } #endif +/*[clinic input] +_curses.baudrate + +Return the output speed of the terminal in bits per second. +[clinic start generated code]*/ + +static PyObject * +_curses_baudrate_impl(PyObject *module) +/*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/ +NoArgReturnIntFunctionBody(baudrate) + +/*[clinic input] +_curses.beep + +Emit a short attention sound. +[clinic start generated code]*/ + +static PyObject * +_curses_beep_impl(PyObject *module) +/*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/ +NoArgNoReturnFunctionBody(beep) + +/*[clinic input] +_curses.can_change_color + +Return True if the programmer can change the colors displayed by the terminal. +[clinic start generated code]*/ + +static PyObject * +_curses_can_change_color_impl(PyObject *module) +/*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/ +NoArgTrueFalseFunctionBody(can_change_color) + +/*[clinic input] +_curses.cbreak + + flag: bool(accept={int}) = True + If false, the effect is the same as calling nocbreak(). + / + +Enter cbreak mode. + +In cbreak mode (sometimes called "rare" mode) normal tty line buffering is +turned off and characters are available to be read one by one. However, +unlike raw mode, special characters (interrupt, quit, suspend, and flow +control) retain their effects on the tty driver and calling program. +Calling first raw() then cbreak() leaves the terminal in cbreak mode. +[clinic start generated code]*/ + +static PyObject * +_curses_cbreak_impl(PyObject *module, int flag) +/*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ +NoArgOrFlagNoReturnFunctionBody(cbreak, flag) + +/*[clinic input] +_curses.color_content + + color_number: short + The number of the color (0 - COLORS). + / + +Return the red, green, and blue (RGB) components of the specified color. + +A 3-tuple is returned, containing the R, G, B values for the given color, +which will be between 0 (no component) and 1000 (maximum amount of component). +[clinic start generated code]*/ + static PyObject * -PyCurses_Color_Content(PyObject *self, PyObject *args) +_curses_color_content_impl(PyObject *module, short color_number) +/*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/ { - short color,r,g,b; + short r,g,b; PyCursesInitialised; PyCursesInitialisedColor; - if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL; - - if (color_content(color, &r, &g, &b) != ERR) + if (color_content(color_number, &r, &g, &b) != ERR) return Py_BuildValue("(iii)", r, g, b); else { PyErr_SetString(PyCursesError, @@ -2195,47 +2601,155 @@ PyCurses_Color_Content(PyObject *self, PyObject *args) } } +/*[clinic input] +_curses.color_pair + + color_number: short + The number of the color (0 - COLORS). + / + +Return the attribute value for displaying text in the specified color. + +This attribute value can be combined with A_STANDOUT, A_REVERSE, and the +other A_* attributes. pair_number() is the counterpart to this function. +[clinic start generated code]*/ + static PyObject * -PyCurses_color_pair(PyObject *self, PyObject *args) +_curses_color_pair_impl(PyObject *module, short color_number) +/*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/ { - int n; - PyCursesInitialised; PyCursesInitialisedColor; - if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL; - return PyLong_FromLong((long) (n << 8)); + return PyLong_FromLong((long) (color_number << 8)); } +/*[clinic input] +_curses.curs_set + + visibility: int + 0 for invisible, 1 for normal visible, or 2 for very visible. + / + +Set the cursor state. + +If the terminal supports the visibility requested, the previous cursor +state is returned; otherwise, an exception is raised. On many terminals, +the "visible" mode is an underline cursor and the "very visible" mode is +a block cursor. +[clinic start generated code]*/ + static PyObject * -PyCurses_Curs_Set(PyObject *self, PyObject *args) +_curses_curs_set_impl(PyObject *module, int visibility) +/*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/ { - int vis,erg; + int erg; PyCursesInitialised; - if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL; - - erg = curs_set(vis); + erg = curs_set(visibility); if (erg == ERR) return PyCursesCheckERR(erg, "curs_set"); return PyLong_FromLong((long) erg); } +/*[clinic input] +_curses.def_prog_mode + +Save the current terminal mode as the "program" mode. + +The "program" mode is the mode when the running program is using curses. + +Subsequent calls to reset_prog_mode() will restore this mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_Delay_Output(PyObject *self, PyObject *args) -{ - int ms; +_curses_def_prog_mode_impl(PyObject *module) +/*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/ +NoArgNoReturnFunctionBody(def_prog_mode) - PyCursesInitialised; +/*[clinic input] +_curses.def_shell_mode + +Save the current terminal mode as the "shell" mode. + +The "shell" mode is the mode when the running program is not using curses. + +Subsequent calls to reset_shell_mode() will restore this mode. +[clinic start generated code]*/ + +static PyObject * +_curses_def_shell_mode_impl(PyObject *module) +/*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/ +NoArgNoReturnFunctionBody(def_shell_mode) + +/*[clinic input] +_curses.delay_output + + ms: int + Duration in milliseconds. + / + +Insert a pause in output. +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL; +static PyObject * +_curses_delay_output_impl(PyObject *module, int ms) +/*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/ +{ + PyCursesInitialised; return PyCursesCheckERR(delay_output(ms), "delay_output"); } +/*[clinic input] +_curses.doupdate + +Update the physical screen to match the virtual screen. +[clinic start generated code]*/ + +static PyObject * +_curses_doupdate_impl(PyObject *module) +/*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/ +NoArgNoReturnFunctionBody(doupdate) + +/*[clinic input] +_curses.echo + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noecho(). + / + +Enter echo mode. + +In echo mode, each character input is echoed to the screen as it is entered. +[clinic start generated code]*/ + +static PyObject * +_curses_echo_impl(PyObject *module, int flag) +/*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ +NoArgOrFlagNoReturnFunctionBody(echo, flag) + +/*[clinic input] +_curses.endwin + +De-initialize the library, and return terminal to normal status. +[clinic start generated code]*/ + +static PyObject * +_curses_endwin_impl(PyObject *module) +/*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/ +NoArgNoReturnFunctionBody(endwin) + +/*[clinic input] +_curses.erasechar + +Return the user's current erase character. +[clinic start generated code]*/ + static PyObject * -PyCurses_EraseChar(PyObject *self) +_curses_erasechar_impl(PyObject *module) +/*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/ { char ch; @@ -2246,9 +2760,45 @@ PyCurses_EraseChar(PyObject *self) return PyBytes_FromStringAndSize(&ch, 1); } +/*[clinic input] +_curses.flash + +Flash the screen. + +That is, change it to reverse-video and then change it back in a short interval. +[clinic start generated code]*/ + +static PyObject * +_curses_flash_impl(PyObject *module) +/*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/ +NoArgNoReturnFunctionBody(flash) + +/*[clinic input] +_curses.flushinp + +Flush all input buffers. + +This throws away any typeahead that has been typed by the user and has not +yet been processed by the program. +[clinic start generated code]*/ + +static PyObject * +_curses_flushinp_impl(PyObject *module) +/*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/ +NoArgNoReturnVoidFunctionBody(flushinp) + #ifdef getsyx +/*[clinic input] +_curses.getsyx + +Return the current coordinates of the virtual screen cursor. + +Return a (y, x) tuple. If leaveok is currently true, return (-1, -1). +[clinic start generated code]*/ + static PyObject * -PyCurses_getsyx(PyObject *self) +_curses_getsyx_impl(PyObject *module) +/*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/ { int x = 0; int y = 0; @@ -2262,8 +2812,18 @@ PyCurses_getsyx(PyObject *self) #endif #ifdef NCURSES_MOUSE_VERSION +/*[clinic input] +_curses.getmouse + +Retrieve the queued mouse event. + +After getch() returns KEY_MOUSE to signal a mouse event, this function +returns a 5-tuple (id, x, y, z, bstate). +[clinic start generated code]*/ + static PyObject * -PyCurses_GetMouse(PyObject *self) +_curses_getmouse_impl(PyObject *module) +/*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/ { int rtn; MEVENT event; @@ -2281,18 +2841,29 @@ PyCurses_GetMouse(PyObject *self) (unsigned long) event.bstate); } +/*[clinic input] +_curses.ungetmouse + + id: short + x: int + y: int + z: int + bstate: unsigned_long(bitwise=True) + / + +Push a KEY_MOUSE event onto the input queue. + +The following getmouse() will return the given state data. +[clinic start generated code]*/ + static PyObject * -PyCurses_UngetMouse(PyObject *self, PyObject *args) +_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, + unsigned long bstate) +/*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/ { MEVENT event; - short id; - int x, y, z; - unsigned long bstate; PyCursesInitialised; - if (!PyArg_ParseTuple(args, "hiiik", - &id, &x, &y, &z, &bstate)) - return NULL; event.id = id; event.x = x; @@ -2303,8 +2874,21 @@ PyCurses_UngetMouse(PyObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.getwin + + file: object + / + +Read window related data stored in the file by an earlier putwin() call. + +The routine then creates and initializes a new window using that data, +returning the new window object. +[clinic start generated code]*/ + static PyObject * -PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) +_curses_getwin(PyObject *module, PyObject *file) +/*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/ { FILE *fp; PyObject *data; @@ -2322,8 +2906,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto error; - - data = _PyObject_CallMethodId(stream, &PyId_read, NULL); + data = _PyObject_CallMethodId(file, &PyId_read, NULL); if (data == NULL) goto error; if (!PyBytes_Check(data)) { @@ -2354,82 +2937,158 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) return res; } +/*[clinic input] +_curses.halfdelay + + tenths: byte + Maximal blocking delay in tenths of seconds (1 - 255). + / + +Enter half-delay mode. + +Use nocbreak() to leave half-delay mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_HalfDelay(PyObject *self, PyObject *args) +_curses_halfdelay_impl(PyObject *module, unsigned char tenths) +/*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/ { - unsigned char tenths; - PyCursesInitialised; - if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL; - return PyCursesCheckERR(halfdelay(tenths), "halfdelay"); } +/*[clinic input] +_curses.has_colors + +Return True if the terminal can display colors; otherwise, return False. +[clinic start generated code]*/ + +static PyObject * +_curses_has_colors_impl(PyObject *module) +/*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/ +NoArgTrueFalseFunctionBody(has_colors) + +/*[clinic input] +_curses.has_ic + +Return True if the terminal has insert- and delete-character capabilities. +[clinic start generated code]*/ + +static PyObject * +_curses_has_ic_impl(PyObject *module) +/*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/ +NoArgTrueFalseFunctionBody(has_ic) + +/*[clinic input] +_curses.has_il + +Return True if the terminal has insert- and delete-line capabilities. +[clinic start generated code]*/ + +static PyObject * +_curses_has_il_impl(PyObject *module) +/*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/ +NoArgTrueFalseFunctionBody(has_il) + #ifdef HAVE_CURSES_HAS_KEY +/*[clinic input] +_curses.has_key + + key: int + Key number. + / + +Return True if the current terminal type recognizes a key with that value. +[clinic start generated code]*/ + static PyObject * -PyCurses_has_key(PyObject *self, PyObject *args) +_curses_has_key_impl(PyObject *module, int key) +/*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/ { - int ch; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i",&ch)) return NULL; - - if (has_key(ch) == FALSE) { - Py_RETURN_FALSE; - } - Py_RETURN_TRUE; + return PyBool_FromLong(has_key(key)); } #endif +/*[clinic input] +_curses.init_color + + color_number: short + The number of the color to be changed (0 - COLORS). + r: short + Red component (0 - 1000). + g: short + Green component (0 - 1000). + b: short + Blue component (0 - 1000). + / + +Change the definition of a color. + +When init_color() is used, all occurrences of that color on the screen +immediately change to the new definition. This function is a no-op on +most terminals; it is active only if can_change_color() returns 1. +[clinic start generated code]*/ + static PyObject * -PyCurses_Init_Color(PyObject *self, PyObject *args) +_curses_init_color_impl(PyObject *module, short color_number, short r, + short g, short b) +/*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/ { - short color, r, g, b; - PyCursesInitialised; PyCursesInitialisedColor; - switch(PyTuple_Size(args)) { - case 4: - if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments"); - return NULL; - } - - return PyCursesCheckERR(init_color(color, r, g, b), "init_color"); + return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color"); } +/*[clinic input] +_curses.init_pair + + pair_number: short + The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)). + fg: short + Foreground color number (0 - COLORS). + bg: short + Background color number (0 - COLORS). + / + +Change the definition of a color-pair. + +If the color-pair was previously initialized, the screen is refreshed and +all occurrences of that color-pair are changed to the new definition. +[clinic start generated code]*/ + static PyObject * -PyCurses_Init_Pair(PyObject *self, PyObject *args) +_curses_init_pair_impl(PyObject *module, short pair_number, short fg, + short bg) +/*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/ { - short pair, f, b; - PyCursesInitialised; PyCursesInitialisedColor; - if (PyTuple_Size(args) != 3) { - PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL; - - return PyCursesCheckERR(init_pair(pair, f, b), "init_pair"); + return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair"); } static PyObject *ModDict; +/*[clinic input] +_curses.initscr + +Initialize the library. + +Return a WindowObject which represents the whole screen. +[clinic start generated code]*/ + static PyObject * -PyCurses_InitScr(PyObject *self) +_curses_initscr_impl(PyObject *module) +/*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/ { WINDOW *win; PyCursesWindowObject *winobj; - if (initialised == TRUE) { + if (initialised) { wrefresh(stdscr); return (PyObject *)PyCursesWindow_New(stdscr, NULL); } @@ -2528,19 +3187,24 @@ PyCurses_InitScr(PyObject *self) return (PyObject *)winobj; } +/*[clinic input] +_curses.setupterm + + term: str(accept={str, NoneType}) = NULL + Terminal name. + If omitted, the value of the TERM environment variable will be used. + fd: int = -1 + File descriptor to which any initialization sequences will be sent. + If not supplied, the file descriptor for sys.stdout will be used. + +Initialize the terminal. +[clinic start generated code]*/ + static PyObject * -PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) +_curses_setupterm_impl(PyObject *module, const char *term, int fd) +/*[clinic end generated code: output=4584e587350f2848 input=8ac5f78ec6268be3]*/ { - int fd = -1; int err; - char* termstr = NULL; - - static char *kwlist[] = {"term", "fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords( - args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) { - return NULL; - } if (fd == -1) { PyObject* sys_stdout; @@ -2561,7 +3225,7 @@ PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) } } - if (!initialised_setupterm && setupterm(termstr,fd,&err) == ERR) { + if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) { const char* s = "setupterm: unknown error"; if (err == 0) { @@ -2579,67 +3243,93 @@ PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds) Py_RETURN_NONE; } +/*[clinic input] +_curses.intrflush + + flag: bool(accept={int}) + / + +[clinic start generated code]*/ + static PyObject * -PyCurses_IntrFlush(PyObject *self, PyObject *args) +_curses_intrflush_impl(PyObject *module, int flag) +/*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ { - int ch; - PyCursesInitialised; - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument"); - return NULL; - } - - return PyCursesCheckERR(intrflush(NULL,ch), "intrflush"); + return PyCursesCheckERR(intrflush(NULL, flag), "intrflush"); } +/*[clinic input] +_curses.isendwin + +Return True if endwin() has been called. +[clinic start generated code]*/ + +static PyObject * +_curses_isendwin_impl(PyObject *module) +/*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/ +NoArgTrueFalseFunctionBody(isendwin) + #ifdef HAVE_CURSES_IS_TERM_RESIZED +/*[clinic input] +_curses.is_term_resized + + nlines: int + Height. + ncols: int + Width. + / + +Return True if resize_term() would modify the window structure, False otherwise. +[clinic start generated code]*/ + static PyObject * -PyCurses_Is_Term_Resized(PyObject *self, PyObject *args) +_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/ { - int lines; - int columns; - int result; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns)) - return NULL; - result = is_term_resized(lines, columns); - if (result == TRUE) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + return PyBool_FromLong(is_term_resized(nlines, ncols)); } #endif /* HAVE_CURSES_IS_TERM_RESIZED */ +/*[clinic input] +_curses.keyname + + key: int + Key number. + / + +Return the name of specified key. +[clinic start generated code]*/ + static PyObject * -PyCurses_KeyName(PyObject *self, PyObject *args) +_curses_keyname_impl(PyObject *module, int key) +/*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/ { const char *knp; - int ch; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i",&ch)) return NULL; - - if (ch < 0) { + if (key < 0) { PyErr_SetString(PyExc_ValueError, "invalid key number"); return NULL; } - knp = keyname(ch); + knp = keyname(key); return PyBytes_FromString((knp == NULL) ? "" : knp); } +/*[clinic input] +_curses.killchar + +Return the user's current line kill character. +[clinic start generated code]*/ + static PyObject * -PyCurses_KillChar(PyObject *self) +_curses_killchar_impl(PyObject *module) +/*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/ { char ch; @@ -2648,74 +3338,132 @@ PyCurses_KillChar(PyObject *self) return PyBytes_FromStringAndSize(&ch, 1); } +/*[clinic input] +_curses.longname + +Return the terminfo long name field describing the current terminal. + +The maximum length of a verbose description is 128 characters. It is defined +only after the call to initscr(). +[clinic start generated code]*/ + static PyObject * -PyCurses_Meta(PyObject *self, PyObject *args) -{ - int ch; +_curses_longname_impl(PyObject *module) +/*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/ +NoArgReturnStringFunctionBody(longname) - PyCursesInitialised; +/*[clinic input] +_curses.meta - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "meta requires 1 argument"); - return NULL; - } + yes: bool(accept={int}) + / + +Enable/disable meta keys. + +If yes is True, allow 8-bit characters to be input. If yes is False, +allow only 7-bit characters. +[clinic start generated code]*/ - return PyCursesCheckERR(meta(stdscr, ch), "meta"); +static PyObject * +_curses_meta_impl(PyObject *module, int yes) +/*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ +{ + PyCursesInitialised; + + return PyCursesCheckERR(meta(stdscr, yes), "meta"); } #ifdef NCURSES_MOUSE_VERSION +/*[clinic input] +_curses.mouseinterval + + interval: int + Time in milliseconds. + / + +Set and retrieve the maximum time between press and release in a click. + +Set the maximum time that can elapse between press and release events in +order for them to be recognized as a click, and return the previous interval +value. +[clinic start generated code]*/ + static PyObject * -PyCurses_MouseInterval(PyObject *self, PyObject *args) +_curses_mouseinterval_impl(PyObject *module, int interval) +/*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/ { - int interval; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i;interval",&interval)) - return NULL; return PyCursesCheckERR(mouseinterval(interval), "mouseinterval"); } +/*[clinic input] +_curses.mousemask + + newmask: unsigned_long(bitwise=True) + / + +Set the mouse events to be reported, and return a tuple (availmask, oldmask). + +Return a tuple (availmask, oldmask). availmask indicates which of the +specified mouse events can be reported; on complete failure it returns 0. +oldmask is the previous value of the given window's mouse event mask. +If this function is never called, no mouse events are ever reported. +[clinic start generated code]*/ + static PyObject * -PyCurses_MouseMask(PyObject *self, PyObject *args) +_curses_mousemask_impl(PyObject *module, unsigned long newmask) +/*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/ { - unsigned long newmask; mmask_t oldmask, availmask; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"k;mousemask",&newmask)) - return NULL; availmask = mousemask((mmask_t)newmask, &oldmask); return Py_BuildValue("(kk)", (unsigned long)availmask, (unsigned long)oldmask); } #endif +/*[clinic input] +_curses.napms + + ms: int + Duration in milliseconds. + / + +Sleep for specified time. +[clinic start generated code]*/ + static PyObject * -PyCurses_Napms(PyObject *self, PyObject *args) +_curses_napms_impl(PyObject *module, int ms) +/*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/ { - int ms; - PyCursesInitialised; - if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL; return Py_BuildValue("i", napms(ms)); } +/*[clinic input] +_curses.newpad + + nlines: int + Height. + ncols: int + Width. + / + +Create and return a pointer to a new pad data structure. +[clinic start generated code]*/ + static PyObject * -PyCurses_NewPad(PyObject *self, PyObject *args) +_curses_newpad_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/ { WINDOW *win; - int nlines, ncols; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL; - win = newpad(nlines, ncols); if (win == NULL) { @@ -2726,29 +3474,36 @@ PyCurses_NewPad(PyObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } +/*[clinic input] +_curses.newwin + + nlines: int + Height. + ncols: int + Width. + [ + begin_y: int = 0 + Top side y-coordinate. + begin_x: int = 0 + Left side x-coordinate. + ] + / + +Return a new window. + +By default, the window will extend from the specified position to the lower +right corner of the screen. +[clinic start generated code]*/ + static PyObject * -PyCurses_NewWindow(PyObject *self, PyObject *args) +_curses_newwin_impl(PyObject *module, int nlines, int ncols, + int group_right_1, int begin_y, int begin_x) +/*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/ { WINDOW *win; - int nlines, ncols, begin_y=0, begin_x=0; PyCursesInitialised; - switch (PyTuple_Size(args)) { - case 2: - if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) - return NULL; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x", - &nlines,&ncols,&begin_y,&begin_x)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments"); - return NULL; - } - win = newwin(nlines,ncols,begin_y,begin_x); if (win == NULL) { PyErr_SetString(PyCursesError, catchall_NULL); @@ -2758,24 +3513,111 @@ PyCurses_NewWindow(PyObject *self, PyObject *args) return (PyObject *)PyCursesWindow_New(win, NULL); } +/*[clinic input] +_curses.nl + + flag: bool(accept={int}) = True + If false, the effect is the same as calling nonl(). + / + +Enter newline mode. + +This mode translates the return key into newline on input, and translates +newline into return and line-feed on output. Newline mode is initially on. +[clinic start generated code]*/ + static PyObject * -PyCurses_Pair_Content(PyObject *self, PyObject *args) -{ - short pair,f,b; +_curses_nl_impl(PyObject *module, int flag) +/*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ +NoArgOrFlagNoReturnFunctionBody(nl, flag) - PyCursesInitialised; - PyCursesInitialisedColor; +/*[clinic input] +_curses.nocbreak - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument"); - return NULL; - } +Leave cbreak mode. + +Return to normal "cooked" mode with line buffering. +[clinic start generated code]*/ + +static PyObject * +_curses_nocbreak_impl(PyObject *module) +/*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/ +NoArgNoReturnFunctionBody(nocbreak) + +/*[clinic input] +_curses.noecho + +Leave echo mode. + +Echoing of input characters is turned off. +[clinic start generated code]*/ + +static PyObject * +_curses_noecho_impl(PyObject *module) +/*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/ +NoArgNoReturnFunctionBody(noecho) + +/*[clinic input] +_curses.nonl + +Leave newline mode. + +Disable translation of return into newline on input, and disable low-level +translation of newline into newline/return on output. +[clinic start generated code]*/ + +static PyObject * +_curses_nonl_impl(PyObject *module) +/*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/ +NoArgNoReturnFunctionBody(nonl) + +/*[clinic input] +_curses.noqiflush + +Disable queue flushing. + +When queue flushing is disabled, normal flush of input and output queues +associated with the INTR, QUIT and SUSP characters will not be done. +[clinic start generated code]*/ + +static PyObject * +_curses_noqiflush_impl(PyObject *module) +/*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/ +NoArgNoReturnVoidFunctionBody(noqiflush) + +/*[clinic input] +_curses.noraw + +Leave raw mode. + +Return to normal "cooked" mode with line buffering. +[clinic start generated code]*/ + +static PyObject * +_curses_noraw_impl(PyObject *module) +/*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/ +NoArgNoReturnFunctionBody(noraw) + +/*[clinic input] +_curses.pair_content + + pair_number: short + The number of the color pair (1 - (COLOR_PAIRS-1)). + / + +Return a tuple (fg, bg) containing the colors for the requested color pair. +[clinic start generated code]*/ + +static PyObject * +_curses_pair_content_impl(PyObject *module, short pair_number) +/*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/ +{ + short f, b; + + PyCursesInitialised; + PyCursesInitialisedColor; - if (pair_content(pair, &f, &b)==ERR) { + if (pair_content(pair_number, &f, &b)==ERR) { PyErr_SetString(PyCursesError, "Argument 1 was out of range. (1..COLOR_PAIRS-1)"); return NULL; @@ -2784,57 +3626,71 @@ PyCurses_Pair_Content(PyObject *self, PyObject *args) return Py_BuildValue("(ii)", f, b); } +/*[clinic input] +_curses.pair_number + + attr: int + / + +Return the number of the color-pair set by the specified attribute value. + +color_pair() is the counterpart to this function. +[clinic start generated code]*/ + static PyObject * -PyCurses_pair_number(PyObject *self, PyObject *args) +_curses_pair_number_impl(PyObject *module, int attr) +/*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/ { - int n; - PyCursesInitialised; PyCursesInitialisedColor; - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, - "pair_number requires 1 argument"); - return NULL; - } - - return PyLong_FromLong((long) ((n & A_COLOR) >> 8)); + return PyLong_FromLong((long) ((attr & A_COLOR) >> 8)); } +/*[clinic input] +_curses.putp + + string: str(accept={robuffer}) + / + +Emit the value of a specified terminfo capability for the current terminal. + +Note that the output of putp() always goes to standard output. +[clinic start generated code]*/ + static PyObject * -PyCurses_Putp(PyObject *self, PyObject *args) +_curses_putp_impl(PyObject *module, const char *string) +/*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/ { - char *str; - - if (!PyArg_ParseTuple(args,"y;str", &str)) - return NULL; - return PyCursesCheckERR(putp(str), "putp"); + return PyCursesCheckERR(putp(string), "putp"); } +/*[clinic input] +_curses.qiflush + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noqiflush(). + / + +Enable queue flushing. + +If queue flushing is enabled, all output in the display driver queue +will be flushed when the INTR, QUIT and SUSP characters are read. +[clinic start generated code]*/ + static PyObject * -PyCurses_QiFlush(PyObject *self, PyObject *args) +_curses_qiflush_impl(PyObject *module, int flag) +/*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ { - int flag = 0; - PyCursesInitialised; - switch(PyTuple_Size(args)) { - case 0: + if (flag) { qiflush(); - Py_RETURN_NONE; - case 1: - if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; - if (flag) qiflush(); - else noqiflush(); - Py_RETURN_NONE; - default: - PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments"); - return NULL; } + else { + noqiflush(); + } + Py_RETURN_NONE; } /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES @@ -2888,28 +3744,97 @@ update_lines_cols(void) return 1; } -static PyObject * -PyCurses_update_lines_cols(PyObject *self) +/*[clinic input] +_curses.update_lines_cols -> int + +[clinic start generated code]*/ + +static int +_curses_update_lines_cols_impl(PyObject *module) +/*[clinic end generated code: output=0345e7f072ea711a input=3a87760f7d5197f0]*/ { - return PyLong_FromLong((long) update_lines_cols()); + return update_lines_cols(); } #endif +/*[clinic input] +_curses.raw + + flag: bool(accept={int}) = True + If false, the effect is the same as calling noraw(). + / + +Enter raw mode. + +In raw mode, normal line buffering and processing of interrupt, quit, +suspend, and flow control keys are turned off; characters are presented to +curses input functions one by one. +[clinic start generated code]*/ + +static PyObject * +_curses_raw_impl(PyObject *module, int flag) +/*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ +NoArgOrFlagNoReturnFunctionBody(raw, flag) + +/*[clinic input] +_curses.reset_prog_mode + +Restore the terminal to "program" mode, as previously saved by def_prog_mode(). +[clinic start generated code]*/ + +static PyObject * +_curses_reset_prog_mode_impl(PyObject *module) +/*[clinic end generated code: output=15eb765abf0b6575 input=3d82bea2b3243471]*/ +NoArgNoReturnFunctionBody(reset_prog_mode) + +/*[clinic input] +_curses.reset_shell_mode + +Restore the terminal to "shell" mode, as previously saved by def_shell_mode(). +[clinic start generated code]*/ + +static PyObject * +_curses_reset_shell_mode_impl(PyObject *module) +/*[clinic end generated code: output=0238de2962090d33 input=1c738fa64bd1a24f]*/ +NoArgNoReturnFunctionBody(reset_shell_mode) + +/*[clinic input] +_curses.resetty + +Restore terminal mode. +[clinic start generated code]*/ + +static PyObject * +_curses_resetty_impl(PyObject *module) +/*[clinic end generated code: output=ff4b448e80a7cd63 input=940493de03624bb0]*/ +NoArgNoReturnFunctionBody(resetty) + #ifdef HAVE_CURSES_RESIZETERM +/*[clinic input] +_curses.resizeterm + + nlines: int + Height. + ncols: int + Width. + / + +Resize the standard and current windows to the specified dimensions. + +Adjusts other bookkeeping data used by the curses library that record the +window dimensions (in particular the SIGWINCH handler). +[clinic start generated code]*/ + static PyObject * -PyCurses_ResizeTerm(PyObject *self, PyObject *args) +_curses_resizeterm_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/ { - int lines; - int columns; PyObject *result; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns)) - return NULL; - - result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm"); + result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); if (!result) return NULL; if (!update_lines_cols()) @@ -2920,20 +3845,33 @@ PyCurses_ResizeTerm(PyObject *self, PyObject *args) #endif #ifdef HAVE_CURSES_RESIZE_TERM +/*[clinic input] +_curses.resize_term + + nlines: int + Height. + ncols: int + Width. + / + +Backend function used by resizeterm(), performing most of the work. + +When resizing the windows, resize_term() blank-fills the areas that are +extended. The calling application should fill in these areas with appropriate +data. The resize_term() function attempts to resize all windows. However, +due to the calling convention of pads, it is not possible to resize these +without additional interaction with the application. +[clinic start generated code]*/ + static PyObject * -PyCurses_Resize_Term(PyObject *self, PyObject *args) +_curses_resize_term_impl(PyObject *module, int nlines, int ncols) +/*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/ { - int lines; - int columns; - PyObject *result; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns)) - return NULL; - - result = PyCursesCheckERR(resize_term(lines, columns), "resize_term"); + result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); if (!result) return NULL; if (!update_lines_cols()) @@ -2942,20 +3880,37 @@ PyCurses_Resize_Term(PyObject *self, PyObject *args) } #endif /* HAVE_CURSES_RESIZE_TERM */ -#ifdef getsyx +/*[clinic input] +_curses.savetty + +Save terminal mode. +[clinic start generated code]*/ + static PyObject * -PyCurses_setsyx(PyObject *self, PyObject *args) -{ - int y,x; +_curses_savetty_impl(PyObject *module) +/*[clinic end generated code: output=6babc49f12b42199 input=fce6b2b7d2200102]*/ +NoArgNoReturnFunctionBody(savetty) - PyCursesInitialised; +#ifdef getsyx +/*[clinic input] +_curses.setsyx - if (PyTuple_Size(args)!=2) { - PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments"); - return NULL; - } + y: int + Y-coordinate. + x: int + X-coordinate. + / + +Set the virtual screen cursor. + +If y and x are both -1, then leaveok is set. +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL; +static PyObject * +_curses_setsyx_impl(PyObject *module, int y, int x) +/*[clinic end generated code: output=23dcf753511a2464 input=fa7f2b208e10a557]*/ +{ + PyCursesInitialised; setsyx(y,x); @@ -2963,8 +3918,22 @@ PyCurses_setsyx(PyObject *self, PyObject *args) } #endif +/*[clinic input] +_curses.start_color + +Initializes eight basic colors and global variables COLORS and COLOR_PAIRS. + +Must be called if the programmer wants to use colors, and before any other +color manipulation routine is called. It is good practice to call this +routine right after initscr(). + +It also restores the colors on the terminal to the values they had when the +terminal was just turned on. +[clinic start generated code]*/ + static PyObject * -PyCurses_Start_Color(PyObject *self) +_curses_start_color_impl(PyObject *module) +/*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/ { int code; PyObject *c, *cp; @@ -2991,42 +3960,91 @@ PyCurses_Start_Color(PyObject *self) } } +/*[clinic input] +_curses.termattrs + +Return a logical OR of all video attributes supported by the terminal. +[clinic start generated code]*/ + static PyObject * -PyCurses_tigetflag(PyObject *self, PyObject *args) -{ - char *capname; +_curses_termattrs_impl(PyObject *module) +/*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/ +NoArgReturnIntFunctionBody(termattrs) - PyCursesSetupTermCalled; +/*[clinic input] +_curses.termname - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; +Return the value of the environment variable TERM, truncated to 14 characters. +[clinic start generated code]*/ + +static PyObject * +_curses_termname_impl(PyObject *module) +/*[clinic end generated code: output=96375577ebbd67fd input=33c08d000944f33f]*/ +NoArgReturnStringFunctionBody(termname) + +/*[clinic input] +_curses.tigetflag + + capname: str + The terminfo capability name. + / + +Return the value of the Boolean capability. + +The value -1 is returned if capname is not a Boolean capability, or 0 if +it is canceled or absent from the terminal description. +[clinic start generated code]*/ + +static PyObject * +_curses_tigetflag_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=8853c0e55542195b input=b0787af9e3e9a6ce]*/ +{ + PyCursesSetupTermCalled; return PyLong_FromLong( (long) tigetflag( capname ) ); } +/*[clinic input] +_curses.tigetnum + + capname: str + The terminfo capability name. + / + +Return the value of the numeric capability. + +The value -2 is returned if capname is not a numeric capability, or -1 if +it is canceled or absent from the terminal description. +[clinic start generated code]*/ + static PyObject * -PyCurses_tigetnum(PyObject *self, PyObject *args) +_curses_tigetnum_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/ { - char *capname; - PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; - return PyLong_FromLong( (long) tigetnum( capname ) ); } +/*[clinic input] +_curses.tigetstr + + capname: str + The terminfo capability name. + / + +Return the value of the string capability. + +None is returned if capname is not a string capability, or is canceled or +absent from the terminal description. +[clinic start generated code]*/ + static PyObject * -PyCurses_tigetstr(PyObject *self, PyObject *args) +_curses_tigetstr_impl(PyObject *module, const char *capname) +/*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/ { - char *capname; - PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "s", &capname)) - return NULL; - capname = tigetstr( capname ); if (capname == NULL || capname == (char*) -1) { Py_RETURN_NONE; @@ -3034,22 +4052,35 @@ PyCurses_tigetstr(PyObject *self, PyObject *args) return PyBytes_FromString( capname ); } +/*[clinic input] +_curses.tparm + + str: str(accept={robuffer}) + Parameterized byte string obtained from the terminfo database. + i1: int = 0 + i2: int = 0 + i3: int = 0 + i4: int = 0 + i5: int = 0 + i6: int = 0 + i7: int = 0 + i8: int = 0 + i9: int = 0 + / + +Instantiate the specified byte string with the supplied parameters. +[clinic start generated code]*/ + static PyObject * -PyCurses_tparm(PyObject *self, PyObject *args) +_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, + int i4, int i5, int i6, int i7, int i8, int i9) +/*[clinic end generated code: output=599f62b615c667ff input=5e30b15786f032aa]*/ { - char* fmt; char* result = NULL; - int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0; PyCursesSetupTermCalled; - if (!PyArg_ParseTuple(args, "y|iiiiiiiii:tparm", - &fmt, &i1, &i2, &i3, &i4, - &i5, &i6, &i7, &i8, &i9)) { - return NULL; - } - - result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9); + result = tparm(str,i1,i2,i3,i4,i5,i6,i7,i8,i9); if (!result) { PyErr_SetString(PyCursesError, "tparm() returned NULL"); return NULL; @@ -3059,50 +4090,75 @@ PyCurses_tparm(PyObject *self, PyObject *args) } #ifdef HAVE_CURSES_TYPEAHEAD +/*[clinic input] +_curses.typeahead + + fd: int + File descriptor. + / + +Specify that the file descriptor fd be used for typeahead checking. + +If fd is -1, then no typeahead checking is done. +[clinic start generated code]*/ + static PyObject * -PyCurses_TypeAhead(PyObject *self, PyObject *args) +_curses_typeahead_impl(PyObject *module, int fd) +/*[clinic end generated code: output=084bb649d7066583 input=f2968d8e1805051b]*/ { - int fd; - PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL; - return PyCursesCheckERR(typeahead( fd ), "typeahead"); } #endif +/*[clinic input] +_curses.unctrl + + ch: object + / + +Return a string which is a printable representation of the character ch. + +Control characters are displayed as a caret followed by the character, +for example as ^C. Printing characters are left as they are. +[clinic start generated code]*/ + static PyObject * -PyCurses_UnCtrl(PyObject *self, PyObject *args) +_curses_unctrl(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=8e07fafc430c9434 input=cd1e35e16cd1ace4]*/ { - PyObject *temp; - chtype ch; + chtype ch_; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL; - - if (!PyCurses_ConvertToChtype(NULL, temp, &ch)) + if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) return NULL; - return PyBytes_FromString(unctrl(ch)); + return PyBytes_FromString(unctrl(ch_)); } +/*[clinic input] +_curses.ungetch + + ch: object + / + +Push ch so the next getch() will return it. +[clinic start generated code]*/ + static PyObject * -PyCurses_UngetCh(PyObject *self, PyObject *args) +_curses_ungetch(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=9b19d8268376d887 input=6681e6ae4c42e5eb]*/ { - PyObject *temp; - chtype ch; + chtype ch_; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) - return NULL; - - if (!PyCurses_ConvertToChtype(NULL, temp, &ch)) + if (!PyCurses_ConvertToChtype(NULL, ch, &ch_)) return NULL; - return PyCursesCheckERR(ungetch(ch), "ungetch"); + return PyCursesCheckERR(ungetch(ch_), "ungetch"); } #ifdef HAVE_NCURSESW @@ -3153,46 +4209,70 @@ PyCurses_ConvertToWchar_t(PyObject *obj, } } +/*[clinic input] +_curses.unget_wch + + ch: object + / + +Push ch so the next get_wch() will return it. +[clinic start generated code]*/ + static PyObject * -PyCurses_Unget_Wch(PyObject *self, PyObject *args) +_curses_unget_wch(PyObject *module, PyObject *ch) +/*[clinic end generated code: output=1974c9fb01d37863 input=0d56dc65a46feebb]*/ { - PyObject *obj; wchar_t wch; PyCursesInitialised; - if (!PyArg_ParseTuple(args,"O", &obj)) - return NULL; - - if (!PyCurses_ConvertToWchar_t(obj, &wch)) + if (!PyCurses_ConvertToWchar_t(ch, &wch)) return NULL; return PyCursesCheckERR(unget_wch(wch), "unget_wch"); } #endif -#ifdef HAVE_CURSES_TYPEAHEAD +#ifdef HAVE_CURSES_USE_ENV +/*[clinic input] +_curses.use_env + + flag: bool(accept={int}) + / + +Use environment variables LINES and COLUMNS. + +If used, this function should be called before initscr() or newterm() are +called. + +When flag is False, the values of lines and columns specified in the terminfo +database will be used, even if environment variables LINES and COLUMNS (used +by default) are set, or if curses is running in a window (in which case +default behavior would be to use the window size if LINES and COLUMNS are +not set). +[clinic start generated code]*/ + static PyObject * -PyCurses_Use_Env(PyObject *self, PyObject *args) +_curses_use_env_impl(PyObject *module, int flag) +/*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ { - int flag; - - switch(PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag)) - return NULL; - break; - default: - PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument"); - return NULL; - } use_env(flag); Py_RETURN_NONE; } #endif #ifndef STRICT_SYSV_CURSES +/*[clinic input] +_curses.use_default_colors + +Allow use of default values for colors on terminals supporting this feature. + +Use this to support transparency in your application. The default color +is assigned to the color number -1. +[clinic start generated code]*/ + static PyObject * -PyCurses_Use_Default_Colors(PyObject *self) +_curses_use_default_colors_impl(PyObject *module) +/*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/ { int code; @@ -3212,109 +4292,80 @@ PyCurses_Use_Default_Colors(PyObject *self) /* List of functions defined in the module */ static PyMethodDef PyCurses_methods[] = { - {"baudrate", (PyCFunction)PyCurses_baudrate, METH_NOARGS}, - {"beep", (PyCFunction)PyCurses_beep, METH_NOARGS}, - {"can_change_color", (PyCFunction)PyCurses_can_change_color, METH_NOARGS}, - {"cbreak", (PyCFunction)PyCurses_cbreak, METH_VARARGS}, - {"color_content", (PyCFunction)PyCurses_Color_Content, METH_VARARGS}, - {"color_pair", (PyCFunction)PyCurses_color_pair, METH_VARARGS}, - {"curs_set", (PyCFunction)PyCurses_Curs_Set, METH_VARARGS}, - {"def_prog_mode", (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS}, - {"def_shell_mode", (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS}, - {"delay_output", (PyCFunction)PyCurses_Delay_Output, METH_VARARGS}, - {"doupdate", (PyCFunction)PyCurses_doupdate, METH_NOARGS}, - {"echo", (PyCFunction)PyCurses_echo, METH_VARARGS}, - {"endwin", (PyCFunction)PyCurses_endwin, METH_NOARGS}, - {"erasechar", (PyCFunction)PyCurses_EraseChar, METH_NOARGS}, -#ifdef HAVE_CURSES_FILTER - {"filter", (PyCFunction)PyCurses_filter, METH_NOARGS}, -#endif - {"flash", (PyCFunction)PyCurses_flash, METH_NOARGS}, - {"flushinp", (PyCFunction)PyCurses_flushinp, METH_NOARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"getmouse", (PyCFunction)PyCurses_GetMouse, METH_NOARGS}, - {"ungetmouse", (PyCFunction)PyCurses_UngetMouse, METH_VARARGS}, -#endif -#ifdef getsyx - {"getsyx", (PyCFunction)PyCurses_getsyx, METH_NOARGS}, -#endif - {"getwin", (PyCFunction)PyCurses_GetWin, METH_O}, - {"has_colors", (PyCFunction)PyCurses_has_colors, METH_NOARGS}, - {"has_ic", (PyCFunction)PyCurses_has_ic, METH_NOARGS}, - {"has_il", (PyCFunction)PyCurses_has_il, METH_NOARGS}, -#ifdef HAVE_CURSES_HAS_KEY - {"has_key", (PyCFunction)PyCurses_has_key, METH_VARARGS}, -#endif - {"halfdelay", (PyCFunction)PyCurses_HalfDelay, METH_VARARGS}, - {"init_color", (PyCFunction)PyCurses_Init_Color, METH_VARARGS}, - {"init_pair", (PyCFunction)PyCurses_Init_Pair, METH_VARARGS}, - {"initscr", (PyCFunction)PyCurses_InitScr, METH_NOARGS}, - {"intrflush", (PyCFunction)PyCurses_IntrFlush, METH_VARARGS}, - {"isendwin", (PyCFunction)PyCurses_isendwin, METH_NOARGS}, -#ifdef HAVE_CURSES_IS_TERM_RESIZED - {"is_term_resized", (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS}, -#endif - {"keyname", (PyCFunction)PyCurses_KeyName, METH_VARARGS}, - {"killchar", (PyCFunction)PyCurses_KillChar, METH_NOARGS}, - {"longname", (PyCFunction)PyCurses_longname, METH_NOARGS}, - {"meta", (PyCFunction)PyCurses_Meta, METH_VARARGS}, -#ifdef NCURSES_MOUSE_VERSION - {"mouseinterval", (PyCFunction)PyCurses_MouseInterval, METH_VARARGS}, - {"mousemask", (PyCFunction)PyCurses_MouseMask, METH_VARARGS}, -#endif - {"napms", (PyCFunction)PyCurses_Napms, METH_VARARGS}, - {"newpad", (PyCFunction)PyCurses_NewPad, METH_VARARGS}, - {"newwin", (PyCFunction)PyCurses_NewWindow, METH_VARARGS}, - {"nl", (PyCFunction)PyCurses_nl, METH_VARARGS}, - {"nocbreak", (PyCFunction)PyCurses_nocbreak, METH_NOARGS}, - {"noecho", (PyCFunction)PyCurses_noecho, METH_NOARGS}, - {"nonl", (PyCFunction)PyCurses_nonl, METH_NOARGS}, - {"noqiflush", (PyCFunction)PyCurses_noqiflush, METH_NOARGS}, - {"noraw", (PyCFunction)PyCurses_noraw, METH_NOARGS}, - {"pair_content", (PyCFunction)PyCurses_Pair_Content, METH_VARARGS}, - {"pair_number", (PyCFunction)PyCurses_pair_number, METH_VARARGS}, - {"putp", (PyCFunction)PyCurses_Putp, METH_VARARGS}, - {"qiflush", (PyCFunction)PyCurses_QiFlush, METH_VARARGS}, - {"raw", (PyCFunction)PyCurses_raw, METH_VARARGS}, - {"reset_prog_mode", (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS}, - {"reset_shell_mode", (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS}, - {"resetty", (PyCFunction)PyCurses_resetty, METH_NOARGS}, -#ifdef HAVE_CURSES_RESIZETERM - {"resizeterm", (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS}, -#endif -#ifdef HAVE_CURSES_RESIZE_TERM - {"resize_term", (PyCFunction)PyCurses_Resize_Term, METH_VARARGS}, -#endif - {"savetty", (PyCFunction)PyCurses_savetty, METH_NOARGS}, -#ifdef getsyx - {"setsyx", (PyCFunction)PyCurses_setsyx, METH_VARARGS}, -#endif - {"setupterm", (PyCFunction)PyCurses_setupterm, - METH_VARARGS|METH_KEYWORDS}, - {"start_color", (PyCFunction)PyCurses_Start_Color, METH_NOARGS}, - {"termattrs", (PyCFunction)PyCurses_termattrs, METH_NOARGS}, - {"termname", (PyCFunction)PyCurses_termname, METH_NOARGS}, - {"tigetflag", (PyCFunction)PyCurses_tigetflag, METH_VARARGS}, - {"tigetnum", (PyCFunction)PyCurses_tigetnum, METH_VARARGS}, - {"tigetstr", (PyCFunction)PyCurses_tigetstr, METH_VARARGS}, - {"tparm", (PyCFunction)PyCurses_tparm, METH_VARARGS}, -#ifdef HAVE_CURSES_TYPEAHEAD - {"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS}, -#endif - {"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS}, - {"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS}, -#if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) - {"update_lines_cols", (PyCFunction)PyCurses_update_lines_cols, METH_NOARGS}, -#endif -#ifdef HAVE_NCURSESW - {"unget_wch", (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS}, -#endif -#ifdef HAVE_CURSES_USE_ENV - {"use_env", (PyCFunction)PyCurses_Use_Env, METH_VARARGS}, -#endif -#ifndef STRICT_SYSV_CURSES - {"use_default_colors", (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS}, -#endif + _CURSES_BAUDRATE_METHODDEF + _CURSES_BEEP_METHODDEF + _CURSES_CAN_CHANGE_COLOR_METHODDEF + _CURSES_CBREAK_METHODDEF + _CURSES_COLOR_CONTENT_METHODDEF + _CURSES_COLOR_PAIR_METHODDEF + _CURSES_CURS_SET_METHODDEF + _CURSES_DEF_PROG_MODE_METHODDEF + _CURSES_DEF_SHELL_MODE_METHODDEF + _CURSES_DELAY_OUTPUT_METHODDEF + _CURSES_DOUPDATE_METHODDEF + _CURSES_ECHO_METHODDEF + _CURSES_ENDWIN_METHODDEF + _CURSES_ERASECHAR_METHODDEF + _CURSES_FILTER_METHODDEF + _CURSES_FLASH_METHODDEF + _CURSES_FLUSHINP_METHODDEF + _CURSES_GETMOUSE_METHODDEF + _CURSES_UNGETMOUSE_METHODDEF + _CURSES_GETSYX_METHODDEF + _CURSES_GETWIN_METHODDEF + _CURSES_HAS_COLORS_METHODDEF + _CURSES_HAS_IC_METHODDEF + _CURSES_HAS_IL_METHODDEF + _CURSES_HAS_KEY_METHODDEF + _CURSES_HALFDELAY_METHODDEF + _CURSES_INIT_COLOR_METHODDEF + _CURSES_INIT_PAIR_METHODDEF + _CURSES_INITSCR_METHODDEF + _CURSES_INTRFLUSH_METHODDEF + _CURSES_ISENDWIN_METHODDEF + _CURSES_IS_TERM_RESIZED_METHODDEF + _CURSES_KEYNAME_METHODDEF + _CURSES_KILLCHAR_METHODDEF + _CURSES_LONGNAME_METHODDEF + _CURSES_META_METHODDEF + _CURSES_MOUSEINTERVAL_METHODDEF + _CURSES_MOUSEMASK_METHODDEF + _CURSES_NAPMS_METHODDEF + _CURSES_NEWPAD_METHODDEF + _CURSES_NEWWIN_METHODDEF + _CURSES_NL_METHODDEF + _CURSES_NOCBREAK_METHODDEF + _CURSES_NOECHO_METHODDEF + _CURSES_NONL_METHODDEF + _CURSES_NOQIFLUSH_METHODDEF + _CURSES_NORAW_METHODDEF + _CURSES_PAIR_CONTENT_METHODDEF + _CURSES_PAIR_NUMBER_METHODDEF + _CURSES_PUTP_METHODDEF + _CURSES_QIFLUSH_METHODDEF + _CURSES_RAW_METHODDEF + _CURSES_RESET_PROG_MODE_METHODDEF + _CURSES_RESET_SHELL_MODE_METHODDEF + _CURSES_RESETTY_METHODDEF + _CURSES_RESIZETERM_METHODDEF + _CURSES_RESIZE_TERM_METHODDEF + _CURSES_SAVETTY_METHODDEF + _CURSES_SETSYX_METHODDEF + _CURSES_SETUPTERM_METHODDEF + _CURSES_START_COLOR_METHODDEF + _CURSES_TERMATTRS_METHODDEF + _CURSES_TERMNAME_METHODDEF + _CURSES_TIGETFLAG_METHODDEF + _CURSES_TIGETNUM_METHODDEF + _CURSES_TIGETSTR_METHODDEF + _CURSES_TPARM_METHODDEF + _CURSES_TYPEAHEAD_METHODDEF + _CURSES_UNCTRL_METHODDEF + _CURSES_UNGETCH_METHODDEF + _CURSES_UPDATE_LINES_COLS_METHODDEF + _CURSES_UNGET_WCH_METHODDEF + _CURSES_USE_ENV_METHODDEF + _CURSES_USE_DEFAULT_COLORS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -3496,5 +4547,8 @@ PyInit__curses(void) SetDictInt("KEY_MIN", KEY_MIN); SetDictInt("KEY_MAX", KEY_MAX); } + + Py_INCREF(&PyCursesWindow_Type); + PyModule_AddObject(m, "window", (PyObject *)&PyCursesWindow_Type); return m; } diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h new file mode 100644 index 000000000000..e11c68d864a6 --- /dev/null +++ b/Modules/clinic/_curses_panel.c.h @@ -0,0 +1,317 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, +"bottom($self, /)\n" +"--\n" +"\n" +"Push the panel to the bottom of the stack."); + +#define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ + {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, + +static PyObject * +_curses_panel_panel_bottom_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_bottom_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hide__doc__, +"hide($self, /)\n" +"--\n" +"\n" +"Hide the panel.\n" +"\n" +"This does not delete the object, it just makes the window on screen invisible."); + +#define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ + {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, + +static PyObject * +_curses_panel_panel_hide_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hide_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_show__doc__, +"show($self, /)\n" +"--\n" +"\n" +"Display the panel (which might have been hidden)."); + +#define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ + {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, + +static PyObject * +_curses_panel_panel_show_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_show_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_top__doc__, +"top($self, /)\n" +"--\n" +"\n" +"Push panel to the top of the stack."); + +#define _CURSES_PANEL_PANEL_TOP_METHODDEF \ + {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, + +static PyObject * +_curses_panel_panel_top_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_top_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_above__doc__, +"above($self, /)\n" +"--\n" +"\n" +"Return the panel above the current panel."); + +#define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ + {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, + +static PyObject * +_curses_panel_panel_above_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_above_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_below__doc__, +"below($self, /)\n" +"--\n" +"\n" +"Return the panel below the current panel."); + +#define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ + {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, + +static PyObject * +_curses_panel_panel_below_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_below_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, +"hidden($self, /)\n" +"--\n" +"\n" +"Return True if the panel is hidden (not visible), False otherwise."); + +#define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ + {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, + +static PyObject * +_curses_panel_panel_hidden_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_hidden_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_move__doc__, +"move($self, y, x, /)\n" +"--\n" +"\n" +"Move the panel to the screen coordinates (y, x)."); + +#define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ + {"move", (PyCFunction)_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, + +static PyObject * +_curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); + +static PyObject * +_curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_ParseStack(args, nargs, "ii:move", + &y, &x)) { + goto exit; + } + return_value = _curses_panel_panel_move_impl(self, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_window__doc__, +"window($self, /)\n" +"--\n" +"\n" +"Return the window object associated with the panel."); + +#define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ + {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, + +static PyObject * +_curses_panel_panel_window_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_window_impl(self); +} + +PyDoc_STRVAR(_curses_panel_panel_replace__doc__, +"replace($self, win, /)\n" +"--\n" +"\n" +"Change the window associated with the panel to the window win."); + +#define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ + {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, + +static PyObject * +_curses_panel_panel_replace_impl(PyCursesPanelObject *self, + PyCursesWindowObject *win); + +static PyObject * +_curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyArg_Parse(arg, "O!:replace", &PyCursesWindow_Type, &win)) { + goto exit; + } + return_value = _curses_panel_panel_replace_impl(self, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, +"set_userptr($self, obj, /)\n" +"--\n" +"\n" +"Set the panel?s user pointer to obj."); + +#define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ + {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, + +PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, +"userptr($self, /)\n" +"--\n" +"\n" +"Return the user pointer for the panel."); + +#define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ + {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, + +static PyObject * +_curses_panel_panel_userptr_impl(PyCursesPanelObject *self); + +static PyObject * +_curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_panel_userptr_impl(self); +} + +PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, +"bottom_panel($module, /)\n" +"--\n" +"\n" +"Return the bottom panel in the panel stack."); + +#define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ + {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, + +static PyObject * +_curses_panel_bottom_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_bottom_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_new_panel__doc__, +"new_panel($module, win, /)\n" +"--\n" +"\n" +"Return a panel object, associating it with the given window win."); + +#define _CURSES_PANEL_NEW_PANEL_METHODDEF \ + {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, + +static PyObject * +_curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); + +static PyObject * +_curses_panel_new_panel(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *win; + + if (!PyArg_Parse(arg, "O!:new_panel", &PyCursesWindow_Type, &win)) { + goto exit; + } + return_value = _curses_panel_new_panel_impl(module, win); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_panel_top_panel__doc__, +"top_panel($module, /)\n" +"--\n" +"\n" +"Return the top panel in the panel stack."); + +#define _CURSES_PANEL_TOP_PANEL_METHODDEF \ + {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, + +static PyObject * +_curses_panel_top_panel_impl(PyObject *module); + +static PyObject * +_curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_top_panel_impl(module); +} + +PyDoc_STRVAR(_curses_panel_update_panels__doc__, +"update_panels($module, /)\n" +"--\n" +"\n" +"Updates the virtual screen after changes in the panel stack.\n" +"\n" +"This does not call curses.doupdate(), so you?ll have to do this yourself."); + +#define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ + {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, + +static PyObject * +_curses_panel_update_panels_impl(PyObject *module); + +static PyObject * +_curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_panel_update_panels_impl(module); +} +/*[clinic end generated code: output=96f627ca0b08b96d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 62ff1c8ae18a..b32797fc74ee 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2,9 +2,9 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(curses_window_addch__doc__, -"addch([y, x,] ch, [attr])\n" -"Paint character ch at (y, x) with attributes attr.\n" +PyDoc_STRVAR(_curses_window_addch__doc__, +"addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" +"Paint the character.\n" "\n" " y\n" " Y-coordinate.\n" @@ -20,15 +20,16 @@ PyDoc_STRVAR(curses_window_addch__doc__, "By default, the character position and attributes are the\n" "current settings for the window object."); -#define CURSES_WINDOW_ADDCH_METHODDEF \ - {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, +#define _CURSES_WINDOW_ADDCH_METHODDEF \ + {"addch", (PyCFunction)_curses_window_addch, METH_VARARGS, _curses_window_addch__doc__}, static PyObject * -curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, - int x, PyObject *ch, int group_right_1, long attr); +_curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr); static PyObject * -curses_window_addch(PyCursesWindowObject *self, PyObject *args) +_curses_window_addch(PyCursesWindowObject *self, PyObject *args) { PyObject *return_value = NULL; int group_left_1 = 0; @@ -36,7 +37,7 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) int x = 0; PyObject *ch; int group_right_1 = 0; - long attr = 0; + long attr = A_NORMAL; switch (PyTuple_GET_SIZE(args)) { case 1: @@ -64,12 +65,3777 @@ curses_window_addch(PyCursesWindowObject *self, PyObject *args) group_left_1 = 1; break; default: - PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); + PyErr_SetString(PyExc_TypeError, "_curses.window.addch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addstr__doc__, +"addstr([y, x,] str, [attr])\n" +"Paint the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint the string str at (y, x) with attributes attr,\n" +"overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDSTR_METHODDEF \ + {"addstr", (PyCFunction)_curses_window_addstr, METH_VARARGS, _curses_window_addstr__doc__}, + +static PyObject * +_curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_addstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:addstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:addstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:addstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:addstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_addstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_addnstr__doc__, +"addnstr([y, x,] str, n, [attr])\n" +"Paint at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to add.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Paint at most n characters of the string str at (y, x) with\n" +"attributes attr, overwriting anything previously on the display.\n" +"By default, the character position and attributes are the\n" +"current settings for the window object."); + +#define _CURSES_WINDOW_ADDNSTR_METHODDEF \ + {"addnstr", (PyCFunction)_curses_window_addnstr, METH_VARARGS, _curses_window_addnstr__doc__}, + +static PyObject * +_curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_addnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:addnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:addnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:addnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:addnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.addnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_addnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgd__doc__, +"bkgd($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the background property of the window.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGD_METHODDEF \ + {"bkgd", (PyCFunction)_curses_window_bkgd, METH_FASTCALL, _curses_window_bkgd__doc__}, + +static PyObject * +_curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr); + +static PyObject * +_curses_window_bkgd(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:bkgd", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_bkgd_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attroff__doc__, +"attroff($self, attr, /)\n" +"--\n" +"\n" +"Remove attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTROFF_METHODDEF \ + {"attroff", (PyCFunction)_curses_window_attroff, METH_O, _curses_window_attroff__doc__}, + +static PyObject * +_curses_window_attroff_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attroff(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attroff", &attr)) { + goto exit; + } + return_value = _curses_window_attroff_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attron__doc__, +"attron($self, attr, /)\n" +"--\n" +"\n" +"Add attribute attr from the \"background\" set."); + +#define _CURSES_WINDOW_ATTRON_METHODDEF \ + {"attron", (PyCFunction)_curses_window_attron, METH_O, _curses_window_attron__doc__}, + +static PyObject * +_curses_window_attron_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attron(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attron", &attr)) { + goto exit; + } + return_value = _curses_window_attron_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_attrset__doc__, +"attrset($self, attr, /)\n" +"--\n" +"\n" +"Set the \"background\" set of attributes."); + +#define _CURSES_WINDOW_ATTRSET_METHODDEF \ + {"attrset", (PyCFunction)_curses_window_attrset, METH_O, _curses_window_attrset__doc__}, + +static PyObject * +_curses_window_attrset_impl(PyCursesWindowObject *self, long attr); + +static PyObject * +_curses_window_attrset(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + long attr; + + if (!PyArg_Parse(arg, "l:attrset", &attr)) { + goto exit; + } + return_value = _curses_window_attrset_impl(self, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_bkgdset__doc__, +"bkgdset($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Set the window\'s background.\n" +"\n" +" ch\n" +" Background character.\n" +" attr\n" +" Background attributes."); + +#define _CURSES_WINDOW_BKGDSET_METHODDEF \ + {"bkgdset", (PyCFunction)_curses_window_bkgdset, METH_FASTCALL, _curses_window_bkgdset__doc__}, + +static PyObject * +_curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_bkgdset(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:bkgdset", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_bkgdset_impl(self, ch, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_border__doc__, +"border($self, ls=_curses.ACS_VLINE, rs=_curses.ACS_VLINE,\n" +" ts=_curses.ACS_HLINE, bs=_curses.ACS_HLINE,\n" +" tl=_curses.ACS_ULCORNER, tr=_curses.ACS_URCORNER,\n" +" bl=_curses.ACS_LLCORNER, br=_curses.ACS_LRCORNER, /)\n" +"--\n" +"\n" +"Draw a border around the edges of the window.\n" +"\n" +" ls\n" +" Left side.\n" +" rs\n" +" Right side.\n" +" ts\n" +" Top side.\n" +" bs\n" +" Bottom side.\n" +" tl\n" +" Upper-left corner.\n" +" tr\n" +" Upper-right corner.\n" +" bl\n" +" Bottom-left corner.\n" +" br\n" +" Bottom-right corner.\n" +"\n" +"Each parameter specifies the character to use for a specific part of the\n" +"border. The characters can be specified as integers or as one-character\n" +"strings. A 0 value for any parameter will cause the default character to be\n" +"used for that parameter."); + +#define _CURSES_WINDOW_BORDER_METHODDEF \ + {"border", (PyCFunction)_curses_window_border, METH_FASTCALL, _curses_window_border__doc__}, + +static PyObject * +_curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, + PyObject *rs, PyObject *ts, PyObject *bs, + PyObject *tl, PyObject *tr, PyObject *bl, + PyObject *br); + +static PyObject * +_curses_window_border(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ls = NULL; + PyObject *rs = NULL; + PyObject *ts = NULL; + PyObject *bs = NULL; + PyObject *tl = NULL; + PyObject *tr = NULL; + PyObject *bl = NULL; + PyObject *br = NULL; + + if (!_PyArg_UnpackStack(args, nargs, "border", + 0, 8, + &ls, &rs, &ts, &bs, &tl, &tr, &bl, &br)) { + goto exit; + } + return_value = _curses_window_border_impl(self, ls, rs, ts, bs, tl, tr, bl, br); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_box__doc__, +"box([verch=0, horch=0])\n" +"Draw a border around the edges of the window.\n" +"\n" +" verch\n" +" Left and right side.\n" +" horch\n" +" Top and bottom side.\n" +"\n" +"Similar to border(), but both ls and rs are verch and both ts and bs are\n" +"horch. The default corner characters are always used by this function."); + +#define _CURSES_WINDOW_BOX_METHODDEF \ + {"box", (PyCFunction)_curses_window_box, METH_VARARGS, _curses_window_box__doc__}, + +static PyObject * +_curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, + PyObject *verch, PyObject *horch); + +static PyObject * +_curses_window_box(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + PyObject *verch = _PyLong_Zero; + PyObject *horch = _PyLong_Zero; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:box", &verch, &horch)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.box requires 0 to 2 arguments"); goto exit; } - return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + return_value = _curses_window_box_impl(self, group_right_1, verch, horch); exit: return return_value; } -/*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_curses_window_delch__doc__, +"delch([y, x])\n" +"Delete any character at (y, x).\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_DELCH_METHODDEF \ + {"delch", (PyCFunction)_curses_window_delch, METH_VARARGS, _curses_window_delch__doc__}, + +static PyObject * +_curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_delch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:delch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.delch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_delch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_derwin__doc__, +"derwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (window-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"derwin() is the same as calling subwin(), except that begin_y and begin_x\n" +"are relative to the origin of the window, rather than relative to the entire\n" +"screen."); + +#define _CURSES_WINDOW_DERWIN_METHODDEF \ + {"derwin", (PyCFunction)_curses_window_derwin, METH_VARARGS, _curses_window_derwin__doc__}, + +static PyObject * +_curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_derwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:derwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:derwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.derwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_derwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_echochar__doc__, +"echochar($self, ch, attr=_curses.A_NORMAL, /)\n" +"--\n" +"\n" +"Add character ch with attribute attr, and refresh.\n" +"\n" +" ch\n" +" Character to add.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_ECHOCHAR_METHODDEF \ + {"echochar", (PyCFunction)_curses_window_echochar, METH_FASTCALL, _curses_window_echochar__doc__}, + +static PyObject * +_curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, + long attr); + +static PyObject * +_curses_window_echochar(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *ch; + long attr = A_NORMAL; + + if (!_PyArg_ParseStack(args, nargs, "O|l:echochar", + &ch, &attr)) { + goto exit; + } + return_value = _curses_window_echochar_impl(self, ch, attr); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_window_enclose__doc__, +"enclose($self, y, x, /)\n" +"--\n" +"\n" +"Return True if the screen-relative coordinates are enclosed by the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate."); + +#define _CURSES_WINDOW_ENCLOSE_METHODDEF \ + {"enclose", (PyCFunction)_curses_window_enclose, METH_FASTCALL, _curses_window_enclose__doc__}, + +static long +_curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x); + +static PyObject * +_curses_window_enclose(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + long _return_value; + + if (!_PyArg_ParseStack(args, nargs, "ii:enclose", + &y, &x)) { + goto exit; + } + _return_value = _curses_window_enclose_impl(self, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_window_getbkgd__doc__, +"getbkgd($self, /)\n" +"--\n" +"\n" +"Return the window\'s current background character/attribute pair."); + +#define _CURSES_WINDOW_GETBKGD_METHODDEF \ + {"getbkgd", (PyCFunction)_curses_window_getbkgd, METH_NOARGS, _curses_window_getbkgd__doc__}, + +static long +_curses_window_getbkgd_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_getbkgd(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + long _return_value; + + _return_value = _curses_window_getbkgd_impl(self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getch__doc__, +"getch([y, x])\n" +"Get a character code from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The integer returned does not have to be in ASCII range: function keys,\n" +"keypad keys and so on return numbers higher than 256. In no-delay mode, -1\n" +"is returned if there is no input, else getch() waits until a key is pressed."); + +#define _CURSES_WINDOW_GETCH_METHODDEF \ + {"getch", (PyCFunction)_curses_window_getch, METH_VARARGS, _curses_window_getch__doc__}, + +static int +_curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + int _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_getch_impl(self, group_right_1, y, x); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_getkey__doc__, +"getkey([y, x])\n" +"Get a character (string) from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Returning a string instead of an integer, as getch() does. Function keys,\n" +"keypad keys and other special keys return a multibyte string containing the\n" +"key name. In no-delay mode, an exception is raised if there is no input."); + +#define _CURSES_WINDOW_GETKEY_METHODDEF \ + {"getkey", (PyCFunction)_curses_window_getkey, METH_VARARGS, _curses_window_getkey__doc__}, + +static PyObject * +_curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_getkey(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:getkey", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.getkey requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_getkey_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_window_get_wch__doc__, +"get_wch([y, x])\n" +"Get a wide character from terminal keyboard.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"Return a character for most keys, or an integer for function keys,\n" +"keypad keys, and other special keys."); + +#define _CURSES_WINDOW_GET_WCH_METHODDEF \ + {"get_wch", (PyCFunction)_curses_window_get_wch, METH_VARARGS, _curses_window_get_wch__doc__}, + +static PyObject * +_curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_get_wch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:get_wch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.get_wch requires 0 to 2 arguments"); + goto exit; + } + return_value = _curses_window_get_wch_impl(self, group_right_1, y, x); + +exit: + return return_value; +} + +#endif /* defined(HAVE_NCURSESW) */ + +PyDoc_STRVAR(_curses_window_hline__doc__, +"hline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a horizontal line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the characters."); + +#define _CURSES_WINDOW_HLINE_METHODDEF \ + {"hline", (PyCFunction)_curses_window_hline, METH_VARARGS, _curses_window_hline__doc__}, + +static PyObject * +_curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_hline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:hline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:hline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:hline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:hline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.hline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_hline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insch__doc__, +"insch([y, x,] ch, [attr=_curses.A_NORMAL])\n" +"Insert a character before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" ch\n" +" Character to insert.\n" +" attr\n" +" Attributes for the character.\n" +"\n" +"All characters to the right of the cursor are shifted one position right, with\n" +"the rightmost characters on the line being lost."); + +#define _CURSES_WINDOW_INSCH_METHODDEF \ + {"insch", (PyCFunction)_curses_window_insch, METH_VARARGS, _curses_window_insch__doc__}, + +static PyObject * +_curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int group_right_1, + long attr); + +static PyObject * +_curses_window_insch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insch", &ch)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insch", &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insch", &y, &x, &ch)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insch", &y, &x, &ch, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insch requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insch_impl(self, group_left_1, y, x, ch, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_inch__doc__, +"inch([y, x])\n" +"Return the character at the given position in the window.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"The bottom 8 bits are the character proper, and upper bits are the attributes."); + +#define _CURSES_WINDOW_INCH_METHODDEF \ + {"inch", (PyCFunction)_curses_window_inch, METH_VARARGS, _curses_window_inch__doc__}, + +static unsigned long +_curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1, + int y, int x); + +static PyObject * +_curses_window_inch(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int y = 0; + int x = 0; + unsigned long _return_value; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:inch", &y, &x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.inch requires 0 to 2 arguments"); + goto exit; + } + _return_value = _curses_window_inch_impl(self, group_right_1, y, x); + if ((_return_value == (unsigned long)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insstr__doc__, +"insstr([y, x,] str, [attr])\n" +"Insert the string before the current or specified position.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor. All characters to the right of\n" +"the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x,\n" +"if specified)."); + +#define _CURSES_WINDOW_INSSTR_METHODDEF \ + {"insstr", (PyCFunction)_curses_window_insstr, METH_VARARGS, _curses_window_insstr__doc__}, + +static PyObject * +_curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int group_right_1, + long attr); + +static PyObject * +_curses_window_insstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:insstr", &str)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "Ol:insstr", &str, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iiO:insstr", &y, &x, &str)) { + goto exit; + } + group_left_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOl:insstr", &y, &x, &str, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insstr requires 1 to 4 arguments"); + goto exit; + } + return_value = _curses_window_insstr_impl(self, group_left_1, y, x, str, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_insnstr__doc__, +"insnstr([y, x,] str, n, [attr])\n" +"Insert at most n characters of the string.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +" str\n" +" String to insert.\n" +" n\n" +" Maximal number of characters.\n" +" attr\n" +" Attributes for characters.\n" +"\n" +"Insert a character string (as many characters as will fit on the line)\n" +"before the character under the cursor, up to n characters. If n is zero\n" +"or negative, the entire string is inserted. All characters to the right\n" +"of the cursor are shifted right, with the rightmost characters on the line\n" +"being lost. The cursor position does not change (after moving to y, x, if\n" +"specified)."); + +#define _CURSES_WINDOW_INSNSTR_METHODDEF \ + {"insnstr", (PyCFunction)_curses_window_insnstr, METH_VARARGS, _curses_window_insnstr__doc__}, + +static PyObject * +_curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *str, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_insnstr(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *str; + int n; + int group_right_1 = 0; + long attr = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:insnstr", &str, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:insnstr", &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:insnstr", &y, &x, &str, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:insnstr", &y, &x, &str, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.insnstr requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_insnstr_impl(self, group_left_1, y, x, str, n, group_right_1, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_is_linetouched__doc__, +"is_linetouched($self, line, /)\n" +"--\n" +"\n" +"Return True if the specified line was modified, otherwise return False.\n" +"\n" +" line\n" +" Line number.\n" +"\n" +"Raise a curses.error exception if line is not valid for the given window."); + +#define _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF \ + {"is_linetouched", (PyCFunction)_curses_window_is_linetouched, METH_O, _curses_window_is_linetouched__doc__}, + +static PyObject * +_curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line); + +static PyObject * +_curses_window_is_linetouched(PyCursesWindowObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int line; + + if (!PyArg_Parse(arg, "i:is_linetouched", &line)) { + goto exit; + } + return_value = _curses_window_is_linetouched_impl(self, line); + +exit: + return return_value; +} + +#if defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_VARARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self, + int group_right_1, int pminrow, int pmincol, + int sminrow, int smincol, int smaxrow, + int smaxcol); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:noutrefresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.noutrefresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_noutrefresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +#endif /* defined(py_is_pad) */ + +#if !defined(py_is_pad) + +PyDoc_STRVAR(_curses_window_noutrefresh__doc__, +"noutrefresh($self, /)\n" +"--\n" +"\n" +"Mark for refresh but wait.\n" +"\n" +"This function updates the data structure representing the desired state of the\n" +"window, but does not force an update of the physical screen. To accomplish\n" +"that, call doupdate()."); + +#define _CURSES_WINDOW_NOUTREFRESH_METHODDEF \ + {"noutrefresh", (PyCFunction)_curses_window_noutrefresh, METH_NOARGS, _curses_window_noutrefresh__doc__}, + +static PyObject * +_curses_window_noutrefresh_impl(PyCursesWindowObject *self); + +static PyObject * +_curses_window_noutrefresh(PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _curses_window_noutrefresh_impl(self); +} + +#endif /* !defined(py_is_pad) */ + +PyDoc_STRVAR(_curses_window_overlay__doc__, +"overlay(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])\n" +"Overlay the window on top of destwin.\n" +"\n" +"The windows need not be the same size, only the overlapping region is copied.\n" +"This copy is non-destructive, which means that the current background\n" +"character does not overwrite the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overlay() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, and the other variables mark a rectangle in the\n" +"destination window."); + +#define _CURSES_WINDOW_OVERLAY_METHODDEF \ + {"overlay", (PyCFunction)_curses_window_overlay, METH_VARARGS, _curses_window_overlay__doc__}, + +static PyObject * +_curses_window_overlay_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, int group_right_1, + int sminrow, int smincol, int dminrow, + int dmincol, int dmaxrow, int dmaxcol); + +static PyObject * +_curses_window_overlay(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overlay", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overlay", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overlay requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overlay_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_overwrite__doc__, +"overwrite(destwin, [sminrow, smincol, dminrow, dmincol, dmaxrow,\n" +" dmaxcol])\n" +"Overwrite the window on top of destwin.\n" +"\n" +"The windows need not be the same size, in which case only the overlapping\n" +"region is copied. This copy is destructive, which means that the current\n" +"background character overwrites the old contents of destwin.\n" +"\n" +"To get fine-grained control over the copied region, the second form of\n" +"overwrite() can be used. sminrow and smincol are the upper-left coordinates\n" +"of the source window, the other variables mark a rectangle in the destination\n" +"window."); + +#define _CURSES_WINDOW_OVERWRITE_METHODDEF \ + {"overwrite", (PyCFunction)_curses_window_overwrite, METH_VARARGS, _curses_window_overwrite__doc__}, + +static PyObject * +_curses_window_overwrite_impl(PyCursesWindowObject *self, + PyCursesWindowObject *destwin, + int group_right_1, int sminrow, int smincol, + int dminrow, int dmincol, int dmaxrow, + int dmaxcol); + +static PyObject * +_curses_window_overwrite(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyCursesWindowObject *destwin; + int group_right_1 = 0; + int sminrow = 0; + int smincol = 0; + int dminrow = 0; + int dmincol = 0; + int dmaxrow = 0; + int dmaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O!:overwrite", &PyCursesWindow_Type, &destwin)) { + goto exit; + } + break; + case 7: + if (!PyArg_ParseTuple(args, "O!iiiiii:overwrite", &PyCursesWindow_Type, &destwin, &sminrow, &smincol, &dminrow, &dmincol, &dmaxrow, &dmaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.overwrite requires 1 to 7 arguments"); + goto exit; + } + return_value = _curses_window_overwrite_impl(self, destwin, group_right_1, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_putwin__doc__, +"putwin($self, file, /)\n" +"--\n" +"\n" +"Write all data associated with the window into the provided file object.\n" +"\n" +"This information can be later retrieved using the getwin() function."); + +#define _CURSES_WINDOW_PUTWIN_METHODDEF \ + {"putwin", (PyCFunction)_curses_window_putwin, METH_O, _curses_window_putwin__doc__}, + +PyDoc_STRVAR(_curses_window_redrawln__doc__, +"redrawln($self, beg, num, /)\n" +"--\n" +"\n" +"Mark the specified lines corrupted.\n" +"\n" +" beg\n" +" Starting line number.\n" +" num\n" +" The number of lines.\n" +"\n" +"They should be completely redrawn on the next refresh() call."); + +#define _CURSES_WINDOW_REDRAWLN_METHODDEF \ + {"redrawln", (PyCFunction)_curses_window_redrawln, METH_FASTCALL, _curses_window_redrawln__doc__}, + +static PyObject * +_curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num); + +static PyObject * +_curses_window_redrawln(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int beg; + int num; + + if (!_PyArg_ParseStack(args, nargs, "ii:redrawln", + &beg, &num)) { + goto exit; + } + return_value = _curses_window_redrawln_impl(self, beg, num); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_refresh__doc__, +"refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])\n" +"Update the display immediately.\n" +"\n" +"Synchronize actual screen with previous drawing/deleting methods.\n" +"The 6 optional arguments can only be specified when the window is a pad\n" +"created with newpad(). The additional parameters are needed to indicate\n" +"what part of the pad and screen are involved. pminrow and pmincol specify\n" +"the upper left-hand corner of the rectangle to be displayed in the pad.\n" +"sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to\n" +"be displayed on the screen. The lower right-hand corner of the rectangle to\n" +"be displayed in the pad is calculated from the screen coordinates, since the\n" +"rectangles must be the same size. Both rectangles must be entirely contained\n" +"within their respective structures. Negative values of pminrow, pmincol,\n" +"sminrow, or smincol are treated as if they were zero."); + +#define _CURSES_WINDOW_REFRESH_METHODDEF \ + {"refresh", (PyCFunction)_curses_window_refresh, METH_VARARGS, _curses_window_refresh__doc__}, + +static PyObject * +_curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1, + int pminrow, int pmincol, int sminrow, + int smincol, int smaxrow, int smaxcol); + +static PyObject * +_curses_window_refresh(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int pminrow = 0; + int pmincol = 0; + int sminrow = 0; + int smincol = 0; + int smaxrow = 0; + int smaxcol = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 6: + if (!PyArg_ParseTuple(args, "iiiiii:refresh", &pminrow, &pmincol, &sminrow, &smincol, &smaxrow, &smaxcol)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.refresh requires 0 to 6 arguments"); + goto exit; + } + return_value = _curses_window_refresh_impl(self, group_right_1, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_setscrreg__doc__, +"setscrreg($self, top, bottom, /)\n" +"--\n" +"\n" +"Define a software scrolling region.\n" +"\n" +" top\n" +" First line number.\n" +" bottom\n" +" Last line number.\n" +"\n" +"All scrolling actions will take place in this region."); + +#define _CURSES_WINDOW_SETSCRREG_METHODDEF \ + {"setscrreg", (PyCFunction)_curses_window_setscrreg, METH_FASTCALL, _curses_window_setscrreg__doc__}, + +static PyObject * +_curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, + int bottom); + +static PyObject * +_curses_window_setscrreg(PyCursesWindowObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int top; + int bottom; + + if (!_PyArg_ParseStack(args, nargs, "ii:setscrreg", + &top, &bottom)) { + goto exit; + } + return_value = _curses_window_setscrreg_impl(self, top, bottom); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_subwin__doc__, +"subwin([nlines=0, ncols=0,] begin_y, begin_x)\n" +"Create a sub-window (screen-relative coordinates).\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the sub-window will extend from the specified position to the\n" +"lower right corner of the window."); + +#define _CURSES_WINDOW_SUBWIN_METHODDEF \ + {"subwin", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__}, + +static PyObject * +_curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1, + int nlines, int ncols, int begin_y, int begin_x); + +static PyObject * +_curses_window_subwin(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int nlines = 0; + int ncols = 0; + int begin_y; + int begin_x; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:subwin", &begin_y, &begin_x)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:subwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.subwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_window_subwin_impl(self, group_left_1, nlines, ncols, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_scroll__doc__, +"scroll([lines=1])\n" +"Scroll the screen or scrolling region.\n" +"\n" +" lines\n" +" Number of lines to scroll.\n" +"\n" +"Scroll upward if the argument is positive and downward if it is negative."); + +#define _CURSES_WINDOW_SCROLL_METHODDEF \ + {"scroll", (PyCFunction)_curses_window_scroll, METH_VARARGS, _curses_window_scroll__doc__}, + +static PyObject * +_curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1, + int lines); + +static PyObject * +_curses_window_scroll(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_right_1 = 0; + int lines = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 0: + break; + case 1: + if (!PyArg_ParseTuple(args, "i:scroll", &lines)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.scroll requires 0 to 1 arguments"); + goto exit; + } + return_value = _curses_window_scroll_impl(self, group_right_1, lines); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_touchline__doc__, +"touchline(start, count, [changed=True])\n" +"Pretend count lines have been changed, starting with line start.\n" +"\n" +"If changed is supplied, it specifies whether the affected lines are marked\n" +"as having been changed (changed=True) or unchanged (changed=False)."); + +#define _CURSES_WINDOW_TOUCHLINE_METHODDEF \ + {"touchline", (PyCFunction)_curses_window_touchline, METH_VARARGS, _curses_window_touchline__doc__}, + +static PyObject * +_curses_window_touchline_impl(PyCursesWindowObject *self, int start, + int count, int group_right_1, int changed); + +static PyObject * +_curses_window_touchline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int start; + int count; + int group_right_1 = 0; + int changed = 1; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:touchline", &start, &count)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "iii:touchline", &start, &count, &changed)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.touchline requires 2 to 3 arguments"); + goto exit; + } + return_value = _curses_window_touchline_impl(self, start, count, group_right_1, changed); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_window_vline__doc__, +"vline([y, x,] ch, n, [attr=_curses.A_NORMAL])\n" +"Display a vertical line.\n" +"\n" +" y\n" +" Starting Y-coordinate.\n" +" x\n" +" Starting X-coordinate.\n" +" ch\n" +" Character to draw.\n" +" n\n" +" Line length.\n" +" attr\n" +" Attributes for the character."); + +#define _CURSES_WINDOW_VLINE_METHODDEF \ + {"vline", (PyCFunction)_curses_window_vline, METH_VARARGS, _curses_window_vline__doc__}, + +static PyObject * +_curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1, + int y, int x, PyObject *ch, int n, + int group_right_1, long attr); + +static PyObject * +_curses_window_vline(PyCursesWindowObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int y = 0; + int x = 0; + PyObject *ch; + int n; + int group_right_1 = 0; + long attr = A_NORMAL; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "Oi:vline", &ch, &n)) { + goto exit; + } + break; + case 3: + if (!PyArg_ParseTuple(args, "Oil:vline", &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + break; + case 4: + if (!PyArg_ParseTuple(args, "iiOi:vline", &y, &x, &ch, &n)) { + goto exit; + } + group_left_1 = 1; + break; + case 5: + if (!PyArg_ParseTuple(args, "iiOil:vline", &y, &x, &ch, &n, &attr)) { + goto exit; + } + group_right_1 = 1; + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.window.vline requires 2 to 5 arguments"); + goto exit; + } + return_value = _curses_window_vline_impl(self, group_left_1, y, x, ch, n, group_right_1, attr); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_FILTER) + +PyDoc_STRVAR(_curses_filter__doc__, +"filter($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_FILTER_METHODDEF \ + {"filter", (PyCFunction)_curses_filter, METH_NOARGS, _curses_filter__doc__}, + +static PyObject * +_curses_filter_impl(PyObject *module); + +static PyObject * +_curses_filter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_filter_impl(module); +} + +#endif /* defined(HAVE_CURSES_FILTER) */ + +PyDoc_STRVAR(_curses_baudrate__doc__, +"baudrate($module, /)\n" +"--\n" +"\n" +"Return the output speed of the terminal in bits per second."); + +#define _CURSES_BAUDRATE_METHODDEF \ + {"baudrate", (PyCFunction)_curses_baudrate, METH_NOARGS, _curses_baudrate__doc__}, + +static PyObject * +_curses_baudrate_impl(PyObject *module); + +static PyObject * +_curses_baudrate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_baudrate_impl(module); +} + +PyDoc_STRVAR(_curses_beep__doc__, +"beep($module, /)\n" +"--\n" +"\n" +"Emit a short attention sound."); + +#define _CURSES_BEEP_METHODDEF \ + {"beep", (PyCFunction)_curses_beep, METH_NOARGS, _curses_beep__doc__}, + +static PyObject * +_curses_beep_impl(PyObject *module); + +static PyObject * +_curses_beep(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_beep_impl(module); +} + +PyDoc_STRVAR(_curses_can_change_color__doc__, +"can_change_color($module, /)\n" +"--\n" +"\n" +"Return True if the programmer can change the colors displayed by the terminal."); + +#define _CURSES_CAN_CHANGE_COLOR_METHODDEF \ + {"can_change_color", (PyCFunction)_curses_can_change_color, METH_NOARGS, _curses_can_change_color__doc__}, + +static PyObject * +_curses_can_change_color_impl(PyObject *module); + +static PyObject * +_curses_can_change_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_can_change_color_impl(module); +} + +PyDoc_STRVAR(_curses_cbreak__doc__, +"cbreak($module, flag=True, /)\n" +"--\n" +"\n" +"Enter cbreak mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nocbreak().\n" +"\n" +"In cbreak mode (sometimes called \"rare\" mode) normal tty line buffering is\n" +"turned off and characters are available to be read one by one. However,\n" +"unlike raw mode, special characters (interrupt, quit, suspend, and flow\n" +"control) retain their effects on the tty driver and calling program.\n" +"Calling first raw() then cbreak() leaves the terminal in cbreak mode."); + +#define _CURSES_CBREAK_METHODDEF \ + {"cbreak", (PyCFunction)_curses_cbreak, METH_FASTCALL, _curses_cbreak__doc__}, + +static PyObject * +_curses_cbreak_impl(PyObject *module, int flag); + +static PyObject * +_curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:cbreak", + &flag)) { + goto exit; + } + return_value = _curses_cbreak_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_content__doc__, +"color_content($module, color_number, /)\n" +"--\n" +"\n" +"Return the red, green, and blue (RGB) components of the specified color.\n" +"\n" +" color_number\n" +" The number of the color (0 - COLORS).\n" +"\n" +"A 3-tuple is returned, containing the R, G, B values for the given color,\n" +"which will be between 0 (no component) and 1000 (maximum amount of component)."); + +#define _CURSES_COLOR_CONTENT_METHODDEF \ + {"color_content", (PyCFunction)_curses_color_content, METH_O, _curses_color_content__doc__}, + +static PyObject * +_curses_color_content_impl(PyObject *module, short color_number); + +static PyObject * +_curses_color_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short color_number; + + if (!PyArg_Parse(arg, "h:color_content", &color_number)) { + goto exit; + } + return_value = _curses_color_content_impl(module, color_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_color_pair__doc__, +"color_pair($module, color_number, /)\n" +"--\n" +"\n" +"Return the attribute value for displaying text in the specified color.\n" +"\n" +" color_number\n" +" The number of the color (0 - COLORS).\n" +"\n" +"This attribute value can be combined with A_STANDOUT, A_REVERSE, and the\n" +"other A_* attributes. pair_number() is the counterpart to this function."); + +#define _CURSES_COLOR_PAIR_METHODDEF \ + {"color_pair", (PyCFunction)_curses_color_pair, METH_O, _curses_color_pair__doc__}, + +static PyObject * +_curses_color_pair_impl(PyObject *module, short color_number); + +static PyObject * +_curses_color_pair(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short color_number; + + if (!PyArg_Parse(arg, "h:color_pair", &color_number)) { + goto exit; + } + return_value = _curses_color_pair_impl(module, color_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_curs_set__doc__, +"curs_set($module, visibility, /)\n" +"--\n" +"\n" +"Set the cursor state.\n" +"\n" +" visibility\n" +" 0 for invisible, 1 for normal visible, or 2 for very visible.\n" +"\n" +"If the terminal supports the visibility requested, the previous cursor\n" +"state is returned; otherwise, an exception is raised. On many terminals,\n" +"the \"visible\" mode is an underline cursor and the \"very visible\" mode is\n" +"a block cursor."); + +#define _CURSES_CURS_SET_METHODDEF \ + {"curs_set", (PyCFunction)_curses_curs_set, METH_O, _curses_curs_set__doc__}, + +static PyObject * +_curses_curs_set_impl(PyObject *module, int visibility); + +static PyObject * +_curses_curs_set(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int visibility; + + if (!PyArg_Parse(arg, "i:curs_set", &visibility)) { + goto exit; + } + return_value = _curses_curs_set_impl(module, visibility); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_def_prog_mode__doc__, +"def_prog_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"program\" mode.\n" +"\n" +"The \"program\" mode is the mode when the running program is using curses.\n" +"\n" +"Subsequent calls to reset_prog_mode() will restore this mode."); + +#define _CURSES_DEF_PROG_MODE_METHODDEF \ + {"def_prog_mode", (PyCFunction)_curses_def_prog_mode, METH_NOARGS, _curses_def_prog_mode__doc__}, + +static PyObject * +_curses_def_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_def_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_def_shell_mode__doc__, +"def_shell_mode($module, /)\n" +"--\n" +"\n" +"Save the current terminal mode as the \"shell\" mode.\n" +"\n" +"The \"shell\" mode is the mode when the running program is not using curses.\n" +"\n" +"Subsequent calls to reset_shell_mode() will restore this mode."); + +#define _CURSES_DEF_SHELL_MODE_METHODDEF \ + {"def_shell_mode", (PyCFunction)_curses_def_shell_mode, METH_NOARGS, _curses_def_shell_mode__doc__}, + +static PyObject * +_curses_def_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_def_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_def_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_delay_output__doc__, +"delay_output($module, ms, /)\n" +"--\n" +"\n" +"Insert a pause in output.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_DELAY_OUTPUT_METHODDEF \ + {"delay_output", (PyCFunction)_curses_delay_output, METH_O, _curses_delay_output__doc__}, + +static PyObject * +_curses_delay_output_impl(PyObject *module, int ms); + +static PyObject * +_curses_delay_output(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (!PyArg_Parse(arg, "i:delay_output", &ms)) { + goto exit; + } + return_value = _curses_delay_output_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_doupdate__doc__, +"doupdate($module, /)\n" +"--\n" +"\n" +"Update the physical screen to match the virtual screen."); + +#define _CURSES_DOUPDATE_METHODDEF \ + {"doupdate", (PyCFunction)_curses_doupdate, METH_NOARGS, _curses_doupdate__doc__}, + +static PyObject * +_curses_doupdate_impl(PyObject *module); + +static PyObject * +_curses_doupdate(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_doupdate_impl(module); +} + +PyDoc_STRVAR(_curses_echo__doc__, +"echo($module, flag=True, /)\n" +"--\n" +"\n" +"Enter echo mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noecho().\n" +"\n" +"In echo mode, each character input is echoed to the screen as it is entered."); + +#define _CURSES_ECHO_METHODDEF \ + {"echo", (PyCFunction)_curses_echo, METH_FASTCALL, _curses_echo__doc__}, + +static PyObject * +_curses_echo_impl(PyObject *module, int flag); + +static PyObject * +_curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:echo", + &flag)) { + goto exit; + } + return_value = _curses_echo_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_endwin__doc__, +"endwin($module, /)\n" +"--\n" +"\n" +"De-initialize the library, and return terminal to normal status."); + +#define _CURSES_ENDWIN_METHODDEF \ + {"endwin", (PyCFunction)_curses_endwin, METH_NOARGS, _curses_endwin__doc__}, + +static PyObject * +_curses_endwin_impl(PyObject *module); + +static PyObject * +_curses_endwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_endwin_impl(module); +} + +PyDoc_STRVAR(_curses_erasechar__doc__, +"erasechar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current erase character."); + +#define _CURSES_ERASECHAR_METHODDEF \ + {"erasechar", (PyCFunction)_curses_erasechar, METH_NOARGS, _curses_erasechar__doc__}, + +static PyObject * +_curses_erasechar_impl(PyObject *module); + +static PyObject * +_curses_erasechar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_erasechar_impl(module); +} + +PyDoc_STRVAR(_curses_flash__doc__, +"flash($module, /)\n" +"--\n" +"\n" +"Flash the screen.\n" +"\n" +"That is, change it to reverse-video and then change it back in a short interval."); + +#define _CURSES_FLASH_METHODDEF \ + {"flash", (PyCFunction)_curses_flash, METH_NOARGS, _curses_flash__doc__}, + +static PyObject * +_curses_flash_impl(PyObject *module); + +static PyObject * +_curses_flash(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flash_impl(module); +} + +PyDoc_STRVAR(_curses_flushinp__doc__, +"flushinp($module, /)\n" +"--\n" +"\n" +"Flush all input buffers.\n" +"\n" +"This throws away any typeahead that has been typed by the user and has not\n" +"yet been processed by the program."); + +#define _CURSES_FLUSHINP_METHODDEF \ + {"flushinp", (PyCFunction)_curses_flushinp, METH_NOARGS, _curses_flushinp__doc__}, + +static PyObject * +_curses_flushinp_impl(PyObject *module); + +static PyObject * +_curses_flushinp(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_flushinp_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_getsyx__doc__, +"getsyx($module, /)\n" +"--\n" +"\n" +"Return the current coordinates of the virtual screen cursor.\n" +"\n" +"Return a (y, x) tuple. If leaveok is currently true, return (-1, -1)."); + +#define _CURSES_GETSYX_METHODDEF \ + {"getsyx", (PyCFunction)_curses_getsyx, METH_NOARGS, _curses_getsyx__doc__}, + +static PyObject * +_curses_getsyx_impl(PyObject *module); + +static PyObject * +_curses_getsyx(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getsyx_impl(module); +} + +#endif /* defined(getsyx) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_getmouse__doc__, +"getmouse($module, /)\n" +"--\n" +"\n" +"Retrieve the queued mouse event.\n" +"\n" +"After getch() returns KEY_MOUSE to signal a mouse event, this function\n" +"returns a 5-tuple (id, x, y, z, bstate)."); + +#define _CURSES_GETMOUSE_METHODDEF \ + {"getmouse", (PyCFunction)_curses_getmouse, METH_NOARGS, _curses_getmouse__doc__}, + +static PyObject * +_curses_getmouse_impl(PyObject *module); + +static PyObject * +_curses_getmouse(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_getmouse_impl(module); +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_ungetmouse__doc__, +"ungetmouse($module, id, x, y, z, bstate, /)\n" +"--\n" +"\n" +"Push a KEY_MOUSE event onto the input queue.\n" +"\n" +"The following getmouse() will return the given state data."); + +#define _CURSES_UNGETMOUSE_METHODDEF \ + {"ungetmouse", (PyCFunction)_curses_ungetmouse, METH_FASTCALL, _curses_ungetmouse__doc__}, + +static PyObject * +_curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, + unsigned long bstate); + +static PyObject * +_curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short id; + int x; + int y; + int z; + unsigned long bstate; + + if (!_PyArg_ParseStack(args, nargs, "hiiik:ungetmouse", + &id, &x, &y, &z, &bstate)) { + goto exit; + } + return_value = _curses_ungetmouse_impl(module, id, x, y, z, bstate); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_getwin__doc__, +"getwin($module, file, /)\n" +"--\n" +"\n" +"Read window related data stored in the file by an earlier putwin() call.\n" +"\n" +"The routine then creates and initializes a new window using that data,\n" +"returning the new window object."); + +#define _CURSES_GETWIN_METHODDEF \ + {"getwin", (PyCFunction)_curses_getwin, METH_O, _curses_getwin__doc__}, + +PyDoc_STRVAR(_curses_halfdelay__doc__, +"halfdelay($module, tenths, /)\n" +"--\n" +"\n" +"Enter half-delay mode.\n" +"\n" +" tenths\n" +" Maximal blocking delay in tenths of seconds (1 - 255).\n" +"\n" +"Use nocbreak() to leave half-delay mode."); + +#define _CURSES_HALFDELAY_METHODDEF \ + {"halfdelay", (PyCFunction)_curses_halfdelay, METH_O, _curses_halfdelay__doc__}, + +static PyObject * +_curses_halfdelay_impl(PyObject *module, unsigned char tenths); + +static PyObject * +_curses_halfdelay(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned char tenths; + + if (!PyArg_Parse(arg, "b:halfdelay", &tenths)) { + goto exit; + } + return_value = _curses_halfdelay_impl(module, tenths); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_has_colors__doc__, +"has_colors($module, /)\n" +"--\n" +"\n" +"Return True if the terminal can display colors; otherwise, return False."); + +#define _CURSES_HAS_COLORS_METHODDEF \ + {"has_colors", (PyCFunction)_curses_has_colors, METH_NOARGS, _curses_has_colors__doc__}, + +static PyObject * +_curses_has_colors_impl(PyObject *module); + +static PyObject * +_curses_has_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_colors_impl(module); +} + +PyDoc_STRVAR(_curses_has_ic__doc__, +"has_ic($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-character capabilities."); + +#define _CURSES_HAS_IC_METHODDEF \ + {"has_ic", (PyCFunction)_curses_has_ic, METH_NOARGS, _curses_has_ic__doc__}, + +static PyObject * +_curses_has_ic_impl(PyObject *module); + +static PyObject * +_curses_has_ic(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_ic_impl(module); +} + +PyDoc_STRVAR(_curses_has_il__doc__, +"has_il($module, /)\n" +"--\n" +"\n" +"Return True if the terminal has insert- and delete-line capabilities."); + +#define _CURSES_HAS_IL_METHODDEF \ + {"has_il", (PyCFunction)_curses_has_il, METH_NOARGS, _curses_has_il__doc__}, + +static PyObject * +_curses_has_il_impl(PyObject *module); + +static PyObject * +_curses_has_il(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_has_il_impl(module); +} + +#if defined(HAVE_CURSES_HAS_KEY) + +PyDoc_STRVAR(_curses_has_key__doc__, +"has_key($module, key, /)\n" +"--\n" +"\n" +"Return True if the current terminal type recognizes a key with that value.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_HAS_KEY_METHODDEF \ + {"has_key", (PyCFunction)_curses_has_key, METH_O, _curses_has_key__doc__}, + +static PyObject * +_curses_has_key_impl(PyObject *module, int key); + +static PyObject * +_curses_has_key(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (!PyArg_Parse(arg, "i:has_key", &key)) { + goto exit; + } + return_value = _curses_has_key_impl(module, key); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_HAS_KEY) */ + +PyDoc_STRVAR(_curses_init_color__doc__, +"init_color($module, color_number, r, g, b, /)\n" +"--\n" +"\n" +"Change the definition of a color.\n" +"\n" +" color_number\n" +" The number of the color to be changed (0 - COLORS).\n" +" r\n" +" Red component (0 - 1000).\n" +" g\n" +" Green component (0 - 1000).\n" +" b\n" +" Blue component (0 - 1000).\n" +"\n" +"When init_color() is used, all occurrences of that color on the screen\n" +"immediately change to the new definition. This function is a no-op on\n" +"most terminals; it is active only if can_change_color() returns 1."); + +#define _CURSES_INIT_COLOR_METHODDEF \ + {"init_color", (PyCFunction)_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, + +static PyObject * +_curses_init_color_impl(PyObject *module, short color_number, short r, + short g, short b); + +static PyObject * +_curses_init_color(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short color_number; + short r; + short g; + short b; + + if (!_PyArg_ParseStack(args, nargs, "hhhh:init_color", + &color_number, &r, &g, &b)) { + goto exit; + } + return_value = _curses_init_color_impl(module, color_number, r, g, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_init_pair__doc__, +"init_pair($module, pair_number, fg, bg, /)\n" +"--\n" +"\n" +"Change the definition of a color-pair.\n" +"\n" +" pair_number\n" +" The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).\n" +" fg\n" +" Foreground color number (0 - COLORS).\n" +" bg\n" +" Background color number (0 - COLORS).\n" +"\n" +"If the color-pair was previously initialized, the screen is refreshed and\n" +"all occurrences of that color-pair are changed to the new definition."); + +#define _CURSES_INIT_PAIR_METHODDEF \ + {"init_pair", (PyCFunction)_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, + +static PyObject * +_curses_init_pair_impl(PyObject *module, short pair_number, short fg, + short bg); + +static PyObject * +_curses_init_pair(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short pair_number; + short fg; + short bg; + + if (!_PyArg_ParseStack(args, nargs, "hhh:init_pair", + &pair_number, &fg, &bg)) { + goto exit; + } + return_value = _curses_init_pair_impl(module, pair_number, fg, bg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_initscr__doc__, +"initscr($module, /)\n" +"--\n" +"\n" +"Initialize the library.\n" +"\n" +"Return a WindowObject which represents the whole screen."); + +#define _CURSES_INITSCR_METHODDEF \ + {"initscr", (PyCFunction)_curses_initscr, METH_NOARGS, _curses_initscr__doc__}, + +static PyObject * +_curses_initscr_impl(PyObject *module); + +static PyObject * +_curses_initscr(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_initscr_impl(module); +} + +PyDoc_STRVAR(_curses_setupterm__doc__, +"setupterm($module, /, term=None, fd=-1)\n" +"--\n" +"\n" +"Initialize the terminal.\n" +"\n" +" term\n" +" Terminal name.\n" +" If omitted, the value of the TERM environment variable will be used.\n" +" fd\n" +" File descriptor to which any initialization sequences will be sent.\n" +" If not supplied, the file descriptor for sys.stdout will be used."); + +#define _CURSES_SETUPTERM_METHODDEF \ + {"setupterm", (PyCFunction)_curses_setupterm, METH_FASTCALL|METH_KEYWORDS, _curses_setupterm__doc__}, + +static PyObject * +_curses_setupterm_impl(PyObject *module, const char *term, int fd); + +static PyObject * +_curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"term", "fd", NULL}; + static _PyArg_Parser _parser = {"|zi:setupterm", _keywords, 0}; + const char *term = NULL; + int fd = -1; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &term, &fd)) { + goto exit; + } + return_value = _curses_setupterm_impl(module, term, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_intrflush__doc__, +"intrflush($module, flag, /)\n" +"--\n" +"\n"); + +#define _CURSES_INTRFLUSH_METHODDEF \ + {"intrflush", (PyCFunction)_curses_intrflush, METH_O, _curses_intrflush__doc__}, + +static PyObject * +_curses_intrflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_intrflush(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (!PyArg_Parse(arg, "i:intrflush", &flag)) { + goto exit; + } + return_value = _curses_intrflush_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_isendwin__doc__, +"isendwin($module, /)\n" +"--\n" +"\n" +"Return True if endwin() has been called."); + +#define _CURSES_ISENDWIN_METHODDEF \ + {"isendwin", (PyCFunction)_curses_isendwin, METH_NOARGS, _curses_isendwin__doc__}, + +static PyObject * +_curses_isendwin_impl(PyObject *module); + +static PyObject * +_curses_isendwin(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_isendwin_impl(module); +} + +#if defined(HAVE_CURSES_IS_TERM_RESIZED) + +PyDoc_STRVAR(_curses_is_term_resized__doc__, +"is_term_resized($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Return True if resize_term() would modify the window structure, False otherwise.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_IS_TERM_RESIZED_METHODDEF \ + {"is_term_resized", (PyCFunction)_curses_is_term_resized, METH_FASTCALL, _curses_is_term_resized__doc__}, + +static PyObject * +_curses_is_term_resized_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_is_term_resized(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:is_term_resized", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_is_term_resized_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_IS_TERM_RESIZED) */ + +PyDoc_STRVAR(_curses_keyname__doc__, +"keyname($module, key, /)\n" +"--\n" +"\n" +"Return the name of specified key.\n" +"\n" +" key\n" +" Key number."); + +#define _CURSES_KEYNAME_METHODDEF \ + {"keyname", (PyCFunction)_curses_keyname, METH_O, _curses_keyname__doc__}, + +static PyObject * +_curses_keyname_impl(PyObject *module, int key); + +static PyObject * +_curses_keyname(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int key; + + if (!PyArg_Parse(arg, "i:keyname", &key)) { + goto exit; + } + return_value = _curses_keyname_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_killchar__doc__, +"killchar($module, /)\n" +"--\n" +"\n" +"Return the user\'s current line kill character."); + +#define _CURSES_KILLCHAR_METHODDEF \ + {"killchar", (PyCFunction)_curses_killchar, METH_NOARGS, _curses_killchar__doc__}, + +static PyObject * +_curses_killchar_impl(PyObject *module); + +static PyObject * +_curses_killchar(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_killchar_impl(module); +} + +PyDoc_STRVAR(_curses_longname__doc__, +"longname($module, /)\n" +"--\n" +"\n" +"Return the terminfo long name field describing the current terminal.\n" +"\n" +"The maximum length of a verbose description is 128 characters. It is defined\n" +"only after the call to initscr()."); + +#define _CURSES_LONGNAME_METHODDEF \ + {"longname", (PyCFunction)_curses_longname, METH_NOARGS, _curses_longname__doc__}, + +static PyObject * +_curses_longname_impl(PyObject *module); + +static PyObject * +_curses_longname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_longname_impl(module); +} + +PyDoc_STRVAR(_curses_meta__doc__, +"meta($module, yes, /)\n" +"--\n" +"\n" +"Enable/disable meta keys.\n" +"\n" +"If yes is True, allow 8-bit characters to be input. If yes is False,\n" +"allow only 7-bit characters."); + +#define _CURSES_META_METHODDEF \ + {"meta", (PyCFunction)_curses_meta, METH_O, _curses_meta__doc__}, + +static PyObject * +_curses_meta_impl(PyObject *module, int yes); + +static PyObject * +_curses_meta(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int yes; + + if (!PyArg_Parse(arg, "i:meta", &yes)) { + goto exit; + } + return_value = _curses_meta_impl(module, yes); + +exit: + return return_value; +} + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mouseinterval__doc__, +"mouseinterval($module, interval, /)\n" +"--\n" +"\n" +"Set and retrieve the maximum time between press and release in a click.\n" +"\n" +" interval\n" +" Time in milliseconds.\n" +"\n" +"Set the maximum time that can elapse between press and release events in\n" +"order for them to be recognized as a click, and return the previous interval\n" +"value."); + +#define _CURSES_MOUSEINTERVAL_METHODDEF \ + {"mouseinterval", (PyCFunction)_curses_mouseinterval, METH_O, _curses_mouseinterval__doc__}, + +static PyObject * +_curses_mouseinterval_impl(PyObject *module, int interval); + +static PyObject * +_curses_mouseinterval(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int interval; + + if (!PyArg_Parse(arg, "i:mouseinterval", &interval)) { + goto exit; + } + return_value = _curses_mouseinterval_impl(module, interval); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +#if defined(NCURSES_MOUSE_VERSION) + +PyDoc_STRVAR(_curses_mousemask__doc__, +"mousemask($module, newmask, /)\n" +"--\n" +"\n" +"Set the mouse events to be reported, and return a tuple (availmask, oldmask).\n" +"\n" +"Return a tuple (availmask, oldmask). availmask indicates which of the\n" +"specified mouse events can be reported; on complete failure it returns 0.\n" +"oldmask is the previous value of the given window\'s mouse event mask.\n" +"If this function is never called, no mouse events are ever reported."); + +#define _CURSES_MOUSEMASK_METHODDEF \ + {"mousemask", (PyCFunction)_curses_mousemask, METH_O, _curses_mousemask__doc__}, + +static PyObject * +_curses_mousemask_impl(PyObject *module, unsigned long newmask); + +static PyObject * +_curses_mousemask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned long newmask; + + if (!PyArg_Parse(arg, "k:mousemask", &newmask)) { + goto exit; + } + return_value = _curses_mousemask_impl(module, newmask); + +exit: + return return_value; +} + +#endif /* defined(NCURSES_MOUSE_VERSION) */ + +PyDoc_STRVAR(_curses_napms__doc__, +"napms($module, ms, /)\n" +"--\n" +"\n" +"Sleep for specified time.\n" +"\n" +" ms\n" +" Duration in milliseconds."); + +#define _CURSES_NAPMS_METHODDEF \ + {"napms", (PyCFunction)_curses_napms, METH_O, _curses_napms__doc__}, + +static PyObject * +_curses_napms_impl(PyObject *module, int ms); + +static PyObject * +_curses_napms(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (!PyArg_Parse(arg, "i:napms", &ms)) { + goto exit; + } + return_value = _curses_napms_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newpad__doc__, +"newpad($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Create and return a pointer to a new pad data structure.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width."); + +#define _CURSES_NEWPAD_METHODDEF \ + {"newpad", (PyCFunction)_curses_newpad, METH_FASTCALL, _curses_newpad__doc__}, + +static PyObject * +_curses_newpad_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_newpad(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:newpad", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_newpad_impl(module, nlines, ncols); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_newwin__doc__, +"newwin(nlines, ncols, [begin_y=0, begin_x=0])\n" +"Return a new window.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +" begin_y\n" +" Top side y-coordinate.\n" +" begin_x\n" +" Left side x-coordinate.\n" +"\n" +"By default, the window will extend from the specified position to the lower\n" +"right corner of the screen."); + +#define _CURSES_NEWWIN_METHODDEF \ + {"newwin", (PyCFunction)_curses_newwin, METH_VARARGS, _curses_newwin__doc__}, + +static PyObject * +_curses_newwin_impl(PyObject *module, int nlines, int ncols, + int group_right_1, int begin_y, int begin_x); + +static PyObject * +_curses_newwin(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + int group_right_1 = 0; + int begin_y = 0; + int begin_x = 0; + + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "ii:newwin", &nlines, &ncols)) { + goto exit; + } + break; + case 4: + if (!PyArg_ParseTuple(args, "iiii:newwin", &nlines, &ncols, &begin_y, &begin_x)) { + goto exit; + } + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "_curses.newwin requires 2 to 4 arguments"); + goto exit; + } + return_value = _curses_newwin_impl(module, nlines, ncols, group_right_1, begin_y, begin_x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nl__doc__, +"nl($module, flag=True, /)\n" +"--\n" +"\n" +"Enter newline mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling nonl().\n" +"\n" +"This mode translates the return key into newline on input, and translates\n" +"newline into return and line-feed on output. Newline mode is initially on."); + +#define _CURSES_NL_METHODDEF \ + {"nl", (PyCFunction)_curses_nl, METH_FASTCALL, _curses_nl__doc__}, + +static PyObject * +_curses_nl_impl(PyObject *module, int flag); + +static PyObject * +_curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:nl", + &flag)) { + goto exit; + } + return_value = _curses_nl_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_nocbreak__doc__, +"nocbreak($module, /)\n" +"--\n" +"\n" +"Leave cbreak mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NOCBREAK_METHODDEF \ + {"nocbreak", (PyCFunction)_curses_nocbreak, METH_NOARGS, _curses_nocbreak__doc__}, + +static PyObject * +_curses_nocbreak_impl(PyObject *module); + +static PyObject * +_curses_nocbreak(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nocbreak_impl(module); +} + +PyDoc_STRVAR(_curses_noecho__doc__, +"noecho($module, /)\n" +"--\n" +"\n" +"Leave echo mode.\n" +"\n" +"Echoing of input characters is turned off."); + +#define _CURSES_NOECHO_METHODDEF \ + {"noecho", (PyCFunction)_curses_noecho, METH_NOARGS, _curses_noecho__doc__}, + +static PyObject * +_curses_noecho_impl(PyObject *module); + +static PyObject * +_curses_noecho(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noecho_impl(module); +} + +PyDoc_STRVAR(_curses_nonl__doc__, +"nonl($module, /)\n" +"--\n" +"\n" +"Leave newline mode.\n" +"\n" +"Disable translation of return into newline on input, and disable low-level\n" +"translation of newline into newline/return on output."); + +#define _CURSES_NONL_METHODDEF \ + {"nonl", (PyCFunction)_curses_nonl, METH_NOARGS, _curses_nonl__doc__}, + +static PyObject * +_curses_nonl_impl(PyObject *module); + +static PyObject * +_curses_nonl(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_nonl_impl(module); +} + +PyDoc_STRVAR(_curses_noqiflush__doc__, +"noqiflush($module, /)\n" +"--\n" +"\n" +"Disable queue flushing.\n" +"\n" +"When queue flushing is disabled, normal flush of input and output queues\n" +"associated with the INTR, QUIT and SUSP characters will not be done."); + +#define _CURSES_NOQIFLUSH_METHODDEF \ + {"noqiflush", (PyCFunction)_curses_noqiflush, METH_NOARGS, _curses_noqiflush__doc__}, + +static PyObject * +_curses_noqiflush_impl(PyObject *module); + +static PyObject * +_curses_noqiflush(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noqiflush_impl(module); +} + +PyDoc_STRVAR(_curses_noraw__doc__, +"noraw($module, /)\n" +"--\n" +"\n" +"Leave raw mode.\n" +"\n" +"Return to normal \"cooked\" mode with line buffering."); + +#define _CURSES_NORAW_METHODDEF \ + {"noraw", (PyCFunction)_curses_noraw, METH_NOARGS, _curses_noraw__doc__}, + +static PyObject * +_curses_noraw_impl(PyObject *module); + +static PyObject * +_curses_noraw(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_noraw_impl(module); +} + +PyDoc_STRVAR(_curses_pair_content__doc__, +"pair_content($module, pair_number, /)\n" +"--\n" +"\n" +"Return a tuple (fg, bg) containing the colors for the requested color pair.\n" +"\n" +" pair_number\n" +" The number of the color pair (1 - (COLOR_PAIRS-1))."); + +#define _CURSES_PAIR_CONTENT_METHODDEF \ + {"pair_content", (PyCFunction)_curses_pair_content, METH_O, _curses_pair_content__doc__}, + +static PyObject * +_curses_pair_content_impl(PyObject *module, short pair_number); + +static PyObject * +_curses_pair_content(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + short pair_number; + + if (!PyArg_Parse(arg, "h:pair_content", &pair_number)) { + goto exit; + } + return_value = _curses_pair_content_impl(module, pair_number); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_pair_number__doc__, +"pair_number($module, attr, /)\n" +"--\n" +"\n" +"Return the number of the color-pair set by the specified attribute value.\n" +"\n" +"color_pair() is the counterpart to this function."); + +#define _CURSES_PAIR_NUMBER_METHODDEF \ + {"pair_number", (PyCFunction)_curses_pair_number, METH_O, _curses_pair_number__doc__}, + +static PyObject * +_curses_pair_number_impl(PyObject *module, int attr); + +static PyObject * +_curses_pair_number(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int attr; + + if (!PyArg_Parse(arg, "i:pair_number", &attr)) { + goto exit; + } + return_value = _curses_pair_number_impl(module, attr); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_putp__doc__, +"putp($module, string, /)\n" +"--\n" +"\n" +"Emit the value of a specified terminfo capability for the current terminal.\n" +"\n" +"Note that the output of putp() always goes to standard output."); + +#define _CURSES_PUTP_METHODDEF \ + {"putp", (PyCFunction)_curses_putp, METH_O, _curses_putp__doc__}, + +static PyObject * +_curses_putp_impl(PyObject *module, const char *string); + +static PyObject * +_curses_putp(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *string; + + if (!PyArg_Parse(arg, "y:putp", &string)) { + goto exit; + } + return_value = _curses_putp_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_qiflush__doc__, +"qiflush($module, flag=True, /)\n" +"--\n" +"\n" +"Enable queue flushing.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noqiflush().\n" +"\n" +"If queue flushing is enabled, all output in the display driver queue\n" +"will be flushed when the INTR, QUIT and SUSP characters are read."); + +#define _CURSES_QIFLUSH_METHODDEF \ + {"qiflush", (PyCFunction)_curses_qiflush, METH_FASTCALL, _curses_qiflush__doc__}, + +static PyObject * +_curses_qiflush_impl(PyObject *module, int flag); + +static PyObject * +_curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:qiflush", + &flag)) { + goto exit; + } + return_value = _curses_qiflush_impl(module, flag); + +exit: + return return_value; +} + +#if (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) + +PyDoc_STRVAR(_curses_update_lines_cols__doc__, +"update_lines_cols($module, /)\n" +"--\n" +"\n"); + +#define _CURSES_UPDATE_LINES_COLS_METHODDEF \ + {"update_lines_cols", (PyCFunction)_curses_update_lines_cols, METH_NOARGS, _curses_update_lines_cols__doc__}, + +static int +_curses_update_lines_cols_impl(PyObject *module); + +static PyObject * +_curses_update_lines_cols(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = _curses_update_lines_cols_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) */ + +PyDoc_STRVAR(_curses_raw__doc__, +"raw($module, flag=True, /)\n" +"--\n" +"\n" +"Enter raw mode.\n" +"\n" +" flag\n" +" If false, the effect is the same as calling noraw().\n" +"\n" +"In raw mode, normal line buffering and processing of interrupt, quit,\n" +"suspend, and flow control keys are turned off; characters are presented to\n" +"curses input functions one by one."); + +#define _CURSES_RAW_METHODDEF \ + {"raw", (PyCFunction)_curses_raw, METH_FASTCALL, _curses_raw__doc__}, + +static PyObject * +_curses_raw_impl(PyObject *module, int flag); + +static PyObject * +_curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!_PyArg_ParseStack(args, nargs, "|i:raw", + &flag)) { + goto exit; + } + return_value = _curses_raw_impl(module, flag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_reset_prog_mode__doc__, +"reset_prog_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"program\" mode, as previously saved by def_prog_mode()."); + +#define _CURSES_RESET_PROG_MODE_METHODDEF \ + {"reset_prog_mode", (PyCFunction)_curses_reset_prog_mode, METH_NOARGS, _curses_reset_prog_mode__doc__}, + +static PyObject * +_curses_reset_prog_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_prog_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_prog_mode_impl(module); +} + +PyDoc_STRVAR(_curses_reset_shell_mode__doc__, +"reset_shell_mode($module, /)\n" +"--\n" +"\n" +"Restore the terminal to \"shell\" mode, as previously saved by def_shell_mode()."); + +#define _CURSES_RESET_SHELL_MODE_METHODDEF \ + {"reset_shell_mode", (PyCFunction)_curses_reset_shell_mode, METH_NOARGS, _curses_reset_shell_mode__doc__}, + +static PyObject * +_curses_reset_shell_mode_impl(PyObject *module); + +static PyObject * +_curses_reset_shell_mode(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_reset_shell_mode_impl(module); +} + +PyDoc_STRVAR(_curses_resetty__doc__, +"resetty($module, /)\n" +"--\n" +"\n" +"Restore terminal mode."); + +#define _CURSES_RESETTY_METHODDEF \ + {"resetty", (PyCFunction)_curses_resetty, METH_NOARGS, _curses_resetty__doc__}, + +static PyObject * +_curses_resetty_impl(PyObject *module); + +static PyObject * +_curses_resetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_resetty_impl(module); +} + +#if defined(HAVE_CURSES_RESIZETERM) + +PyDoc_STRVAR(_curses_resizeterm__doc__, +"resizeterm($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Resize the standard and current windows to the specified dimensions.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"Adjusts other bookkeeping data used by the curses library that record the\n" +"window dimensions (in particular the SIGWINCH handler)."); + +#define _CURSES_RESIZETERM_METHODDEF \ + {"resizeterm", (PyCFunction)_curses_resizeterm, METH_FASTCALL, _curses_resizeterm__doc__}, + +static PyObject * +_curses_resizeterm_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resizeterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:resizeterm", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_resizeterm_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZETERM) */ + +#if defined(HAVE_CURSES_RESIZE_TERM) + +PyDoc_STRVAR(_curses_resize_term__doc__, +"resize_term($module, nlines, ncols, /)\n" +"--\n" +"\n" +"Backend function used by resizeterm(), performing most of the work.\n" +"\n" +" nlines\n" +" Height.\n" +" ncols\n" +" Width.\n" +"\n" +"When resizing the windows, resize_term() blank-fills the areas that are\n" +"extended. The calling application should fill in these areas with appropriate\n" +"data. The resize_term() function attempts to resize all windows. However,\n" +"due to the calling convention of pads, it is not possible to resize these\n" +"without additional interaction with the application."); + +#define _CURSES_RESIZE_TERM_METHODDEF \ + {"resize_term", (PyCFunction)_curses_resize_term, METH_FASTCALL, _curses_resize_term__doc__}, + +static PyObject * +_curses_resize_term_impl(PyObject *module, int nlines, int ncols); + +static PyObject * +_curses_resize_term(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int nlines; + int ncols; + + if (!_PyArg_ParseStack(args, nargs, "ii:resize_term", + &nlines, &ncols)) { + goto exit; + } + return_value = _curses_resize_term_impl(module, nlines, ncols); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_RESIZE_TERM) */ + +PyDoc_STRVAR(_curses_savetty__doc__, +"savetty($module, /)\n" +"--\n" +"\n" +"Save terminal mode."); + +#define _CURSES_SAVETTY_METHODDEF \ + {"savetty", (PyCFunction)_curses_savetty, METH_NOARGS, _curses_savetty__doc__}, + +static PyObject * +_curses_savetty_impl(PyObject *module); + +static PyObject * +_curses_savetty(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_savetty_impl(module); +} + +#if defined(getsyx) + +PyDoc_STRVAR(_curses_setsyx__doc__, +"setsyx($module, y, x, /)\n" +"--\n" +"\n" +"Set the virtual screen cursor.\n" +"\n" +" y\n" +" Y-coordinate.\n" +" x\n" +" X-coordinate.\n" +"\n" +"If y and x are both -1, then leaveok is set."); + +#define _CURSES_SETSYX_METHODDEF \ + {"setsyx", (PyCFunction)_curses_setsyx, METH_FASTCALL, _curses_setsyx__doc__}, + +static PyObject * +_curses_setsyx_impl(PyObject *module, int y, int x); + +static PyObject * +_curses_setsyx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int y; + int x; + + if (!_PyArg_ParseStack(args, nargs, "ii:setsyx", + &y, &x)) { + goto exit; + } + return_value = _curses_setsyx_impl(module, y, x); + +exit: + return return_value; +} + +#endif /* defined(getsyx) */ + +PyDoc_STRVAR(_curses_start_color__doc__, +"start_color($module, /)\n" +"--\n" +"\n" +"Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.\n" +"\n" +"Must be called if the programmer wants to use colors, and before any other\n" +"color manipulation routine is called. It is good practice to call this\n" +"routine right after initscr().\n" +"\n" +"It also restores the colors on the terminal to the values they had when the\n" +"terminal was just turned on."); + +#define _CURSES_START_COLOR_METHODDEF \ + {"start_color", (PyCFunction)_curses_start_color, METH_NOARGS, _curses_start_color__doc__}, + +static PyObject * +_curses_start_color_impl(PyObject *module); + +static PyObject * +_curses_start_color(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_start_color_impl(module); +} + +PyDoc_STRVAR(_curses_termattrs__doc__, +"termattrs($module, /)\n" +"--\n" +"\n" +"Return a logical OR of all video attributes supported by the terminal."); + +#define _CURSES_TERMATTRS_METHODDEF \ + {"termattrs", (PyCFunction)_curses_termattrs, METH_NOARGS, _curses_termattrs__doc__}, + +static PyObject * +_curses_termattrs_impl(PyObject *module); + +static PyObject * +_curses_termattrs(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termattrs_impl(module); +} + +PyDoc_STRVAR(_curses_termname__doc__, +"termname($module, /)\n" +"--\n" +"\n" +"Return the value of the environment variable TERM, truncated to 14 characters."); + +#define _CURSES_TERMNAME_METHODDEF \ + {"termname", (PyCFunction)_curses_termname, METH_NOARGS, _curses_termname__doc__}, + +static PyObject * +_curses_termname_impl(PyObject *module); + +static PyObject * +_curses_termname(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_termname_impl(module); +} + +PyDoc_STRVAR(_curses_tigetflag__doc__, +"tigetflag($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the Boolean capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -1 is returned if capname is not a Boolean capability, or 0 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETFLAG_METHODDEF \ + {"tigetflag", (PyCFunction)_curses_tigetflag, METH_O, _curses_tigetflag__doc__}, + +static PyObject * +_curses_tigetflag_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetflag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetflag", &capname)) { + goto exit; + } + return_value = _curses_tigetflag_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetnum__doc__, +"tigetnum($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the numeric capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"The value -2 is returned if capname is not a numeric capability, or -1 if\n" +"it is canceled or absent from the terminal description."); + +#define _CURSES_TIGETNUM_METHODDEF \ + {"tigetnum", (PyCFunction)_curses_tigetnum, METH_O, _curses_tigetnum__doc__}, + +static PyObject * +_curses_tigetnum_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetnum(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetnum", &capname)) { + goto exit; + } + return_value = _curses_tigetnum_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tigetstr__doc__, +"tigetstr($module, capname, /)\n" +"--\n" +"\n" +"Return the value of the string capability.\n" +"\n" +" capname\n" +" The terminfo capability name.\n" +"\n" +"None is returned if capname is not a string capability, or is canceled or\n" +"absent from the terminal description."); + +#define _CURSES_TIGETSTR_METHODDEF \ + {"tigetstr", (PyCFunction)_curses_tigetstr, METH_O, _curses_tigetstr__doc__}, + +static PyObject * +_curses_tigetstr_impl(PyObject *module, const char *capname); + +static PyObject * +_curses_tigetstr(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *capname; + + if (!PyArg_Parse(arg, "s:tigetstr", &capname)) { + goto exit; + } + return_value = _curses_tigetstr_impl(module, capname); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_tparm__doc__, +"tparm($module, str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0,\n" +" i9=0, /)\n" +"--\n" +"\n" +"Instantiate the specified byte string with the supplied parameters.\n" +"\n" +" str\n" +" Parameterized byte string obtained from the terminfo database."); + +#define _CURSES_TPARM_METHODDEF \ + {"tparm", (PyCFunction)_curses_tparm, METH_FASTCALL, _curses_tparm__doc__}, + +static PyObject * +_curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, + int i4, int i5, int i6, int i7, int i8, int i9); + +static PyObject * +_curses_tparm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *str; + int i1 = 0; + int i2 = 0; + int i3 = 0; + int i4 = 0; + int i5 = 0; + int i6 = 0; + int i7 = 0; + int i8 = 0; + int i9 = 0; + + if (!_PyArg_ParseStack(args, nargs, "y|iiiiiiiii:tparm", + &str, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8, &i9)) { + goto exit; + } + return_value = _curses_tparm_impl(module, str, i1, i2, i3, i4, i5, i6, i7, i8, i9); + +exit: + return return_value; +} + +#if defined(HAVE_CURSES_TYPEAHEAD) + +PyDoc_STRVAR(_curses_typeahead__doc__, +"typeahead($module, fd, /)\n" +"--\n" +"\n" +"Specify that the file descriptor fd be used for typeahead checking.\n" +"\n" +" fd\n" +" File descriptor.\n" +"\n" +"If fd is -1, then no typeahead checking is done."); + +#define _CURSES_TYPEAHEAD_METHODDEF \ + {"typeahead", (PyCFunction)_curses_typeahead, METH_O, _curses_typeahead__doc__}, + +static PyObject * +_curses_typeahead_impl(PyObject *module, int fd); + +static PyObject * +_curses_typeahead(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:typeahead", &fd)) { + goto exit; + } + return_value = _curses_typeahead_impl(module, fd); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_TYPEAHEAD) */ + +PyDoc_STRVAR(_curses_unctrl__doc__, +"unctrl($module, ch, /)\n" +"--\n" +"\n" +"Return a string which is a printable representation of the character ch.\n" +"\n" +"Control characters are displayed as a caret followed by the character,\n" +"for example as ^C. Printing characters are left as they are."); + +#define _CURSES_UNCTRL_METHODDEF \ + {"unctrl", (PyCFunction)_curses_unctrl, METH_O, _curses_unctrl__doc__}, + +PyDoc_STRVAR(_curses_ungetch__doc__, +"ungetch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next getch() will return it."); + +#define _CURSES_UNGETCH_METHODDEF \ + {"ungetch", (PyCFunction)_curses_ungetch, METH_O, _curses_ungetch__doc__}, + +#if defined(HAVE_NCURSESW) + +PyDoc_STRVAR(_curses_unget_wch__doc__, +"unget_wch($module, ch, /)\n" +"--\n" +"\n" +"Push ch so the next get_wch() will return it."); + +#define _CURSES_UNGET_WCH_METHODDEF \ + {"unget_wch", (PyCFunction)_curses_unget_wch, METH_O, _curses_unget_wch__doc__}, + +#endif /* defined(HAVE_NCURSESW) */ + +#if defined(HAVE_CURSES_USE_ENV) + +PyDoc_STRVAR(_curses_use_env__doc__, +"use_env($module, flag, /)\n" +"--\n" +"\n" +"Use environment variables LINES and COLUMNS.\n" +"\n" +"If used, this function should be called before initscr() or newterm() are\n" +"called.\n" +"\n" +"When flag is False, the values of lines and columns specified in the terminfo\n" +"database will be used, even if environment variables LINES and COLUMNS (used\n" +"by default) are set, or if curses is running in a window (in which case\n" +"default behavior would be to use the window size if LINES and COLUMNS are\n" +"not set)."); + +#define _CURSES_USE_ENV_METHODDEF \ + {"use_env", (PyCFunction)_curses_use_env, METH_O, _curses_use_env__doc__}, + +static PyObject * +_curses_use_env_impl(PyObject *module, int flag); + +static PyObject * +_curses_use_env(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flag; + + if (!PyArg_Parse(arg, "i:use_env", &flag)) { + goto exit; + } + return_value = _curses_use_env_impl(module, flag); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CURSES_USE_ENV) */ + +#if !defined(STRICT_SYSV_CURSES) + +PyDoc_STRVAR(_curses_use_default_colors__doc__, +"use_default_colors($module, /)\n" +"--\n" +"\n" +"Allow use of default values for colors on terminals supporting this feature.\n" +"\n" +"Use this to support transparency in your application. The default color\n" +"is assigned to the color number -1."); + +#define _CURSES_USE_DEFAULT_COLORS_METHODDEF \ + {"use_default_colors", (PyCFunction)_curses_use_default_colors, METH_NOARGS, _curses_use_default_colors__doc__}, + +static PyObject * +_curses_use_default_colors_impl(PyObject *module); + +static PyObject * +_curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_use_default_colors_impl(module); +} + +#endif /* !defined(STRICT_SYSV_CURSES) */ + +#ifndef _CURSES_WINDOW_ENCLOSE_METHODDEF + #define _CURSES_WINDOW_ENCLOSE_METHODDEF +#endif /* !defined(_CURSES_WINDOW_ENCLOSE_METHODDEF) */ + +#ifndef _CURSES_WINDOW_GET_WCH_METHODDEF + #define _CURSES_WINDOW_GET_WCH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_GET_WCH_METHODDEF) */ + +#ifndef _CURSES_WINDOW_NOUTREFRESH_METHODDEF + #define _CURSES_WINDOW_NOUTREFRESH_METHODDEF +#endif /* !defined(_CURSES_WINDOW_NOUTREFRESH_METHODDEF) */ + +#ifndef _CURSES_FILTER_METHODDEF + #define _CURSES_FILTER_METHODDEF +#endif /* !defined(_CURSES_FILTER_METHODDEF) */ + +#ifndef _CURSES_GETSYX_METHODDEF + #define _CURSES_GETSYX_METHODDEF +#endif /* !defined(_CURSES_GETSYX_METHODDEF) */ + +#ifndef _CURSES_GETMOUSE_METHODDEF + #define _CURSES_GETMOUSE_METHODDEF +#endif /* !defined(_CURSES_GETMOUSE_METHODDEF) */ + +#ifndef _CURSES_UNGETMOUSE_METHODDEF + #define _CURSES_UNGETMOUSE_METHODDEF +#endif /* !defined(_CURSES_UNGETMOUSE_METHODDEF) */ + +#ifndef _CURSES_HAS_KEY_METHODDEF + #define _CURSES_HAS_KEY_METHODDEF +#endif /* !defined(_CURSES_HAS_KEY_METHODDEF) */ + +#ifndef _CURSES_IS_TERM_RESIZED_METHODDEF + #define _CURSES_IS_TERM_RESIZED_METHODDEF +#endif /* !defined(_CURSES_IS_TERM_RESIZED_METHODDEF) */ + +#ifndef _CURSES_MOUSEINTERVAL_METHODDEF + #define _CURSES_MOUSEINTERVAL_METHODDEF +#endif /* !defined(_CURSES_MOUSEINTERVAL_METHODDEF) */ + +#ifndef _CURSES_MOUSEMASK_METHODDEF + #define _CURSES_MOUSEMASK_METHODDEF +#endif /* !defined(_CURSES_MOUSEMASK_METHODDEF) */ + +#ifndef _CURSES_UPDATE_LINES_COLS_METHODDEF + #define _CURSES_UPDATE_LINES_COLS_METHODDEF +#endif /* !defined(_CURSES_UPDATE_LINES_COLS_METHODDEF) */ + +#ifndef _CURSES_RESIZETERM_METHODDEF + #define _CURSES_RESIZETERM_METHODDEF +#endif /* !defined(_CURSES_RESIZETERM_METHODDEF) */ + +#ifndef _CURSES_RESIZE_TERM_METHODDEF + #define _CURSES_RESIZE_TERM_METHODDEF +#endif /* !defined(_CURSES_RESIZE_TERM_METHODDEF) */ + +#ifndef _CURSES_SETSYX_METHODDEF + #define _CURSES_SETSYX_METHODDEF +#endif /* !defined(_CURSES_SETSYX_METHODDEF) */ + +#ifndef _CURSES_TYPEAHEAD_METHODDEF + #define _CURSES_TYPEAHEAD_METHODDEF +#endif /* !defined(_CURSES_TYPEAHEAD_METHODDEF) */ + +#ifndef _CURSES_UNGET_WCH_METHODDEF + #define _CURSES_UNGET_WCH_METHODDEF +#endif /* !defined(_CURSES_UNGET_WCH_METHODDEF) */ + +#ifndef _CURSES_USE_ENV_METHODDEF + #define _CURSES_USE_ENV_METHODDEF +#endif /* !defined(_CURSES_USE_ENV_METHODDEF) */ + +#ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF + #define _CURSES_USE_DEFAULT_COLORS_METHODDEF +#endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ +/*[clinic end generated code: output=763ffe3abc3a97c7 input=a9049054013a1b77]*/ From solipsis at pitrou.net Thu May 10 05:07:59 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 10 May 2018 09:07:59 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=7 Message-ID: <20180510090759.1.3D97FF63F0E7EA37@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 7, -7] memory blocks, sum=0 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [0, -1, 2] memory blocks, sum=1 test_multiprocessing_forkserver leaked [2, -1, 1] memory blocks, sum=2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogOYS5Kn', '--timeout', '7200'] From webhook-mailer at python.org Thu May 10 09:38:54 2018 From: webhook-mailer at python.org (Nick Coghlan) Date: Thu, 10 May 2018 13:38:54 -0000 Subject: [Python-checkins] bpo-26701: Tweak the documentation for special methods in int(). (GH-6741) Message-ID: https://github.com/python/cpython/commit/df00f048250b9a07195b0e3b1c5c0161fdcc9db8 commit: df00f048250b9a07195b0e3b1c5c0161fdcc9db8 branch: master author: Serhiy Storchaka committer: Nick Coghlan date: 2018-05-10T23:38:44+10:00 summary: bpo-26701: Tweak the documentation for special methods in int(). (GH-6741) files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 2d15001bffa7..3b05a3a4ed32 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -671,8 +671,8 @@ are always available. They are listed here in alphabetical order. .. function:: hex(x) Convert an integer number to a lowercase hexadecim