]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Merged revisions 59843-59863 via svnmerge from
authorChristian Heimes <christian@cheimes.de>
Wed, 9 Jan 2008 00:17:24 +0000 (00:17 +0000)
committerChristian Heimes <christian@cheimes.de>
Wed, 9 Jan 2008 00:17:24 +0000 (00:17 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59844 | raymond.hettinger | 2008-01-07 21:56:05 +0100 (Mon, 07 Jan 2008) | 1 line

  Use get() instead of pop() for the optimized version of _replace().
........
  r59847 | raymond.hettinger | 2008-01-07 22:33:51 +0100 (Mon, 07 Jan 2008) | 1 line

  Documentation nits.
........
  r59849 | raymond.hettinger | 2008-01-08 03:02:05 +0100 (Tue, 08 Jan 2008) | 1 line

  Expand comment.
........
  r59850 | raymond.hettinger | 2008-01-08 03:24:15 +0100 (Tue, 08 Jan 2008) | 1 line

  Docs on named tuple's naming conventions and limits of subclassing
........
  r59851 | christian.heimes | 2008-01-08 04:40:04 +0100 (Tue, 08 Jan 2008) | 1 line

  It's verbose, not debug
........
  r59852 | facundo.batista | 2008-01-08 13:25:20 +0100 (Tue, 08 Jan 2008) | 4 lines

  Issue #1757: The hash of a Decimal instance is no longer affected
  by the current context.  Thanks Mark Dickinson.
........
  r59853 | andrew.kuchling | 2008-01-08 15:30:55 +0100 (Tue, 08 Jan 2008) | 1 line

  Patch 1137: allow assigning to .buffer_size attribute of PyExpat.parser objects
........
  r59854 | andrew.kuchling | 2008-01-08 15:56:02 +0100 (Tue, 08 Jan 2008) | 1 line

  Patch 1114: fix compilation of curses module on 64-bit AIX, and any other LP64 platforms where attr_t isn't a C long
........
  r59856 | thomas.heller | 2008-01-08 16:15:09 +0100 (Tue, 08 Jan 2008) | 5 lines

  Use relative instead of absolute filenames in the C-level tracebacks.
  This prevents traceback prints pointing to files in this way:

    File "\loewis\25\python\Modules\_ctypes\callbacks.c", line 206, in 'calling callback function'
........
  r59857 | christian.heimes | 2008-01-08 16:46:10 +0100 (Tue, 08 Jan 2008) | 2 lines

  Added __enter__ and __exit__ functions to HKEY object
  Added ExpandEnvironmentStrings to the _winreg module.
........
  r59858 | georg.brandl | 2008-01-08 17:18:26 +0100 (Tue, 08 Jan 2008) | 2 lines

  Fix markup errors from r59857 and clarify key.__enter__/__exit__ docs
........
  r59860 | georg.brandl | 2008-01-08 20:42:30 +0100 (Tue, 08 Jan 2008) | 2 lines

  Better method for associating .py files with the interpreter.
........
  r59862 | facundo.batista | 2008-01-08 22:10:12 +0100 (Tue, 08 Jan 2008) | 9 lines

  Issue 846388. Adds a call to PyErr_CheckSignals to
  SRE_MATCH so that signal handlers can be invoked during
  long regular expression matches.  It also adds a new
  error return value indicating that an exception
  occurred in a signal handler during the match, allowing
  exceptions in the signal handler to propagate up to the
  main loop.  Thanks Josh Hoyt and Ralf Schmitt.
........

18 files changed:
Doc/library/_winreg.rst
Doc/library/collections.rst
Doc/library/pyexpat.rst
Doc/using/windows.rst
Doc/whatsnew/2.6.rst
Lib/collections.py
Lib/decimal.py
Lib/test/test_decimal.py
Lib/test/test_pyexpat.py
Lib/test/test_socket.py
Lib/test/test_winreg.py
Misc/ACKS
Modules/_ctypes/callbacks.c
Modules/_ctypes/callproc.c
Modules/_cursesmodule.c
Modules/_sre.c
Modules/pyexpat.c
PC/_winreg.c

index a3fe72b099691296186455c044ee56f51455f1aa..7ce34b4d8e7d1e258e99cd5e4ac8b4cfb5215d73 100644 (file)
@@ -131,6 +131,16 @@ This module offers the following functions:
    +-------+--------------------------------------------+
 
 
+.. function:: ExpandEnvironmentStrings(unicode)
+
+   Expands environment strings %NAME% in unicode string like const:`REG_EXPAND_SZ`::
+
+      >>> ExpandEnvironmentStrings(u"%windir%")
+      u"C:\\Windows"
+
+   .. versionadded:: 2.6
+
+
 .. function:: FlushKey(key)
 
    Writes all the attributes of a key to the registry.
@@ -416,3 +426,16 @@ handle, and also disconnect the Windows handle from the handle object.
    handle is not closed.  You would call this function when  you need the
    underlying Win32 handle to exist beyond the lifetime  of the handle object.
 
+.. method:: PyHKEY.__enter__()
+            PyHKEY.__exit__(\*exc_info)
+
+   The HKEY object implements :meth:`__enter__` and :meth:`__exit__` and thus
+   supports the context protocol for the :keyword:`with` statement::
+
+      with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key:
+          # ... work with key ...
+
+   will automatically close *key* when control leaves the :keyword:`with` block.
+
+   .. versionadded:: 2.6
+
index 2b8e27943e6b3eb11a1620ae500cd2c31a4d618e..0c440d6b6e20f3db9c37b3616aa7e293d7136c9a 100644 (file)
@@ -397,8 +397,8 @@ they add the ability to access fields by name instead of position index.
    method which lists the tuple contents in a ``name=value`` format.
 
    The *fieldnames* are a single string with each fieldname separated by whitespace
-   and/or commas (for example 'x y' or 'x, y').  Alternatively, the *fieldnames*
-   can be specified with a sequence of strings (such as ['x', 'y']).
+   and/or commas (for example 'x y' or 'x, y').  Alternatively, *fieldnames*
+   can be a sequence of strings (such as ['x', 'y']).
 
    Any valid Python identifier may be used for a fieldname except for names
    starting with an underscore.  Valid identifiers consist of letters, digits,
@@ -477,7 +477,8 @@ by the :mod:`csv` or :mod:`sqlite3` modules::
        print emp.name, emp.title
 
 In addition to the methods inherited from tuples, named tuples support
-three additional methods and one attribute.
+three additional methods and one attribute.  To prevent conflicts with
+field names, the method and attribute names start with an underscore.
 
 .. method:: somenamedtuple._make(iterable)
 
@@ -513,7 +514,7 @@ three additional methods and one attribute.
 
 .. attribute:: somenamedtuple._fields
 
-   Tuple of strings listing the field names.  This is useful for introspection
+   Tuple of strings listing the field names.  Useful for introspection
    and for creating new named tuple types from existing named tuples.
 
 ::
@@ -532,7 +533,7 @@ function::
     >>> getattr(p, 'x')
     11
 
-When casting a dictionary to a named tuple, use the double-star-operator [#]_::
+To cast a dictionary to a named tuple, use the double-star-operator [#]_::
 
    >>> d = {'x': 11, 'y': 22}
    >>> Point(**d)
@@ -557,14 +558,20 @@ a fixed-width print format::
     Point: x= 1.286 y= 6.000 hypot= 6.136
 
 Another use for subclassing is to replace performance critcal methods with
-faster versions that bypass error-checking and localize variable access::
+faster versions that bypass error-checking and that localize variable access::
 
     >>> class Point(namedtuple('Point', 'x y')):
         _make = classmethod(tuple.__new__)
         def _replace(self, _map=map, **kwds):
-            return self._make(_map(kwds.pop, ('x', 'y'), self))
+            return self._make(_map(kwds.get, ('x', 'y'), self))
 
-Default values can be implemented by using :meth:`_replace`:: to
+
+Subclassing is not useful for adding new, stored fields.  Instead, simply
+create a new named tuple type from the :attr:`_fields` attribute::
+
+    >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
+
+Default values can be implemented by using :meth:`_replace` to
 customize a prototype instance::
 
     >>> Account = namedtuple('Account', 'owner balance transaction_count')
index 29ca5407f210b12c4818b90839d6999f7790a02d..3a3305c0fc5d75d6b84fb5f75b0b7bdc301b72cf 100644 (file)
@@ -177,8 +177,13 @@ XMLParser Objects
 
 .. attribute:: xmlparser.buffer_size
 
-   The size of the buffer used when :attr:`buffer_text` is true.  This value cannot
-   be changed at this time.
+   The size of the buffer used when :attr:`buffer_text` is true.  
+   A new buffer size can be set by assigning a new integer value 
+   to this attribute.  
+   When the size is changed, the buffer will be flushed.
+
+   .. versionchanged:: 2.6
+      The buffer size can now be changed.
 
 
 .. attribute:: xmlparser.buffer_text
index 2b52544e045e420f6e57dade31e7e7a382ae0072..1753b6dbca9f3f7956110f7d1599a0110189d83a 100644 (file)
@@ -188,16 +188,17 @@ of your Python installation directory).  This suppresses the terminal window on
 startup.
 
 You can also make all ``.py`` scripts execute with :program:`pythonw.exe`,
-setting this through the usual facilites, for example (names might differ,
-depending on your version of Windows):
+setting this through the usual facilites, for example (might require
+administrative rights):
 
-#. Open the context menu of a :file:`{*}.py` file.
-#. Click :menuselection:`Open with...`.
-#. Choose the interpreter of your choice (utilize :guilabel:`Other...` or
-   :guilabel:`Choose Program...` if it is not in the list of default programs).
-#. Check :guilabel:`Always open files with this program`.
-#. Click :guilabel:`OK`.
+#. Launch a command prompt.
+#. Associate the correct file group with ``.py`` scripts::
+   
+      assoc .py=Python.File
 
+#. Redirect all Python files to the new executable::
+   
+      ftype Python.File=C:\Path\to\pythonw.exe "%1" %*
 
 
 Additional modules
index fee298deef6ec2067ae06a6e75a84d85b7261f32..4d90d3503e18f35d6853535911a15aad31cd63b9 100644 (file)
@@ -875,6 +875,13 @@ complete list of changes, or look through the CVS logs for all the details.
   changed and :const:`UF_APPEND` to indicate that data can only be appended to the
   file.  (Contributed by M. Levinson.)
 
+* The :mod:`pyexpat` module's :class:`Parser` objects now allow setting
+  their :attr:`buffer_size` attribute to change the size of the buffer 
+  used to hold character data.
+  (Contributed by Achim Gaedke.)
+
+  .. Patch 1137
+
 * The :mod:`random` module's :class:`Random` objects can
   now be pickled on a 32-bit system and unpickled on a 64-bit
   system, and vice versa.  Unfortunately, this change also means
index 2f0d038a813102eecd5c5218bf1a2ac75e54b9e5..e1e9d11a6c231954272a6d922c5659843328f521 100644 (file)
@@ -34,7 +34,8 @@ def namedtuple(typename, field_names, verbose=False):
 
     """
 
-    # Parse and validate the field names
+    # Parse and validate the field names.  Validation serves two purposes,
+    # generating informative error messages and preventing template injection attacks.
     if isinstance(field_names, str):
         field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas
     field_names = tuple(field_names)
@@ -129,7 +130,7 @@ if __name__ == '__main__':
         'Point class with optimized _make() and _replace() without error-checking'
         _make = classmethod(tuple.__new__)
         def _replace(self, _map=map, **kwds):
-            return self._make(_map(kwds.pop, ('x', 'y'), self))
+            return self._make(_map(kwds.get, ('x', 'y'), self))
 
     print(Point(11, 22)._replace(x=100))
 
index 54e8cb479b090240faf19b09b0f8a7462c74da86..1f5ff129628a425c3e1f230ef0a604806f2e187e 100644 (file)
@@ -809,8 +809,10 @@ class Decimal(_numbers.Real, _numbers.Inexact):
     def __hash__(self):
         """x.__hash__() <==> hash(x)"""
         # Decimal integers must hash the same as the ints
-        # Non-integer decimals are normalized and hashed as strings
-        # Normalization assures that hash(100E-1) == hash(10)
+        #
+        # The hash of a nonspecial noninteger Decimal must depend only
+        # on the value of that Decimal, and not on its representation.
+        # For example: hash(Decimal("100E-1")) == hash(Decimal("10")).
         if self._is_special:
             if self._isnan():
                 raise TypeError('Cannot hash a NaN value.')
@@ -826,7 +828,13 @@ class Decimal(_numbers.Real, _numbers.Inexact):
             # 2**64-1.  So we can replace hash((-1)**s*c*10**e) with
             # hash((-1)**s*c*pow(10, e, 2**64-1).
             return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
-        return hash(str(self.normalize()))
+        # The value of a nonzero nonspecial Decimal instance is
+        # faithfully represented by the triple consisting of its sign,
+        # its adjusted exponent, and its coefficient with trailing
+        # zeros removed.
+        return hash((self._sign,
+                     self._exp+len(self._int),
+                     self._int.rstrip('0')))
 
     def as_tuple(self):
         """Represents the number as a triple tuple.
index 3c64e64562fa6150a1075170c6d1c1587637e5ac..0dd7f003252092304eeacab5f7f7d653435d6db4 100644 (file)
@@ -971,6 +971,23 @@ class DecimalUsabilityTest(unittest.TestCase):
         self.assert_(hash(Decimal('Inf')))
         self.assert_(hash(Decimal('-Inf')))
 
+        # check that the value of the hash doesn't depend on the
+        # current context (issue #1757)
+        c = getcontext()
+        old_precision = c.prec
+        x = Decimal("123456789.1")
+
+        c.prec = 6
+        h1 = hash(x)
+        c.prec = 10
+        h2 = hash(x)
+        c.prec = 16
+        h3 = hash(x)
+
+        self.assertEqual(h1, h2)
+        self.assertEqual(h1, h3)
+        c.prec = old_precision
+
     def test_min_and_max_methods(self):
 
         d1 = Decimal('15.32')
index cb4e6eb7cf854932e4b7a22461991a73215ae5d3..9fda72d18f2235bc64ecc31e5ce0e85e20989226 100644 (file)
@@ -2,6 +2,7 @@
 # handler, are obscure and unhelpful.
 
 from io import BytesIO
+import sys
 import unittest
 
 import pyexpat
@@ -385,6 +386,130 @@ class sf1296433Test(unittest.TestCase):
 
         self.assertRaises(Exception, parser.Parse, xml)
 
+class ChardataBufferTest(unittest.TestCase):
+    """
+    test setting of chardata buffer size
+    """
+
+    def test_1025_bytes(self):
+        self.assertEquals(self.small_buffer_test(1025), 2)
+
+    def test_1000_bytes(self):
+        self.assertEquals(self.small_buffer_test(1000), 1)
+
+    def test_wrong_size(self):
+        parser = expat.ParserCreate()
+        parser.buffer_text = 1
+        def f(size):
+            parser.buffer_size = size
+
+        self.assertRaises(ValueError, f, -1)
+        self.assertRaises(ValueError, f, 0)
+
+    def test_unchanged_size(self):
+        xml1 = ("<?xml version='1.0' encoding='iso8859'?><s>%s" % ('a' * 512))
+        xml2 = 'a'*512 + '</s>'
+        parser = expat.ParserCreate()
+        parser.CharacterDataHandler = self.counting_handler
+        parser.buffer_size = 512
+        parser.buffer_text = 1
+
+        # Feed 512 bytes of character data: the handler should be called
+        # once.
+        self.n = 0
+        parser.Parse(xml1)
+        self.assertEquals(self.n, 1)
+
+        # Reassign to buffer_size, but assign the same size.
+        parser.buffer_size = parser.buffer_size
+        self.assertEquals(self.n, 1)
+
+        # Try parsing rest of the document
+        parser.Parse(xml2)
+        self.assertEquals(self.n, 2)
+
+
+    def test_disabling_buffer(self):
+        xml1 = "<?xml version='1.0' encoding='iso8859'?><a>%s" % ('a' * 512)
+        xml2 = ('b' * 1024)
+        xml3 = "%s</a>" % ('c' * 1024)
+        parser = expat.ParserCreate()
+        parser.CharacterDataHandler = self.counting_handler
+        parser.buffer_text = 1
+        parser.buffer_size = 1024
+        self.assertEquals(parser.buffer_size, 1024)
+
+        # Parse one chunk of XML
+        self.n = 0
+        parser.Parse(xml1, 0)
+        self.assertEquals(parser.buffer_size, 1024)
+        self.assertEquals(self.n, 1)
+
+        # Turn off buffering and parse the next chunk.
+        parser.buffer_text = 0
+        self.assertFalse(parser.buffer_text)
+        self.assertEquals(parser.buffer_size, 1024)
+        for i in range(10):
+            parser.Parse(xml2, 0)
+        self.assertEquals(self.n, 11)
+
+        parser.buffer_text = 1
+        self.assertTrue(parser.buffer_text)
+        self.assertEquals(parser.buffer_size, 1024)
+        parser.Parse(xml3, 1)
+        self.assertEquals(self.n, 12)
+
+
+
+    def make_document(self, bytes):
+        return ("<?xml version='1.0'?><tag>" + bytes * 'a' + '</tag>')
+
+    def counting_handler(self, text):
+        self.n += 1
+
+    def small_buffer_test(self, buffer_len):
+        xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * buffer_len)
+        parser = expat.ParserCreate()
+        parser.CharacterDataHandler = self.counting_handler
+        parser.buffer_size = 1024
+        parser.buffer_text = 1
+
+        self.n = 0
+        parser.Parse(xml)
+        return self.n
+
+    def test_change_size_1(self):
+        xml1 = "<?xml version='1.0' encoding='iso8859'?><a><s>%s" % ('a' * 1024)
+        xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
+        parser = expat.ParserCreate()
+        parser.CharacterDataHandler = self.counting_handler
+        parser.buffer_text = 1
+        parser.buffer_size = 1024
+        self.assertEquals(parser.buffer_size, 1024)
+
+        self.n = 0
+        parser.Parse(xml1, 0)
+        parser.buffer_size *= 2
+        self.assertEquals(parser.buffer_size, 2048)
+        parser.Parse(xml2, 1)
+        self.assertEquals(self.n, 2)
+
+    def test_change_size_2(self):
+        xml1 = "<?xml version='1.0' encoding='iso8859'?><a>a<s>%s" % ('a' * 1023)
+        xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
+        parser = expat.ParserCreate()
+        parser.CharacterDataHandler = self.counting_handler
+        parser.buffer_text = 1
+        parser.buffer_size = 2048
+        self.assertEquals(parser.buffer_size, 2048)
+
+        self.n=0
+        parser.Parse(xml1, 0)
+        parser.buffer_size = parser.buffer_size // 2
+        self.assertEquals(parser.buffer_size, 1024)
+        parser.Parse(xml2, 1)
+        self.assertEquals(self.n, 4)
+
 
 def test_main():
     run_unittest(SetAttributeTest,
@@ -394,7 +519,8 @@ def test_main():
                  BufferTextTest,
                  HandlerExceptionTest,
                  PositionTest,
-                 sf1296433Test)
+                 sf1296433Test,
+                 ChardataBufferTest)
 
 if __name__ == "__main__":
     test_main()
