]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Merged revisions 69350 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Fri, 6 Feb 2009 02:50:18 +0000 (02:50 +0000)
committerBenjamin Peterson <benjamin@python.org>
Fri, 6 Feb 2009 02:50:18 +0000 (02:50 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r69350 | benjamin.peterson | 2009-02-05 20:40:07 -0600 (Thu, 05 Feb 2009) | 96 lines

  Merged revisions 69129-69131,69139-69140,69143,69154-69159,69169,69288-69289,69293,69297-69301,69348 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r69129 | benjamin.peterson | 2009-01-30 19:42:55 -0600 (Fri, 30 Jan 2009) | 1 line

    check the errno in bad fd cases
  ........
    r69130 | andrew.kuchling | 2009-01-30 20:50:09 -0600 (Fri, 30 Jan 2009) | 1 line

    Add a section
  ........
    r69131 | andrew.kuchling | 2009-01-30 21:26:02 -0600 (Fri, 30 Jan 2009) | 1 line

    Text edits and markup fixes
  ........
    r69139 | mark.dickinson | 2009-01-31 10:44:04 -0600 (Sat, 31 Jan 2009) | 2 lines

    Add an extra test for long <-> float hash equivalence.
  ........
    r69140 | benjamin.peterson | 2009-01-31 10:52:03 -0600 (Sat, 31 Jan 2009) | 1 line

    PyErr_BadInternalCall() raises a SystemError, not TypeError #5112
  ........
    r69143 | benjamin.peterson | 2009-01-31 15:00:10 -0600 (Sat, 31 Jan 2009) | 1 line

    I believe the intention here was to avoid a global lookup
  ........
    r69154 | benjamin.peterson | 2009-01-31 16:33:02 -0600 (Sat, 31 Jan 2009) | 1 line

    fix indentation in comment
  ........
    r69155 | david.goodger | 2009-01-31 16:53:46 -0600 (Sat, 31 Jan 2009) | 1 line

    markup fix
  ........
    r69156 | gregory.p.smith | 2009-01-31 16:57:30 -0600 (Sat, 31 Jan 2009) | 4 lines

    - Issue #5104: The socket module now raises OverflowError when 16-bit port and
      protocol numbers are supplied outside the allowed 0-65536 range on bind()
      and getservbyport().
  ........
    r69157 | benjamin.peterson | 2009-01-31 17:43:25 -0600 (Sat, 31 Jan 2009) | 1 line

    add explanatory comment
  ........
    r69158 | benjamin.peterson | 2009-01-31 17:54:38 -0600 (Sat, 31 Jan 2009) | 1 line

    more flags which only work for function blocks
  ........
    r69159 | gregory.p.smith | 2009-01-31 18:16:01 -0600 (Sat, 31 Jan 2009) | 2 lines

    Update doc wording as suggested in issue4903.
  ........
    r69169 | guilherme.polo | 2009-01-31 20:56:16 -0600 (Sat, 31 Jan 2009) | 3 lines

    Restore Tkinter.Tk._loadtk so this test doesn't fail for problems
    related to ttk.
  ........
    r69288 | georg.brandl | 2009-02-05 04:30:57 -0600 (Thu, 05 Feb 2009) | 1 line

    #5153: fix typo in example.
  ........
    r69289 | georg.brandl | 2009-02-05 04:37:07 -0600 (Thu, 05 Feb 2009) | 1 line

    #5144: document that PySys_SetArgv prepends the script directory (or the empty string) to sys.path.
  ........
    r69293 | georg.brandl | 2009-02-05 04:59:28 -0600 (Thu, 05 Feb 2009) | 1 line

    #5059: fix example.
  ........
    r69297 | georg.brandl | 2009-02-05 05:32:18 -0600 (Thu, 05 Feb 2009) | 1 line

    #5015: document PythonHome API functions.
  ........
    r69298 | georg.brandl | 2009-02-05 05:33:21 -0600 (Thu, 05 Feb 2009) | 1 line

    #4827: fix callback example.
  ........
    r69299 | georg.brandl | 2009-02-05 05:35:28 -0600 (Thu, 05 Feb 2009) | 1 line

    #4820: use correct module for ctypes.util.
  ........
    r69300 | georg.brandl | 2009-02-05 05:38:23 -0600 (Thu, 05 Feb 2009) | 1 line

    #4563: disable alpha and roman lists, fixes wrong formatting of contributor list.
  ........
    r69301 | georg.brandl | 2009-02-05 05:40:35 -0600 (Thu, 05 Feb 2009) | 1 line

    #5031: fix Thread.daemon property docs.
  ........
    r69348 | benjamin.peterson | 2009-02-05 19:47:31 -0600 (Thu, 05 Feb 2009) | 1 line

    fix download link
  ........
................

17 files changed:
Doc/c-api/exceptions.rst
Doc/c-api/init.rst
Doc/library/ctypes.rst
Doc/library/optparse.rst
Doc/library/threading.rst
Doc/tools/sphinxext/download.html
Doc/tools/sphinxext/pyspecific.py
Doc/tutorial/floatingpoint.rst
Doc/whatsnew/2.7.rst
Lib/heapq.py
Lib/test/test_hash.py
Lib/test/test_os.py
Lib/test/test_socket.py
Lib/test/test_tcl.py
Misc/NEWS
Modules/socketmodule.c
Python/compile.c

index 3fb6e567bf6694a3ab1c3f03cee15a583893d716..e8112df41c2718f07bb6b0bf15ded2f23804aa4c 100644 (file)
@@ -271,9 +271,10 @@ in various ways.  There is a separate error indicator for each thread.
 
 .. cfunction:: void PyErr_BadInternalCall()
 
-   This is a shorthand for ``PyErr_SetString(PyExc_TypeError, message)``, where
-   *message* indicates that an internal operation (e.g. a Python/C API function)
-   was invoked with an illegal argument.  It is mostly for internal use.
+   This is a shorthand for ``PyErr_SetString(PyExc_SystemError, message)``,
+   where *message* indicates that an internal operation (e.g. a Python/C API
+   function) was invoked with an illegal argument.  It is mostly for internal
+   use.
 
 
 .. cfunction:: int PyErr_WarnEx(PyObject *category, char *message, int stacklevel)
index 0ac8d5b60c3663eb08d23830a738d4f6de0a94af..3e5f3f4efd7d258709a891b1de6c67b18144335b 100644 (file)
@@ -350,18 +350,36 @@ Initialization, Finalization, and Threads
       single: Py_FatalError()
       single: argv (in module sys)
 
-   Set ``sys.argv`` based on *argc* and *argv*.  These parameters are similar to
-   those passed to the program's :cfunc:`main` function with the difference that
-   the first entry should refer to the script file to be executed rather than the
-   executable hosting the Python interpreter.  If there isn't a script that will be
-   run, the first entry in *argv* can be an empty string.  If this function fails
-   to initialize ``sys.argv``, a fatal condition is signalled using
-   :cfunc:`Py_FatalError`.
+   Set :data:`sys.argv` based on *argc* and *argv*.  These parameters are
+   similar to those passed to the program's :cfunc:`main` function with the
+   difference that the first entry should refer to the script file to be
+   executed rather than the executable hosting the Python interpreter.  If there
+   isn't a script that will be run, the first entry in *argv* can be an empty
+   string.  If this function fails to initialize :data:`sys.argv`, a fatal
+   condition is signalled using :cfunc:`Py_FatalError`.
+
+   This function also prepends the executed script's path to :data:`sys.path`.
+   If no script is executed (in the case of calling ``python -c`` or just the
+   interactive interpreter), the empty string is used instead.
 
    .. XXX impl. doesn't seem consistent in allowing 0/NULL for the params;
       check w/ Guido.
 
 
+.. cfunction:: void Py_SetPythonHome(char *home)
+
+   Set the default "home" directory, that is, the location of the standard
+   Python libraries.  The libraries are searched in
+   :file:`{home}/lib/python{version}` and :file:`{home}/lib/python{version}`.
+
+
+.. cfunction:: char* Py_GetPythonHome()
+
+   Return the default "home", that is, the value set by a previous call to
+   :cfunc:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME`
+   environment variable if it is set.
+
+
 .. _threads:
 
 Thread State and the Global Interpreter Lock
index 47f9819b4fcffca8dabb0ad66ab2456f58fa719c..e389a633315ee819e57a3d743541830652e6590e 100644 (file)
@@ -1272,6 +1272,7 @@ library to load.
 
 
 .. data:: find_library(name)
+   :module: ctypes.util
    :noindex:
 
    Try to find a library and return a pathname.  *name* is the library name without
index 4e9bb2384a438ba3b06996945a52d12fb4f82ed6..2cf804226e1dd655c41e68aff1ad65f88a4c2f9b 100644 (file)
@@ -1506,7 +1506,7 @@ Here's an example of a callback option that takes no arguments, and simply
 records that the option was seen::
 
    def record_foo_seen(option, opt_str, value, parser):
-       parser.saw_foo = True
+       parser.values.saw_foo = True
 
    parser.add_option("--foo", action="callback", callback=record_foo_seen)
 
@@ -1646,7 +1646,7 @@ arguments::
             value.append(arg)
 
         del parser.rargs[:len(value)]
-        setattr(parser.values, option.dest, value))
+        setattr(parser.values, option.dest, value)
 
    [...]
    parser.add_option("-c", "--callback", dest="vararg_attr",
index 769afd4ffec917a5a3a27a74d1d6be61c08ccc03..609056869bd2e0c034259632c138bf39a247888d 100644 (file)
@@ -198,7 +198,7 @@ changed through the :attr:`name` attribute.
 A thread can be flagged as a "daemon thread".  The significance of this flag is
 that the entire Python program exits when only daemon threads are left.  The
 initial value is inherited from the creating thread.  The flag can be set
-through the :attr:`daemon` attribute.
+through the :attr:`daemon` property.
 
 There is a "main thread" object; this corresponds to the initial thread of
 control in the Python program.  It is not a daemon thread.
@@ -312,10 +312,11 @@ impossible to detect the termination of alien threads.
 
 .. attribute:: Thread.daemon
 
-   The thread's daemon flag. This must be set before :meth:`start` is called,
-   otherwise :exc:`RuntimeError` is raised.
-
-   The initial value is inherited from the creating thread.
+   A boolean value indicating whether this thread is a daemon thread (True) or
+   not (False).  This must be set before :meth:`start` is called, otherwise
+   :exc:`RuntimeError` is raised.  Its initial value is inherited from the
+   creating thread; the main thread is not a daemon thread and therefore all
+   threads created in the main thread default to :attr:`daemon` = ``False``.
 
    The entire Python program exits when no alive non-daemon threads are left.
 
index 0de9c2a062746e9c9692b2d2ad45cb6a1280cf41..22a03a0d2fb503c27b8a8920ebb6aca88fc3ad0b 100644 (file)
@@ -31,7 +31,7 @@ in the table are the size of the download files in megabytes.</p>
     <td><a href="{{ dlbase }}/python-{{ release }}-docs-html.tar.bz2">Download</a> (ca. 4 MB)</td>
   </tr>
   <tr><td>Plain Text</td>
-    <td><a href="{{ dlbase }}/python-{{ release }}-text.zip">Download</a> (ca. 2 MB)</td>
+    <td><a href="{{ dlbase }}/python-{{ release }}-docs-text.zip">Download</a> (ca. 2 MB)</td>
     <td><a href="{{ dlbase }}/python-{{ release }}-docs-text.tar.bz2">Download</a> (ca. 1.5 MB)</td>
   </tr>
 </table>
index 66a0afc294965d8ad8c1257a7b34f106bc201a11..be0da34683aed4d82abecb8d9f4195fe342c86c4 100644 (file)
@@ -13,6 +13,14 @@ ISSUE_URI = 'http://bugs.python.org/issue%s'
 
 from docutils import nodes, utils
 
+# monkey-patch reST parser to disable alphabetic and roman enumerated lists
+from docutils.parsers.rst.states import Body
+Body.enum.converters['loweralpha'] = \
+    Body.enum.converters['upperalpha'] = \
+    Body.enum.converters['lowerroman'] = \
+    Body.enum.converters['upperroman'] = lambda x: None
+
+
 def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
     issue = utils.unescape(text)
     text = 'issue ' + issue
index a38a53ef5ad497e9f477c52121ac21ffcc4d9f12..f41be3a038e24838308192ab9cd270a23494e88b 100644 (file)
@@ -200,7 +200,7 @@ Why is that?  1/10 is not exactly representable as a binary fraction. Almost all
 machines today (November 2000) use IEEE-754 floating point arithmetic, and
 almost all platforms map Python floats to IEEE-754 "double precision".  754
 doubles contain 53 bits of precision, so on input the computer strives to
-convert 0.1 to the closest fraction it can of the form *J*/2\*\**N* where *J* is
+convert 0.1 to the closest fraction it can of the form *J*/2**\ *N* where *J* is
 an integer containing exactly 53 bits.  Rewriting ::
 
    1 / 10 ~= J / (2**N)
index 2c295c551ed30e16eb8d0bddd7be61344e8bdd1a..cb9aad8173b39ac01e266cf2304375f25f3e0a6d 100644 (file)
@@ -108,6 +108,23 @@ changes, or look through the Subversion logs for all the details.
 .. ======================================================================
 .. whole new modules get described in subsections here
 
+ttk: Themed Widgets for Tk
+--------------------------
+
+Tcl/Tk 8.5 includes a set of themed widgets that re-implement basic Tk
+widgets but have a more customizable appearance and can therefore more
+closely resemble the native platform's widgets.  This widget
+set was originally called Tile, but was renamed to Ttk (for "themed Tk")
+on being added to Tcl/Tck release 8.5.
+
+XXX write a brief discussion and an example here.
+
+The :mod:`ttk` module was written by Guilherme Polo and added in
+:issue:`2983`.  An alternate version called ``Tile.py``, written by
+Martin Franklin and maintained by Kevin Walzer, was proposed for
+inclusion in :issue:`2618`, but the authors argued that Guilherme
+Polo's work was more comprehensive.
+
 .. ======================================================================
 
 
index 48111d5b90e73d85ef98be53b1471a06d38ed8f8..55a3027eb6e27f4c68ccb2532905bb8da057feca 100644 (file)
@@ -195,7 +195,7 @@ def nlargest(n, iterable):
     heapify(result)
     _heappushpop = heappushpop
     for elem in it:
-        heappushpop(result, elem)
+        _heappushpop(result, elem)
     result.sort(reverse=True)
     return result
 
index 5881d03c51423191f0b3ecad76cd4ae71e65864a..4cbbe78424ed360a7b80c161f1031474ffdbfa09 100644 (file)
@@ -33,6 +33,7 @@ class HashEqualityTestCase(unittest.TestCase):
         # for 64-bit platforms
         self.same_hash(int(2**31), float(2**31))
         self.same_hash(int(-2**63), float(-2**63))
+        self.same_hash(long(2**63), float(2**63))
 
     def test_coerced_floats(self):
         self.same_hash(int(1.23e300), float(1.23e300))
index 4897aaf713a9bb90c0afea90cf2a1b28c380972c..5fb3c2673fc4eaf574e6c61d7077dbe1efdec227 100644 (file)
@@ -3,6 +3,7 @@
 # portable than they had been thought to be.
 
 import os
+import errno
 import unittest
 import warnings
 import sys
@@ -277,7 +278,6 @@ class StatAttributeTests(unittest.TestCase):
             result = os.statvfs(self.fname)
         except OSError as e:
             # On AtheOS, glibc always returns ENOSYS
-            import errno
             if e.errno == errno.ENOSYS:
                 return
 
@@ -587,6 +587,71 @@ class Win32ErrorTests(unittest.TestCase):
     def test_chmod(self):
         self.assertRaises(WindowsError, os.utime, support.TESTFN, 0)
 
+
+class TestInvalidFD(unittest.TestCase):
+    singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
+               "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
+    #singles.append("close")
+    #We omit close because it doesn'r raise an exception on some platforms
+    def get_single(f):
+        def helper(self):
+            if  hasattr(os, f):
+                self.check(getattr(os, f))
+        return helper
+    for f in singles:
+        locals()["test_"+f] = get_single(f)
+
+    def check(self, f, *args):
+        try:
+            f(support.make_bad_fd(), *args)
+        except OSError as e:
+            self.assertEqual(e.errno, errno.EBADF)
+        else:
+            self.fail("%r didn't raise a OSError with a bad file descriptor"
+                      % f)
+
+    def test_isatty(self):
+        if hasattr(os, "isatty"):
+            self.assertEqual(os.isatty(support.make_bad_fd()), False)
+
+    def test_closerange(self):
+        if hasattr(os, "closerange"):
+            fd = support.make_bad_fd()
+            self.assertEqual(os.closerange(fd, fd + 10), None)
+
+    def test_dup2(self):
+        if hasattr(os, "dup2"):
+            self.check(os.dup2, 20)
+
+    def test_fchmod(self):
+        if hasattr(os, "fchmod"):
+            self.check(os.fchmod, 0)
+
+    def test_fchown(self):
+        if hasattr(os, "fchown"):
+            self.check(os.fchown, -1, -1)
+
+    def test_fpathconf(self):
+        if hasattr(os, "fpathconf"):
+            self.check(os.fpathconf, "PC_NAME_MAX")
+
+    def test_lseek(self):
+        if hasattr(os, "lseek"):
+            self.check(os.lseek, 0, 0)
+
+    def test_read(self):
+        if hasattr(os, "read"):
+            self.check(os.read, 1)
+
+    def test_tcsetpgrpt(self):
+        if hasattr(os, "tcsetpgrp"):
+            self.check(os.tcsetpgrp, 0)
+
+    def test_write(self):
+        if hasattr(os, "write"):
+            self.check(os.write, b" ")
+
+
 if sys.platform != 'win32':
     class Win32ErrorTests(unittest.TestCase):
         pass
index 731827c84b9710f777df90435e45261f4d95a613..429ec6f978d0b78f078d1274467bb1a85f547b65 100644 (file)
@@ -366,6 +366,9 @@ class GeneralModuleTests(unittest.TestCase):
         eq(socket.getservbyport(port, 'tcp'), service)
         if udpport is not None:
             eq(socket.getservbyport(udpport, 'udp'), service)
+        # Make sure getservbyport does not accept out of range ports.
+        self.assertRaises(OverflowError, socket.getservbyport, -1)
+        self.assertRaises(OverflowError, socket.getservbyport, 65536)
 
     def testDefaultTimeout(self):
         # Testing default timeout
@@ -466,15 +469,23 @@ class GeneralModuleTests(unittest.TestCase):
 
     # XXX The following don't test module-level functionality...
 
-    def testSockName(self):
-        # Testing getsockname().  Use a temporary socket to elicit an unused
-        # ephemeral port that we can use later in the test.
+    def _get_unused_port(self, bind_address='0.0.0.0'):
+        """Use a temporary socket to elicit an unused ephemeral port.
+
+        Args:
+            bind_address: Hostname or IP address to search for a port on.
+
+        Returns: A most likely to be unused port.
+        """
         tempsock = socket.socket()
-        tempsock.bind(("0.0.0.0", 0))
-        (host, port) = tempsock.getsockname()
+        tempsock.bind((bind_address, 0))
+        host, port = tempsock.getsockname()
         tempsock.close()
-        del tempsock
+        return port
 
+    def testSockName(self):
+        # Testing getsockname()
+        port = self._get_unused_port()
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         sock.bind(("0.0.0.0", port))
         name = sock.getsockname()
@@ -514,6 +525,19 @@ class GeneralModuleTests(unittest.TestCase):
         self.assertEqual(sock.proto, 0)
         sock.close()
 
+    def test_getsockaddrarg(self):
+        host = '0.0.0.0'
+        port = self._get_unused_port(bind_address=host)
+        big_port = port + 65536
+        neg_port = port - 65536
+        sock = socket.socket()
+        try:
+            self.assertRaises(OverflowError, sock.bind, (host, big_port))
+            self.assertRaises(OverflowError, sock.bind, (host, neg_port))
+            sock.bind((host, port))
+        finally:
+            sock.close()
+
     def test_sock_ioctl(self):
         if os.name != "nt":
             return
index fa1727c81f2582d91fefd13da0bf89ff9339022f..4d92b268b8e631686a6b609a87181df03011b9af 100644 (file)
@@ -4,9 +4,15 @@ import unittest
 import os
 import _tkinter
 from test import support
-from tkinter import Tcl
+from tkinter import Tk, Tcl
 from _tkinter import TclError
 
+# Restore Tkinter.Tk._loadtk that may have been overridden by ttk.
+# If this is not done then this test may fail for reasons related
+# to ttk only (like failing to load the tile package).
+from ttk import __loadtk__
+Tk._loadtk = __loadtk__
+
 
 class TkinterTest(unittest.TestCase):
 
index a66b1461ca71671948f391db649fc99aee27d328..492e0c5db30d0942f7e8432fb92b658e128a3902 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -253,6 +253,10 @@ Library
 - Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on
   biarch systems. Try to rely on ldconfig only, without using objdump and gcc.
 
+- Issue #5104: The socket module now raises OverflowError when 16-bit port and
+  protocol numbers are supplied outside the allowed 0-65536 range on bind()
+  and getservbyport().
+
 Tools/Demos
 -----------
 
index a302dc5fa3a94e3fed2884179df9b714d5e2bf39..f9f486e63157ade1d230743b088795c511321aca 100644 (file)
@@ -1223,6 +1223,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
                 PyMem_Free(host);
                 if (result < 0)
                        return 0;
+               if (port < 0 || port > 0xffff) {
+                       PyErr_SetString(
+                               PyExc_OverflowError,
+                               "getsockaddrarg: port must be 0-65535.");
+                       return 0;
+               }
                addr->sin_family = AF_INET;
                addr->sin_port = htons((short)port);
                *len_ret = sizeof *addr;
@@ -1255,6 +1261,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
                 PyMem_Free(host);
                 if (result < 0)
                        return 0;
+               if (port < 0 || port > 0xffff) {
+                       PyErr_SetString(
+                               PyExc_OverflowError,
+                               "getsockaddrarg: port must be 0-65535.");
+                       return 0;
+               }
                addr->sin6_family = s->sock_family;
                addr->sin6_port = htons((short)port);
                addr->sin6_flowinfo = flowinfo;
@@ -1381,6 +1393,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
                                  "Hardware address must be 8 bytes or less");
                  return 0;
                }
+               if (protoNumber < 0 || protoNumber > 0xffff) {
+                       PyErr_SetString(
+                               PyExc_OverflowError,
+                               "getsockaddrarg: protoNumber must be 0-65535.");
+                       return 0;
+               }
                addr = (struct sockaddr_ll*)addr_ret;
                addr->sll_family = AF_PACKET;
                addr->sll_protocol = htons((short)protoNumber);
@@ -3271,13 +3289,19 @@ otherwise any protocol will match.");
 static PyObject *
 socket_getservbyport(PyObject *self, PyObject *args)
 {
-       unsigned short port;
+       int port;
        char *proto=NULL;
        struct servent *sp;
-       if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto))
+       if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto))
+               return NULL;
+       if (port < 0 || port > 0xffff) {
+               PyErr_SetString(
+                       PyExc_OverflowError,
+                       "getservbyport: port must be 0-65535.");
                return NULL;
+       }
        Py_BEGIN_ALLOW_THREADS
-       sp = getservbyport(htons(port), proto);
+       sp = getservbyport(htons((short)port), proto);
        Py_END_ALLOW_THREADS
        if (sp == NULL) {
                PyErr_SetString(socket_error, "port/proto not found");
index 1d98c860803977726bf480b701f8d34637bde56e..2b3722e648061425a5fbc93b22aad52b9e803dde 100644 (file)
@@ -4016,6 +4016,8 @@ dict_keys_inorder(PyObject *dict, int offset)
                return NULL;
        while (PyDict_Next(dict, &pos, &k, &v)) {
                i = PyLong_AS_LONG(v);
+               /* The keys of the dictionary are tuples. (see compiler_add_o)
+                  The object we want is always first, though. */
                k = PyTuple_GET_ITEM(k, 0);
                Py_INCREF(k);
                assert((i - offset) < size);
@@ -4039,13 +4041,11 @@ compute_code_flags(struct compiler *c)
                        flags |= CO_NESTED;
                if (ste->ste_generator)
                        flags |= CO_GENERATOR;
+               if (ste->ste_varargs)
+                       flags |= CO_VARARGS;
+               if (ste->ste_varkeywords)
+                       flags |= CO_VARKEYWORDS;
        }
-       if (ste->ste_varargs)
-               flags |= CO_VARARGS;
-       if (ste->ste_varkeywords)
-               flags |= CO_VARKEYWORDS;
-       if (ste->ste_generator)
-               flags |= CO_GENERATOR;
 
        /* (Only) inherit compilerflags in PyCF_MASK */
        flags |= (c->c_flags->cf_flags & PyCF_MASK);