index bc31620decbb606bee14d992eb4634c01ff6e913..d47420618c142654af715eb07adf741c804bad0a 100644 (file)
@@ -1133,7 +1133,7 @@ def isTipcAvailable():
         for line in f:
             if line.startswith("tipc "):
                 return True
-    if test_support.debug:
+    if test_support.verbose:
         print("TIPC module is not loaded, please 'sudo modprobe tipc'")
     return False
 
index 7b1baf89e733d848271a4a7f9801fcdc986a456a..3f73c74b02330cefda69f393c9006116f0be458f 100644 (file)
@@ -73,26 +73,26 @@ class WinregTests(unittest.TestCase):
 
         key = OpenKey(root_key, test_key_name)
         # Read the sub-keys
-        sub_key = OpenKey(key, subkeystr)
-        # Check I can enumerate over the values.
-        index = 0
-        while 1:
-            try:
-                data = EnumValue(sub_key, index)
-            except EnvironmentError:
-                break
-            self.assertEquals(data in test_data, True,
-                              "Didn't read back the correct test data")
-            index = index + 1
-        self.assertEquals(index, len(test_data),
-                          "Didn't read the correct number of items")
-        # Check I can directly access each item
-        for value_name, value_data, value_type in test_data:
-            read_val, read_typ = QueryValueEx(sub_key, value_name)
-            self.assertEquals(read_val, value_data,
-                              "Could not directly read the value")
-            self.assertEquals(read_typ, value_type,
-                              "Could not directly read the value")
+        with OpenKey(key, "sub_key") as sub_key:
+            # Check I can enumerate over the values.
+            index = 0
+            while 1:
+                try:
+                    data = EnumValue(sub_key, index)
+                except EnvironmentError:
+                    break
+                self.assertEquals(data in test_data, True,
+                                  "Didn't read back the correct test data")
+                index = index + 1
+            self.assertEquals(index, len(test_data),
+                              "Didn't read the correct number of items")
+            # Check I can directly access each item
+            for value_name, value_data, value_type in test_data:
+                read_val, read_typ = QueryValueEx(sub_key, value_name)
+                self.assertEquals(read_val, value_data,
+                                  "Could not directly read the value")
+                self.assertEquals(read_typ, value_type,
+                                  "Could not directly read the value")
         sub_key.Close()
         # Enumerate our main key.
         read_val = EnumKey(key, 0)
@@ -155,6 +155,11 @@ class WinregTests(unittest.TestCase):
         remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER)
         self.TestAll(remote_key)
 
+    def testExpandEnvironmentStrings(self):
+        r = ExpandEnvironmentStrings("%windir%\\test")
+        self.assertEqual(type(r), str)
+        self.assertEqual(r, os.environ["windir"] + "\\test")
+
 def test_main():
     test_support.run_unittest(WinregTests)
 
index aafcf08bde7c6d13cf93abc19ba8850c0aae15ad..8bb35d8f1c8693c7f314828064561d8ca0ca2da2 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -227,6 +227,7 @@ Gyro Funch
 Peter Funk
 Geoff Furnish
 Ulisses Furquim
+Achim Gaedke
 Lele Gaifax
 Santiago Gala
 Yitzchak Gale
index 050a5c154a772b704ba253110f5ab5bdb82228da..6a1d2b798c11cfe67647735be5c08e07a82de6f5 100644 (file)
@@ -197,7 +197,7 @@ static void _CallPythonObject(void *mem,
        }
 
 #define CHECK(what, x) \
-if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
+if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
 
        result = PyObject_CallObject(callable, arglist);
        CHECK("'calling callback function'", result);
index 8f6b957d2f0bf3b60fe59f2583da39cc2dbe49a9..c24cb815979ceacab411f621177fd7850a2357f0 100644 (file)
@@ -755,7 +755,7 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
 
        v = PyObject_CallFunctionObjArgs(checker, retval, NULL);
        if (v == NULL)
-               _AddTraceback("GetResult", __FILE__, __LINE__-2);
+               _AddTraceback("GetResult", "_ctypes/callproc.c", __LINE__-2);
        Py_DECREF(retval);
        return v;
 }
index 638b38831951ee68036f904c4f7dc162492bf4d0..57f9058ce82521e8e80654d3f2ea41d5d60b3789 100644 (file)
@@ -322,9 +322,6 @@ Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
 Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
 Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
 
-Window_OneArgNoReturnFunction(wattron, attr_t, "l;attr")
-Window_OneArgNoReturnFunction(wattroff, attr_t, "l;attr")
-Window_OneArgNoReturnFunction(wattrset, attr_t, "l;attr")
 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
 #if defined(__NetBSD__)
@@ -379,6 +376,7 @@ PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
   PyObject *temp;
   chtype ch = 0;
   attr_t attr = A_NORMAL;
+  long lattr;
   
   switch (PyTuple_Size(args)) {
   case 1:
@@ -386,8 +384,9 @@ PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
          return NULL;
     break;
   case 2:
-    if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+    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))
@@ -396,8 +395,9 @@ PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
     break;
   case 4:
     if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", 
-                    &y, &x, &temp, &attr))
+                    &y, &x, &temp, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = TRUE;
     break;
   default:
@@ -425,6 +425,7 @@ PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
   int x, y;
   char *str;
   attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  long lattr;
   int use_xy = FALSE, use_attr = FALSE;
 
   switch (PyTuple_Size(args)) {
@@ -433,8 +434,9 @@ PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 2:
-    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr))
       return NULL;
+    attr = lattr;
     use_attr = TRUE;
     break;
   case 3:
@@ -443,8 +445,9 @@ PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
     use_xy = TRUE;
     break;
   case 4:
-    if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &attr))
+    if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = use_attr = TRUE;
     break;
   default:
@@ -471,6 +474,7 @@ PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
   int rtn, x, y, n;
   char *str;
   attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  long lattr;
   int use_xy = FALSE, use_attr = FALSE;
 
   switch (PyTuple_Size(args)) {
@@ -479,8 +483,9 @@ PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 3:
-    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr))
       return NULL;
+    attr = lattr;
     use_attr = TRUE;
     break;
   case 4:
@@ -489,8 +494,9 @@ PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
     use_xy = TRUE;
     break;
   case 5:
-    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = use_attr = TRUE;
     break;
   default:
@@ -517,6 +523,7 @@ PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
   PyObject *temp;
   chtype bkgd;
   attr_t attr = A_NORMAL;
+  long lattr;
 
   switch (PyTuple_Size(args)) {
     case 1:
@@ -524,8 +531,9 @@ PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
         return NULL;
       break;
     case 2:
-      if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+      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");
@@ -540,12 +548,40 @@ PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
   return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
 }
 
+static PyObject *
+PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args)
+{
+  long lattr;
+  if (!PyArg_ParseTuple(args,"l;attr", &lattr))
+    return NULL;
+  return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff");
+}
+
+static PyObject *
+PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args)
+{
+  long lattr;
+  if (!PyArg_ParseTuple(args,"l;attr", &lattr))
+    return NULL;
+  return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron");
+}
+
+static PyObject *
+PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args)
+{
+  long lattr;
+  if (!PyArg_ParseTuple(args,"l;attr", &lattr))
+    return NULL;
+  return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset");
+}
+
 static PyObject *
 PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
 {
   PyObject *temp;
   chtype bkgd;
   attr_t attr = A_NORMAL;
+  long lattr;
 
   switch (PyTuple_Size(args)) {
     case 1:
@@ -553,8 +589,9 @@ PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
         return NULL;
       break;
     case 2:
-      if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+      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");
@@ -742,6 +779,7 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
   PyObject *temp;
   chtype ch;
   attr_t attr = A_NORMAL;
+  long lattr;
 
   switch (PyTuple_Size(args)) {
   case 1:
@@ -749,8 +787,9 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 2:
-    if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &attr))
+    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");
@@ -916,6 +955,7 @@ PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
   chtype ch;
   int n, x, y, code = OK;
   attr_t attr = A_NORMAL;
+  long lattr;
 
   switch (PyTuple_Size(args)) {
   case 2:
@@ -923,8 +963,9 @@ PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 3:
-    if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+    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))
@@ -933,8 +974,9 @@ PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
     break;
   case 5:
     if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", 
-                    &y, &x, &temp, &n, &attr))
+                    &y, &x, &temp, &n, &lattr))
       return NULL;
+    attr = lattr;
     code = wmove(self->win, y, x);
     break;
   default:
@@ -960,6 +1002,7 @@ PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
   PyObject *temp;
   chtype ch = 0;
   attr_t attr = A_NORMAL;
+  long lattr;
   
   switch (PyTuple_Size(args)) {
   case 1:
@@ -967,8 +1010,9 @@ PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 2:
-    if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &attr))
+    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))
@@ -976,8 +1020,9 @@ PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
     use_xy = TRUE;
     break;
   case 4:
-    if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &attr))
+    if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = TRUE;
     break;
   default:
@@ -1062,6 +1107,7 @@ PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
   int x, y;
   char *str;
   attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  long lattr;
   int use_xy = FALSE, use_attr = FALSE;
 
   switch (PyTuple_Size(args)) {
@@ -1070,8 +1116,9 @@ PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 2:
-    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &attr))
+    if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr))
       return NULL;
+    attr = lattr;
     use_attr = TRUE;
     break;
   case 3:
@@ -1080,8 +1127,9 @@ PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
     use_xy = TRUE;
     break;
   case 4:
-    if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &attr))
+    if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = use_attr = TRUE;
     break;
   default:
@@ -1108,6 +1156,7 @@ PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
   int rtn, x, y, n;
   char *str;
   attr_t attr = A_NORMAL , attr_old = A_NORMAL;
+  long lattr;
   int use_xy = FALSE, use_attr = FALSE;
 
   switch (PyTuple_Size(args)) {
@@ -1116,8 +1165,9 @@ PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 3:
-    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &attr))
+    if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr))
       return NULL;
+    attr = lattr;
     use_attr = TRUE;
     break;
   case 4:
@@ -1126,8 +1176,9 @@ PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
     use_xy = TRUE;
     break;
   case 5:
-    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &attr))
+    if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr))
       return NULL;
+    attr = lattr;
     use_xy = use_attr = TRUE;
     break;
   default:
@@ -1470,6 +1521,7 @@ PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
   chtype ch;
   int n, x, y, code = OK;
   attr_t attr = A_NORMAL;
+  long lattr;
 
   switch (PyTuple_Size(args)) {
   case 2:
@@ -1477,8 +1529,9 @@ PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
       return NULL;
     break;
   case 3:
-    if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &attr))
+    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))
@@ -1487,8 +1540,9 @@ PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
     break;
   case 5:
     if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr", 
-                    &y, &x, &temp, &n, &attr))
+                    &y, &x, &temp, &n, &lattr))
       return NULL;
+    attr = lattr;
     code = wmove(self->win, y, x);
     break;
   default:
@@ -1511,9 +1565,9 @@ static PyMethodDef PyCursesWindow_Methods[] = {
        {"addch",           (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS},
        {"addnstr",         (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
        {"addstr",          (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
-       {"attroff",         (PyCFunction)PyCursesWindow_wattroff, METH_VARARGS},
-       {"attron",          (PyCFunction)PyCursesWindow_wattron, METH_VARARGS},
-       {"attrset",         (PyCFunction)PyCursesWindow_wattrset, 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},
        {"chgat",           (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS},
        {"bkgdset",         (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS},
index 19e7bdc59f2a6c6795f9598005a0cda6ada8b9b2..b81a8e2976d0e8613924f162f6b6f2ade20d835f 100644 (file)
@@ -95,6 +95,7 @@ static char copyright[] =
 #define SRE_ERROR_STATE -2 /* illegal state */
 #define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
 #define SRE_ERROR_MEMORY -9 /* out of memory */
+#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
 
 #if defined(VERBOSE)
 #define TRACE(v) printf v
@@ -805,6 +806,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
     Py_ssize_t alloc_pos, ctx_pos = -1;
     Py_ssize_t i, ret = 0;
     Py_ssize_t jump;
+    unsigned int sigcount=0;
 
     SRE_MATCH_CONTEXT* ctx;
     SRE_MATCH_CONTEXT* nextctx;
@@ -833,6 +835,9 @@ entrance:
     }
 
     for (;;) {
+        ++sigcount;
+        if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
+            RETURN_ERROR(SRE_ERROR_INTERRUPTED);
 
         switch (*ctx->pattern++) {
 
@@ -1833,6 +1838,9 @@ pattern_error(int status)
     case SRE_ERROR_MEMORY:
         PyErr_NoMemory();
         break;
+    case SRE_ERROR_INTERRUPTED:
+    /* An exception has already been raised, so let it fly */
+        break;
     default:
         /* other error codes indicate compiler/engine bugs */
         PyErr_SetString(
index ab917f09693369588647f3c4147b7ae5dd470383..005320172c03837f00078a66b8d220555e6bde06 100644 (file)
@@ -1524,6 +1524,50 @@ xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
             self->specified_attributes = 0;
         return 0;
     }
+
+    if (strcmp(name, "buffer_size") == 0) {
+      long new_buffer_size;
+      if (!PyLong_Check(v)) {
+       PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
+       return -1;
+      }
+
+      new_buffer_size=PyLong_AS_LONG(v);
+      /* trivial case -- no change */
+      if (new_buffer_size == self->buffer_size) {
+       return 0;
+      }
+
+      if (new_buffer_size <= 0) {
+       PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
+       return -1;
+      }
+
+      /* check maximum */
+      if (new_buffer_size > INT_MAX) {
+       char errmsg[100];
+       sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
+       PyErr_SetString(PyExc_ValueError, errmsg);
+       return -1;      
+      }
+
+      if (self->buffer != NULL) {
+       /* there is already a buffer */
+       if (self->buffer_used != 0) {
+         flush_character_buffer(self);
+       }
+       /* free existing buffer */
+       free(self->buffer);
+      }
+      self->buffer = malloc(new_buffer_size);
+      if (self->buffer == NULL) {
+       PyErr_NoMemory();
+       return -1;
+      }          
+      self->buffer_size = new_buffer_size;
+      return 0;
+    }
+
     if (strcmp(name, "CharacterDataHandler") == 0) {
         /* If we're changing the character data handler, flush all
          * cached data with the old handler.  Not sure there's a
index 2fdc5b595ef83ef751b0448a3a931202cee559b3..0dcade8b3457de6a059c78aa8b670efd81a8952a 100644 (file)
@@ -46,6 +46,7 @@ PyDoc_STRVAR(module_doc,
 "DeleteValue() - Removes a named value from the specified registry key.\n"
 "EnumKey() - Enumerates subkeys of the specified open registry key.\n"
 "EnumValue() - Enumerates values of the specified open registry key.\n"
+"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ string.\n"
 "FlushKey() - Writes all the attributes of the specified key to the registry.\n"
 "LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n"
 "            registration information from a specified file into that subkey.\n"
@@ -145,6 +146,9 @@ PyDoc_STRVAR(EnumValue_doc,
 " on the underlying registry type.\n"
 "data_type is an integer that identifies the type of the value data.");
 
+PyDoc_STRVAR(ExpandEnvironmentStrings_doc,
+"string = ExpandEnvironmentStrings(string) - Expand environment vars.\n");
+
 PyDoc_STRVAR(FlushKey_doc,
 "FlushKey(key) - Writes all the attributes of a key to the registry.\n"
 "\n"
@@ -503,9 +507,27 @@ PyHKEY_DetachMethod(PyObject *self, PyObject *args)
        return PyLong_FromVoidPtr(ret);
 }
 
+static PyObject *
+PyHKEY_Enter(PyObject *self)
+{
+       Py_XINCREF(self);
+       return self;
+}
+
+static PyObject *
+PyHKEY_Exit(PyObject *self, PyObject *args)
+{
+       if (!PyHKEY_Close(self))
+               return NULL;
+       Py_RETURN_NONE;
+}
+
+
 static struct PyMethodDef PyHKEY_methods[] = {
        {"Close",  PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc},
        {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc},
+       {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL},
+       {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL},
        {NULL}
 };
 
@@ -1061,6 +1083,39 @@ PyEnumValue(PyObject *self, PyObject *args)
        return retVal;
 }
 
+static PyObject *
+PyExpandEnvironmentStrings(PyObject *self, PyObject *args)
+{
+       Py_UNICODE *retValue = NULL;
+       Py_UNICODE *src;
+       DWORD retValueSize;
+       DWORD rc;
+       PyObject *o;
+
+       if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src))
+               return NULL;
+
+       retValueSize = ExpandEnvironmentStringsW(src, retValue, 0);
+       if (retValueSize == 0) {
+               return PyErr_SetFromWindowsErrWithFunction(retValueSize,
+                                               "ExpandEnvironmentStrings");
+       }
+       retValue = (Py_UNICODE *)PyMem_Malloc(retValueSize * sizeof(Py_UNICODE));
+       if (retValue == NULL) {
+               return PyErr_NoMemory();
+       }
+
+       rc = ExpandEnvironmentStringsW(src, retValue, retValueSize);
+       if (rc == 0) {
+               PyMem_Free(retValue);
+               return PyErr_SetFromWindowsErrWithFunction(retValueSize,
+                                               "ExpandEnvironmentStrings");
+       }
+       o = PyUnicode_FromUnicode(retValue, wcslen(retValue));
+       PyMem_Free(retValue);
+       return o;
+}
+
 static PyObject *
 PyFlushKey(PyObject *self, PyObject *args)
 {
@@ -1346,6 +1401,8 @@ static struct PyMethodDef winreg_methods[] = {
        {"DeleteValue",      PyDeleteValue,     METH_VARARGS, DeleteValue_doc},
        {"EnumKey",          PyEnumKey,         METH_VARARGS, EnumKey_doc},
        {"EnumValue",        PyEnumValue,       METH_VARARGS, EnumValue_doc},
+       {"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS,
+               ExpandEnvironmentStrings_doc },
        {"FlushKey",         PyFlushKey,        METH_VARARGS, FlushKey_doc},
        {"LoadKey",          PyLoadKey,         METH_VARARGS, LoadKey_doc},
        {"OpenKey",          PyOpenKey,         METH_VARARGS, OpenKey_doc},