Imported Upstream version 3.6.4
authorHyunjee Kim <hj0426.kim@samsung.com>
Wed, 20 Mar 2019 01:52:04 +0000 (10:52 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Wed, 20 Mar 2019 01:52:04 +0000 (10:52 +0900)
318 files changed:
Doc/c-api/buffer.rst
Doc/c-api/datetime.rst
Doc/c-api/memory.rst
Doc/c-api/veryhigh.rst
Doc/conf.py
Doc/docutils.conf [new file with mode: 0644]
Doc/extending/extending.rst
Doc/extending/newtypes.rst
Doc/glossary.rst
Doc/howto/descriptor.rst
Doc/howto/regex.rst
Doc/includes/email-alternative.py
Doc/includes/sqlite3/load_extension.py
Doc/library/2to3.rst
Doc/library/abc.rst
Doc/library/asyncio-dev.rst
Doc/library/asyncio-eventloop.rst
Doc/library/asyncio-eventloops.rst
Doc/library/asyncio-task.rst
Doc/library/atexit.rst
Doc/library/codecs.rst
Doc/library/collections.abc.rst
Doc/library/csv.rst
Doc/library/curses.ascii.rst
Doc/library/curses.panel.rst
Doc/library/curses.rst
Doc/library/dis.rst
Doc/library/ensurepip.rst
Doc/library/functions.rst
Doc/library/functools.rst
Doc/library/gettext.rst
Doc/library/hashlib.rst
Doc/library/importlib.rst
Doc/library/itertools.rst
Doc/library/locale.rst
Doc/library/msilib.rst
Doc/library/multiprocessing.rst
Doc/library/operator.rst
Doc/library/re.rst
Doc/library/readline.rst
Doc/library/sched.rst
Doc/library/socketserver.rst
Doc/library/sqlite3.rst
Doc/library/ssl.rst
Doc/library/stdtypes.rst
Doc/library/string.rst
Doc/library/subprocess.rst
Doc/library/termios.rst
Doc/library/test.rst
Doc/library/threading.rst
Doc/library/time.rst
Doc/library/tkinter.rst
Doc/library/tkinter.ttk.rst
Doc/library/typing.rst
Doc/library/unittest.rst
Doc/library/urllib.robotparser.rst
Doc/reference/compound_stmts.rst
Doc/reference/expressions.rst
Doc/reference/import.rst
Doc/reference/lexical_analysis.rst
Doc/reference/simple_stmts.rst
Doc/tools/static/switchers.js
Doc/tools/susp-ignored.csv
Doc/tools/templates/indexsidebar.html
Doc/tutorial/introduction.rst
Doc/using/cmdline.rst
Doc/using/venv-create.inc
Doc/whatsnew/3.6.rst
Include/patchlevel.h
Include/py_curses.h
Include/pyerrors.h
Include/pyhash.h
Include/pytime.h
Lib/asyncio/base_events.py
Lib/asyncio/constants.py
Lib/asyncio/coroutines.py
Lib/asyncio/events.py
Lib/asyncio/futures.py
Lib/asyncio/queues.py
Lib/asyncio/selector_events.py
Lib/asyncio/sslproto.py
Lib/asyncio/streams.py
Lib/codecs.py
Lib/ctypes/test/test_anon.py
Lib/ctypes/test/test_frombuffer.py
Lib/ctypes/test/test_funcptr.py
Lib/ctypes/test/test_parameters.py
Lib/ctypes/test/test_pointers.py
Lib/ctypes/test/test_struct_fields.py
Lib/datetime.py
Lib/email/_header_value_parser.py
Lib/email/headerregistry.py
Lib/email/utils.py
Lib/ensurepip/__init__.py
Lib/ensurepip/__main__.py
Lib/ensurepip/_uninstall.py
Lib/idlelib/NEWS.txt
Lib/idlelib/_pyclbr.py [new file with mode: 0644]
Lib/idlelib/browser.py
Lib/idlelib/config_key.py
Lib/idlelib/configdialog.py
Lib/idlelib/editor.py
Lib/idlelib/filelist.py
Lib/idlelib/help_about.py
Lib/idlelib/idle_test/README.txt
Lib/idlelib/idle_test/htest.py
Lib/idlelib/idle_test/test_browser.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_configdialog.py
Lib/idlelib/idle_test/test_pathbrowser.py
Lib/idlelib/idle_test/test_replace.py
Lib/idlelib/idle_test/test_run.py [new file with mode: 0644]
Lib/idlelib/iomenu.py
Lib/idlelib/mainmenu.py
Lib/idlelib/paragraph.py
Lib/idlelib/pathbrowser.py
Lib/idlelib/pyshell.py
Lib/idlelib/run.py
Lib/idlelib/tabbedpages.py [deleted file]
Lib/idlelib/textview.py
Lib/importlib/_bootstrap.py
Lib/inspect.py
Lib/logging/__init__.py
Lib/logging/handlers.py
Lib/multiprocessing/forkserver.py
Lib/multiprocessing/popen_fork.py
Lib/multiprocessing/semaphore_tracker.py
Lib/netrc.py
Lib/plistlib.py
Lib/pydoc_data/topics.py
Lib/random.py
Lib/sqlite3/test/regression.py
Lib/string.py
Lib/test/_test_multiprocessing.py
Lib/test/datetimetester.py
Lib/test/eintrdata/eintr_tester.py
Lib/test/libregrtest/main.py
Lib/test/libregrtest/runtest.py
Lib/test/libregrtest/setup.py
Lib/test/pickletester.py
Lib/test/pythoninfo.py
Lib/test/support/__init__.py
Lib/test/test_ast.py
Lib/test/test_asyncio/test_queues.py
Lib/test/test_asyncio/test_selector_events.py
Lib/test/test_asyncio/test_sslproto.py
Lib/test/test_asyncio/test_streams.py
Lib/test/test_asyncio/test_tasks.py
Lib/test/test_buffer.py
Lib/test/test_bytes.py
Lib/test/test_capi.py
Lib/test/test_code.py
Lib/test/test_code_module.py
Lib/test/test_codecs.py
Lib/test/test_crypt.py
Lib/test/test_curses.py
Lib/test/test_email/test__header_value_parser.py
Lib/test/test_email/test_generator.py
Lib/test/test_email/test_headerregistry.py
Lib/test/test_ensurepip.py
Lib/test/test_exceptions.py
Lib/test/test_faulthandler.py
Lib/test/test_genericpath.py
Lib/test/test_gzip.py
Lib/test/test_hashlib.py
Lib/test/test_httpservers.py
Lib/test/test_imp.py
Lib/test/test_import/__init__.py
Lib/test/test_importlib/import_/test_api.py
Lib/test/test_importlib/import_/test_fromlist.py
Lib/test/test_inspect.py
Lib/test/test_int.py
Lib/test/test_itertools.py
Lib/test/test_json/test_speedups.py
Lib/test/test_kqueue.py
Lib/test/test_logging.py
Lib/test/test_mailbox.py
Lib/test/test_marshal.py
Lib/test/test_msilib.py
Lib/test/test_netrc.py
Lib/test/test_nntplib.py
Lib/test/test_pathlib.py
Lib/test/test_pickle.py
Lib/test/test_pickletools.py
Lib/test/test_plistlib.py
Lib/test/test_poll.py
Lib/test/test_posix.py
Lib/test/test_pty.py
Lib/test/test_random.py
Lib/test/test_repl.py [new file with mode: 0644]
Lib/test/test_robotparser.py
Lib/test/test_shutil.py
Lib/test/test_socket.py
Lib/test/test_socketserver.py
Lib/test/test_stat.py
Lib/test/test_strftime.py
Lib/test/test_string.py
Lib/test/test_subprocess.py
Lib/test/test_support.py
Lib/test/test_syntax.py
Lib/test/test_sys.py
Lib/test/test_tcl.py
Lib/test/test_threading.py
Lib/test/test_time.py
Lib/test/test_tokenize.py
Lib/test/test_tools/test_unparse.py
Lib/test/test_traceback.py
Lib/test/test_types.py
Lib/test/test_typing.py
Lib/test/test_uuid.py
Lib/test/test_venv.py
Lib/test/test_warnings/__init__.py
Lib/test/test_xml_etree.py
Lib/test/test_xml_etree_c.py
Lib/test/test_xmlrpc_net.py
Lib/test/xmltestdata/expat224_utf8_bug.xml [new file with mode: 0644]
Lib/threading.py
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/tkinter/ttk.py
Lib/traceback.py
Lib/turtledemo/__main__.py
Lib/typing.py
Lib/unittest/case.py
Lib/urllib/robotparser.py
Lib/uuid.py
Lib/venv/scripts/common/activate
Mac/BuildScript/build-installer.py
Makefile.pre.in
Misc/ACKS
Misc/NEWS
Misc/python-config.sh.in
Modules/_blake2/blake2b_impl.c
Modules/_blake2/blake2s_impl.c
Modules/_blake2/impl/blake2s-load-xop.h
Modules/_collectionsmodule.c
Modules/_ctypes/_ctypes.c
Modules/_ctypes/cfield.c
Modules/_ctypes/stgdict.c
Modules/_cursesmodule.c
Modules/_datetimemodule.c
Modules/_elementtree.c
Modules/_io/fileio.c
Modules/_io/textio.c
Modules/_json.c
Modules/_pickle.c
Modules/_randommodule.c
Modules/_sqlite/cursor.c
Modules/_ssl.c
Modules/_testcapimodule.c
Modules/_threadmodule.c
Modules/_tkinter.c
Modules/arraymodule.c
Modules/clinic/_tkinter.c.h
Modules/clinic/zlibmodule.c.h
Modules/faulthandler.c
Modules/getpath.c
Modules/itertoolsmodule.c
Modules/main.c
Modules/selectmodule.c
Modules/signalmodule.c
Modules/socketmodule.c
Modules/socketmodule.h
Modules/timemodule.c
Modules/zlibmodule.c
Objects/bytearrayobject.c
Objects/bytesobject.c
Objects/clinic/bytearrayobject.c.h
Objects/clinic/bytesobject.c.h
Objects/codeobject.c
Objects/enumobject.c
Objects/exceptions.c
Objects/longobject.c
Objects/moduleobject.c
Objects/namespaceobject.c
Objects/obmalloc.c
Objects/unicodeobject.c
PC/_msi.c
PC/_testconsole.c
PC/msvcrtmodule.c
PC/python3.def
PCbuild/clean.bat
PCbuild/get_externals.bat
PCbuild/pyproject.props
PCbuild/python.props
PCbuild/readme.txt
Parser/asdl_c.py
Parser/tokenizer.c
Programs/_testembed.c
Python/_warnings.c
Python/ast.c
Python/bltinmodule.c
Python/ceval.c
Python/compile.c
Python/errors.c
Python/formatter_unicode.c
Python/getcompiler.c
Python/importdl.c
Python/importlib.h
Python/marshal.c
Python/pystate.c
Python/pythonrun.c
Python/pytime.c
Python/traceback.c
README.rst
Tools/clinic/clinic.py
Tools/demo/redemo.py
Tools/msi/bundle/bootstrap/pythonba.vcxproj
Tools/msi/bundle/bundle.wxs
Tools/msi/msi.props
Tools/msi/purge.py
Tools/msi/uploadrelease.bat
Tools/msi/uploadrelease.proj
Tools/scripts/treesync.py
Tools/scripts/update_file.py [new file with mode: 0644]
Tools/ssl/multissltests.py
configure
configure.ac
pyconfig.h.in
setup.py

index 3d851b7c39ce0ff9d5e5b67f9ca076cdd4c54f63..8c2de9691f3e1a128a024f15c32203a43013b061 100644 (file)
@@ -473,7 +473,7 @@ Buffer-related functions
    (*order* is ``'A'``).  Return ``0`` otherwise.
 
 
-.. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char order)
+.. c:function:: void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, int itemsize, char order)
 
    Fill the *strides* array with byte-strides of a :term:`contiguous` (C-style if
    *order* is ``'C'`` or Fortran-style if *order* is ``'F'``) array of the
index 39542bd17a3b4a77364dcb6c1684872d5bfd24be..305e990368c29314c2c33fa726bc6fd3999a1dc3 100644 (file)
@@ -188,7 +188,7 @@ not be *NULL*, and the type is not checked:
    .. versionadded:: 3.3
 
 
-.. c:function:: int PyDateTime_DELTA_GET_MICROSECOND(PyDateTime_Delta *o)
+.. c:function:: int PyDateTime_DELTA_GET_MICROSECONDS(PyDateTime_Delta *o)
 
    Return the number of microseconds, as an int from 0 through 999999.
 
index 873fb2ac1d3cad8306b4218429b12e0e09c084ef..73bec7c95a1df4030785484ffc17decae93987e6 100644 (file)
@@ -150,7 +150,7 @@ The default raw memory block allocator uses the following functions:
 
    Frees the memory block pointed to by *p*, which must have been returned by a
    previous call to :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawRealloc` or
-   :c:func:`PyMem_RawCalloc`.  Otherwise, or if ``PyMem_Free(p)`` has been
+   :c:func:`PyMem_RawCalloc`.  Otherwise, or if ``PyMem_RawFree(p)`` has been
    called before, undefined behavior occurs.
 
    If *p* is *NULL*, no operation is performed.
@@ -263,6 +263,69 @@ versions and is therefore deprecated in extension modules.
 * ``PyMem_DEL(ptr)``
 
 
+Object allocators
+=================
+
+The following function sets, modeled after the ANSI C standard, but specifying
+behavior when requesting zero bytes, are available for allocating and releasing
+memory from the Python heap.
+
+By default, these functions use :ref:`pymalloc memory allocator <pymalloc>`.
+
+.. warning::
+
+   The :term:`GIL <global interpreter lock>` must be held when using these
+   functions.
+
+.. c:function:: void* PyObject_Malloc(size_t n)
+
+   Allocates *n* bytes and returns a pointer of type :c:type:`void\*` to the
+   allocated memory, or *NULL* if the request fails.
+
+   Requesting zero bytes returns a distinct non-*NULL* pointer if possible, as
+   if ``PyObject_Malloc(1)`` had been called instead. The memory will not have
+   been initialized in any way.
+
+
+.. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize)
+
+   Allocates *nelem* elements each whose size in bytes is *elsize* and returns
+   a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the
+   request fails. The memory is initialized to zeros.
+
+   Requesting zero elements or elements of size zero bytes returns a distinct
+   non-*NULL* pointer if possible, as if ``PyObject_Calloc(1, 1)`` had been called
+   instead.
+
+   .. versionadded:: 3.5
+
+
+.. c:function:: void* PyObject_Realloc(void *p, size_t n)
+
+   Resizes the memory block pointed to by *p* to *n* bytes. The contents will be
+   unchanged to the minimum of the old and the new sizes.
+
+   If *p* is *NULL*, the call is equivalent to ``PyObject_Malloc(n)``; else if *n*
+   is equal to zero, the memory block is resized but is not freed, and the
+   returned pointer is non-*NULL*.
+
+   Unless *p* is *NULL*, it must have been returned by a previous call to
+   :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or :c:func:`PyObject_Calloc`.
+
+   If the request fails, :c:func:`PyObject_Realloc` returns *NULL* and *p* remains
+   a valid pointer to the previous memory area.
+
+
+.. c:function:: void PyObject_Free(void *p)
+
+   Frees the memory block pointed to by *p*, which must have been returned by a
+   previous call to :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc` or
+   :c:func:`PyObject_Calloc`.  Otherwise, or if ``PyObject_Free(p)`` has been called
+   before, undefined behavior occurs.
+
+   If *p* is *NULL*, no operation is performed.
+
+
 Customize Memory Allocators
 ===========================
 
index 6ab5942929fcceafb1a429643bd3c5d475fefd75..3897fdd828216dd33826faf0472e0eb5dc13df66 100644 (file)
@@ -141,7 +141,8 @@ the same library that the Python runtime is using.
    Read and execute statements from a file associated with an interactive device
    until EOF is reached.  The user will be prompted using ``sys.ps1`` and
    ``sys.ps2``.  *filename* is decoded from the filesystem encoding
-   (:func:`sys.getfilesystemencoding`).  Returns ``0`` at EOF.
+   (:func:`sys.getfilesystemencoding`).  Returns ``0`` at EOF or a negative
+   number upon failure.
 
 
 .. c:var:: int (*PyOS_InputHook)(void)
index d4ee50de7db97b2e61d1136abab6c350b38b035c..43826ec01f46634d8c82070e68a4427c0f7dcca6 100644 (file)
@@ -37,7 +37,8 @@ highlight_language = 'python3'
 needs_sphinx = '1.2'
 
 # Ignore any .rst files in the venv/ directory.
-exclude_patterns = ['venv/*', 'README.rst']
+venvdir = os.getenv('VENVDIR', 'venv')
+exclude_patterns = [venvdir+'/*', 'README.rst']
 
 
 # Options for HTML output
@@ -88,11 +89,10 @@ html_split_index = True
 # Options for LaTeX output
 # ------------------------
 
+latex_engine = 'xelatex'
+
 # Get LaTeX to handle Unicode correctly
 latex_elements = {
-    'inputenc': r'\usepackage[utf8x]{inputenc}',
-    'utf8extra': '',
-    'fontenc': r'\usepackage[T1,T2A]{fontenc}',
 }
 
 # Additional stuff for the LaTeX preamble.
diff --git a/Doc/docutils.conf b/Doc/docutils.conf
new file mode 100644 (file)
index 0000000..bda4f5d
--- /dev/null
@@ -0,0 +1,2 @@
+[restructuredtext parser]
+smartquotes-locales: ja: ""''
index 93584627a291f76ff41dd5dc9ace0d01726be597..a517e130a912c9a07526552606d32961bd8dd4a5 100644 (file)
@@ -40,7 +40,7 @@ A Simple Example
 
 Let's create an extension module called ``spam`` (the favorite food of Monty
 Python fans...) and let's say we want to create a Python interface to the C
-library function :c:func:`system`. [#]_ This function takes a null-terminated
+library function :c:func:`system` [#]_. This function takes a null-terminated
 character string as argument and returns an integer.  We want this function to
 be callable from Python as follows::
 
@@ -917,7 +917,7 @@ It is also possible to :dfn:`borrow` [#]_ a reference to an object.  The
 borrower of a reference should not call :c:func:`Py_DECREF`.  The borrower must
 not hold on to the object longer than the owner from which it was borrowed.
 Using a borrowed reference after the owner has disposed of it risks using freed
-memory and should be avoided completely. [#]_
+memory and should be avoided completely [#]_.
 
 The advantage of borrowing over owning a reference is that you don't need to
 take care of disposing of the reference on all possible paths through the code
@@ -1088,7 +1088,7 @@ checking.
 
 The C function calling mechanism guarantees that the argument list passed to C
 functions (``args`` in the examples) is never *NULL* --- in fact it guarantees
-that it is always a tuple. [#]_
+that it is always a tuple [#]_.
 
 It is a severe error to ever let a *NULL* pointer "escape" to the Python user.
 
index abd5da9db654544c507f7e3d11baded192aae09c..d28d224c2930e9457cad170d6aab9fd09a232b62 100644 (file)
@@ -666,7 +666,7 @@ Fortunately, Python's cyclic-garbage collector will eventually figure out that
 the list is garbage and free it.
 
 In the second version of the :class:`Noddy` example, we allowed any kind of
-object to be stored in the :attr:`first` or :attr:`last` attributes. [#]_ This
+object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. This
 means that :class:`Noddy` objects can participate in cycles::
 
    >>> import noddy2
index dba9186d935a6a8bbac3b02ca5abb5867c66a6ab..b947520b96b66512c5dae22602b0692ac3431794 100644 (file)
@@ -535,7 +535,10 @@ Glossary
       iterables include all sequence types (such as :class:`list`, :class:`str`,
       and :class:`tuple`) and some non-sequence types like :class:`dict`,
       :term:`file objects <file object>`, and objects of any classes you define
-      with an :meth:`__iter__` or :meth:`__getitem__` method.  Iterables can be
+      with an :meth:`__iter__` method or with a :meth:`__getitem__` method
+      that implements :term:`Sequence` semantics.
+
+      Iterables can be
       used in a :keyword:`for` loop and in many other places where a sequence is
       needed (:func:`zip`, :func:`map`, ...).  When an iterable object is passed
       as an argument to the built-in function :func:`iter`, it returns an
index b34937585ea4445ad7b7eaf057e42ba3bbd8b9fe..5e85a9aa6594e458a7ef8470f2248f0133827d6b 100644 (file)
@@ -180,7 +180,7 @@ descriptor is useful for monitoring just a few chosen attributes::
 
 The protocol is simple and offers exciting possibilities.  Several use cases are
 so common that they have been packaged into individual function calls.
-Properties, bound and unbound methods, static methods, and class methods are all
+Properties, bound methods, static methods, and class methods are all
 based on the descriptor protocol.
 
 
@@ -266,22 +266,23 @@ Python's object oriented features are built upon a function based environment.
 Using non-data descriptors, the two are merged seamlessly.
 
 Class dictionaries store methods as functions.  In a class definition, methods
-are written using :keyword:`def` and :keyword:`lambda`, the usual tools for
-creating functions.  The only difference from regular functions is that the
+are written using :keyword:`def` or :keyword:`lambda`, the usual tools for
+creating functions.  Methods only differ from regular functions in that the
 first argument is reserved for the object instance.  By Python convention, the
 instance reference is called *self* but may be called *this* or any other
 variable name.
 
 To support method calls, functions include the :meth:`__get__` method for
 binding methods during attribute access.  This means that all functions are
-non-data descriptors which return bound or unbound methods depending whether
-they are invoked from an object or a class.  In pure python, it works like
-this::
+non-data descriptors which return bound methods when they are invoked from an
+object.  In pure python, it works like this::
 
     class Function(object):
         . . .
         def __get__(self, obj, objtype=None):
             "Simulate func_descr_get() in Objects/funcobject.c"
+            if obj is None:
+                return self
             return types.MethodType(self, obj)
 
 Running the interpreter shows how the function descriptor works in practice::
@@ -291,25 +292,34 @@ Running the interpreter shows how the function descriptor works in practice::
     ...         return x
     ...
     >>> d = D()
-    >>> D.__dict__['f']  # Stored internally as a function
-    <function f at 0x00C45070>
-    >>> D.f              # Get from a class becomes an unbound method
-    <unbound method D.f>
-    >>> d.f              # Get from an instance becomes a bound method
+
+    # Access through the class dictionary does not invoke __get__.
+    # It just returns the underlying function object.
+    >>> D.__dict__['f']
+    <function D.f at 0x00C45070>
+
+    # Dotted access from a class calls __get__() which just returns
+    # the underlying function unchanged.
+    >>> D.f
+    <function D.f at 0x00C45070>
+
+    # The function has a __qualname__ attribute to support introspection
+    >>> D.f.__qualname__
+    'D.f'
+
+    # Dotted access from an instance calls __get__() which returns the
+    # function wrapped in a bound method object
+    >>> d.f
     <bound method D.f of <__main__.D object at 0x00B18C90>>
 
-The output suggests that bound and unbound methods are two different types.
-While they could have been implemented that way, the actual C implementation of
-:c:type:`PyMethod_Type` in :source:`Objects/classobject.c` is a single object
-with two different representations depending on whether the :attr:`im_self`
-field is set or is *NULL* (the C equivalent of ``None``).
-
-Likewise, the effects of calling a method object depend on the :attr:`im_self`
-field. If set (meaning bound), the original function (stored in the
-:attr:`im_func` field) is called as expected with the first argument set to the
-instance.  If unbound, all of the arguments are passed unchanged to the original
-function. The actual C implementation of :func:`instancemethod_call()` is only
-slightly more complex in that it includes some type checking.
+    # Internally, the bound method stores the underlying function,
+    # the bound instance, and the class of the bound instance.
+    >>> d.f.__func__
+    <function D.f at 0x1012e5ae8>
+    >>> d.f.__self__
+    <__main__.D object at 0x1012e1f98>
+    >>> d.f.__class__
+    <class 'method'>
 
 
 Static Methods and Class Methods
index d9b7c9091d467a18134e9945175dd0c50ec209ad..eef63478beed5544f953a69015dad34b8acdd982 100644 (file)
@@ -153,8 +153,8 @@ These sequences can be included inside a character class.  For example,
 ``','`` or ``'.'``.
 
 The final metacharacter in this section is ``.``.  It matches anything except a
-newline character, and there's an alternate mode (``re.DOTALL``) where it will
-match even a newline.  ``'.'`` is often used where you want to match "any
+newline character, and there's an alternate mode (:const:`re.DOTALL`) where it will
+match even a newline.  ``.`` is often used where you want to match "any
 character".
 
 
@@ -168,14 +168,11 @@ wouldn't be much of an advance. Another capability is that you can specify that
 portions of the RE must be repeated a certain number of times.
 
 The first metacharacter for repeating things that we'll look at is ``*``.  ``*``
-doesn't match the literal character ``*``; instead, it specifies that the
+doesn't match the literal character ``'*'``; instead, it specifies that the
 previous character can be matched zero or more times, instead of exactly once.
 
-For example, ``ca*t`` will match ``ct`` (0 ``a`` characters), ``cat`` (1 ``a``),
-``caaat`` (3 ``a`` characters), and so forth.  The RE engine has various
-internal limitations stemming from the size of C's ``int`` type that will
-prevent it from matching over 2 billion ``a`` characters; patterns
-are usually not written to match that much data.
+For example, ``ca*t`` will match ``'ct'`` (0 ``'a'`` characters), ``'cat'`` (1 ``'a'``),
+``'caaat'`` (3 ``'a'`` characters), and so forth.
 
 Repetitions such as ``*`` are :dfn:`greedy`; when repeating a RE, the matching
 engine will try to repeat it as many times as possible. If later portions of the
@@ -185,7 +182,7 @@ fewer repetitions.
 A step-by-step example will make this more obvious.  Let's consider the
 expression ``a[bcd]*b``.  This matches the letter ``'a'``, zero or more letters
 from the class ``[bcd]``, and finally ends with a ``'b'``.  Now imagine matching
-this RE against the string ``abcbd``.
+this RE against the string ``'abcbd'``.
 
 +------+-----------+---------------------------------+
 | Step | Matched   | Explanation                     |
@@ -218,7 +215,7 @@ this RE against the string ``abcbd``.
 |      |           | it succeeds.                    |
 +------+-----------+---------------------------------+
 
-The end of the RE has now been reached, and it has matched ``abcb``.  This
+The end of the RE has now been reached, and it has matched ``'abcb'``.  This
 demonstrates how the matching engine goes as far as it can at first, and if no
 match is found it will then progressively back up and retry the rest of the RE
 again and again.  It will back up until it has tried zero matches for
@@ -229,24 +226,23 @@ Another repeating metacharacter is ``+``, which matches one or more times.  Pay
 careful attention to the difference between ``*`` and ``+``; ``*`` matches
 *zero* or more times, so whatever's being repeated may not be present at all,
 while ``+`` requires at least *one* occurrence.  To use a similar example,
-``ca+t`` will match ``cat`` (1 ``a``), ``caaat`` (3 ``a``'s), but won't match
-``ct``.
+``ca+t`` will match ``'cat'`` (1 ``'a'``), ``'caaat'`` (3 ``'a'``\ s), but won't
+match ``'ct'``.
 
 There are two more repeating qualifiers.  The question mark character, ``?``,
 matches either once or zero times; you can think of it as marking something as
-being optional.  For example, ``home-?brew`` matches either ``homebrew`` or
-``home-brew``.
+being optional.  For example, ``home-?brew`` matches either ``'homebrew'`` or
+``'home-brew'``.
 
 The most complicated repeated qualifier is ``{m,n}``, where *m* and *n* are
 decimal integers.  This qualifier means there must be at least *m* repetitions,
-and at most *n*.  For example, ``a/{1,3}b`` will match ``a/b``, ``a//b``, and
-``a///b``.  It won't match ``ab``, which has no slashes, or ``a////b``, which
+and at most *n*.  For example, ``a/{1,3}b`` will match ``'a/b'``, ``'a//b'``, and
+``'a///b'``.  It won't match ``'ab'``, which has no slashes, or ``'a////b'``, which
 has four.
 
 You can omit either *m* or *n*; in that case, a reasonable value is assumed for
 the missing value.  Omitting *m* is interpreted as a lower limit of 0, while
-omitting *n* results in an upper bound of infinity --- actually, the upper bound
-is the 2-billion limit mentioned earlier, but that might as well be infinity.
+omitting *n* results in an upper bound of infinity.
 
 Readers of a reductionist bent may notice that the three other qualifiers can
 all be expressed using this notation.  ``{0,}`` is the same as ``*``, ``{1,}``
@@ -366,7 +362,7 @@ for a complete listing.
 |                  | returns them as an :term:`iterator`.          |
 +------------------+-----------------------------------------------+
 
-:meth:`~re.regex.match` and :meth:`~re.regex.search` return ``None`` if no match can be found.  If
+:meth:`~re.pattern.match` and :meth:`~re.pattern.search` return ``None`` if no match can be found.  If
 they're successful, a :ref:`match object <match-objects>` instance is returned,
 containing information about the match: where it starts and ends, the substring
 it matched, and more.
@@ -388,24 +384,24 @@ Python interpreter, import the :mod:`re` module, and compile a RE::
 
 Now, you can try matching various strings against the RE ``[a-z]+``.  An empty
 string shouldn't match at all, since ``+`` means 'one or more repetitions'.
-:meth:`match` should return ``None`` in this case, which will cause the
+:meth:`~re.pattern.match` should return ``None`` in this case, which will cause the
 interpreter to print no output.  You can explicitly print the result of
-:meth:`match` to make this clear. ::
+:meth:`!match` to make this clear. ::
 
    >>> p.match("")
    >>> print(p.match(""))
    None
 
 Now, let's try it on a string that it should match, such as ``tempo``.  In this
-case, :meth:`match` will return a :ref:`match object <match-objects>`, so you
+case, :meth:`~re.pattern.match` will return a :ref:`match object <match-objects>`, so you
 should store the result in a variable for later use. ::
 
    >>> m = p.match('tempo')
-   >>> m  #doctest: +ELLIPSIS
+   >>> m
    <_sre.SRE_Match object; span=(0, 5), match='tempo'>
 
 Now you can query the :ref:`match object <match-objects>` for information
-about the matching string.  :ref:`match object <match-objects>` instances
+about the matching string.  Match object instances
 also have several methods and attributes; the most important ones are:
 
 +------------------+--------------------------------------------+
@@ -432,15 +428,15 @@ Trying these methods will soon clarify their meaning::
 
 :meth:`~re.match.group` returns the substring that was matched by the RE.  :meth:`~re.match.start`
 and :meth:`~re.match.end` return the starting and ending index of the match. :meth:`~re.match.span`
-returns both start and end indexes in a single tuple.  Since the :meth:`match`
-method only checks if the RE matches at the start of a string, :meth:`start`
-will always be zero.  However, the :meth:`search` method of patterns
+returns both start and end indexes in a single tuple.  Since the :meth:`~re.pattern.match`
+method only checks if the RE matches at the start of a string, :meth:`!start`
+will always be zero.  However, the :meth:`~re.pattern.search` method of patterns
 scans through the string, so  the match may not start at zero in that
 case. ::
 
    >>> print(p.match('::: message'))
    None
-   >>> m = p.search('::: message'); print(m)  #doctest: +ELLIPSIS
+   >>> m = p.search('::: message'); print(m)
    <_sre.SRE_Match object; span=(4, 11), match='message'>
    >>> m.group()
    'message'
@@ -459,14 +455,14 @@ In actual programs, the most common style is to store the
        print('No match')
 
 Two pattern methods return all of the matches for a pattern.
-:meth:`~re.regex.findall` returns a list of matching strings::
+:meth:`~re.pattern.findall` returns a list of matching strings::
 
    >>> p = re.compile('\d+')
    >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
    ['12', '11', '10']
 
-:meth:`findall` has to create the entire list before it can be returned as the
-result.  The :meth:`~re.regex.finditer` method returns a sequence of
+:meth:`~re.pattern.findall` has to create the entire list before it can be returned as the
+result.  The :meth:`~re.pattern.finditer` method returns a sequence of
 :ref:`match object <match-objects>` instances as an :term:`iterator`::
 
    >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
@@ -529,14 +525,14 @@ of each one.
 |                                 | characters with the respective property.   |
 +---------------------------------+--------------------------------------------+
 | :const:`DOTALL`, :const:`S`     | Make ``.`` match any character, including  |
-|                                 | newlines                                   |
+|                                 | newlines.                                  |
 +---------------------------------+--------------------------------------------+
-| :const:`IGNORECASE`, :const:`I` | Do case-insensitive matches                |
+| :const:`IGNORECASE`, :const:`I` | Do case-insensitive matches.               |
 +---------------------------------+--------------------------------------------+
-| :const:`LOCALE`, :const:`L`     | Do a locale-aware match                    |
+| :const:`LOCALE`, :const:`L`     | Do a locale-aware match.                   |
 +---------------------------------+--------------------------------------------+
 | :const:`MULTILINE`, :const:`M`  | Multi-line matching, affecting ``^`` and   |
-|                                 | ``$``                                      |
+|                                 | ``$``.                                     |
 +---------------------------------+--------------------------------------------+
 | :const:`VERBOSE`, :const:`X`    | Enable verbose REs, which can be organized |
 | (for 'extended')                | more cleanly and understandably.           |
@@ -549,27 +545,41 @@ of each one.
 
    Perform case-insensitive matching; character class and literal strings will
    match letters by ignoring case.  For example, ``[A-Z]`` will match lowercase
-   letters, too, and ``Spam`` will match ``Spam``, ``spam``, or ``spAM``. This
-   lowercasing doesn't take the current locale into account; it will if you also
-   set the :const:`LOCALE` flag.
+   letters, too. Full Unicode matching also works unless the :const:`ASCII`
+   flag is used to disable non-ASCII matches.  When the Unicode patterns
+   ``[a-z]`` or ``[A-Z]`` are used in combination with the :const:`IGNORECASE`
+   flag, they will match the 52 ASCII letters and 4 additional non-ASCII
+   letters: 'İ' (U+0130, Latin capital letter I with dot above), 'ı' (U+0131,
+   Latin small letter dotless i), 'ſ' (U+017F, Latin small letter long s) and
+   'K' (U+212A, Kelvin sign).  ``Spam`` will match ``'Spam'``, ``'spam'``,
+   ``'spAM'``, or ``'ſpam'`` (the latter is matched only in Unicode mode).
+   This lowercasing doesn't take the current locale into account;
+   it will if you also set the :const:`LOCALE` flag.
 
 
 .. data:: L
           LOCALE
    :noindex:
 
-   Make ``\w``, ``\W``, ``\b``, and ``\B``, dependent on the current locale
-   instead of the Unicode database.
-
-   Locales are a feature of the C library intended to help in writing programs that
-   take account of language differences.  For example, if you're processing French
-   text, you'd want to be able to write ``\w+`` to match words, but ``\w`` only
-   matches the character class ``[A-Za-z]``; it won't match ``'é'`` or ``'ç'``.  If
-   your system is configured properly and a French locale is selected, certain C
-   functions will tell the program that ``'é'`` should also be considered a letter.
+   Make ``\w``, ``\W``, ``\b``, ``\B`` and case-insensitive matching dependent
+   on the current locale instead of the Unicode database.
+
+   Locales are a feature of the C library intended to help in writing programs
+   that take account of language differences.  For example, if you're
+   processing encoded French text, you'd want to be able to write ``\w+`` to
+   match words, but ``\w`` only matches the character class ``[A-Za-z]`` in
+   bytes patterns; it won't match bytes corresponding to ``é`` or ``ç``.
+   If your system is configured properly and a French locale is selected,
+   certain C functions will tell the program that the byte corresponding to
+   ``é`` should also be considered a letter.
    Setting the :const:`LOCALE` flag when compiling a regular expression will cause
    the resulting compiled object to use these C functions for ``\w``; this is
    slower, but also enables ``\w+`` to match French words as you'd expect.
+   The use of this flag is discouraged in Python 3 as the locale mechanism
+   is very unreliable, it only handles one "culture" at a time, and it only
+   works with 8-bit locales.  Unicode matching is already enabled by default
+   in Python 3 for Unicode (str) patterns, and it is able to handle different
+   locales/languages.
 
 
 .. data:: M
@@ -667,11 +677,11 @@ zero-width assertions should never be repeated, because if they match once at a
 given location, they can obviously be matched an infinite number of times.
 
 ``|``
-   Alternation, or the "or" operator.   If A and B are regular expressions,
-   ``A|B`` will match any string that matches either ``A`` or ``B``. ``|`` has very
+   Alternation, or the "or" operator.   If *A* and *B* are regular expressions,
+   ``A|B`` will match any string that matches either *A* or *B*. ``|`` has very
    low precedence in order to make it work reasonably when you're alternating
-   multi-character strings. ``Crow|Servo`` will match either ``Crow`` or ``Servo``,
-   not ``Cro``, a ``'w'`` or an ``'S'``, and ``ervo``.
+   multi-character strings. ``Crow|Servo`` will match either ``'Crow'`` or ``'Servo'``,
+   not ``'Cro'``, a ``'w'`` or an ``'S'``, and ``'ervo'``.
 
    To match a literal ``'|'``, use ``\|``, or enclose it inside a character class,
    as in ``[|]``.
@@ -689,8 +699,7 @@ given location, they can obviously be matched an infinite number of times.
       >>> print(re.search('^From', 'Reciting From Memory'))
       None
 
-   .. To match a literal \character{\^}, use \regexp{\e\^} or enclose it
-   .. inside a character class, as in \regexp{[{\e}\^]}.
+   To match a literal ``'^'``, use ``\^``.
 
 ``$``
    Matches at the end of a line, which is defined as either the end of the string,
@@ -725,7 +734,7 @@ given location, they can obviously be matched an infinite number of times.
    match when it's contained inside another word. ::
 
       >>> p = re.compile(r'\bclass\b')
-      >>> print(p.search('no class at all'))  #doctest: +ELLIPSIS
+      >>> print(p.search('no class at all'))
       <_sre.SRE_Match object; span=(3, 8), match='class'>
       >>> print(p.search('the declassified algorithm'))
       None
@@ -743,7 +752,7 @@ given location, they can obviously be matched an infinite number of times.
       >>> p = re.compile('\bclass\b')
       >>> print(p.search('no class at all'))
       None
-      >>> print(p.search('\b' + 'class' + '\b'))  #doctest: +ELLIPSIS
+      >>> print(p.search('\b' + 'class' + '\b'))
       <_sre.SRE_Match object; span=(0, 7), match='\x08class\x08'>
 
    Second, inside a character class, where there's no use for this assertion,
@@ -786,7 +795,8 @@ of a group with a repeating qualifier, such as ``*``, ``+``, ``?``, or
 
 Groups indicated with ``'('``, ``')'`` also capture the starting and ending
 index of the text that they match; this can be retrieved by passing an argument
-to :meth:`group`, :meth:`start`, :meth:`end`, and :meth:`span`.  Groups are
+to :meth:`~re.match.group`, :meth:`~re.match.start`, :meth:`~re.match.end`, and
+:meth:`~re.match.span`.  Groups are
 numbered starting with 0.  Group 0 is always present; it's the whole RE, so
 :ref:`match object <match-objects>` methods all have group 0 as their default
 argument.  Later we'll see how to express groups that don't capture the span
@@ -812,13 +822,13 @@ from left to right. ::
    >>> m.group(2)
    'b'
 
-:meth:`group` can be passed multiple group numbers at a time, in which case it
+:meth:`~re.match.group` can be passed multiple group numbers at a time, in which case it
 will return a tuple containing the corresponding values for those groups. ::
 
    >>> m.group(2,1,2)
    ('b', 'abc', 'b')
 
-The :meth:`groups` method returns a tuple containing the strings for all the
+The :meth:`~re.match.groups` method returns a tuple containing the strings for all the
 subgroups, from 1 up to however many there are. ::
 
    >>> m.groups()
@@ -834,7 +844,7 @@ backreferences in a RE.
 
 For example, the following RE detects doubled words in a string. ::
 
-   >>> p = re.compile(r'(\b\w+)\s+\1')
+   >>> p = re.compile(r'\b(\w+)\s+\1\b')
    >>> p.search('Paris in the the spring').group()
    'the the'
 
@@ -933,9 +943,9 @@ number of the group.  There's naturally a variant that uses the group name
 instead of the number. This is another Python extension: ``(?P=name)`` indicates
 that the contents of the group called *name* should again be matched at the
 current point.  The regular expression for finding doubled words,
-``(\b\w+)\s+\1`` can also be written as ``(?P<word>\b\w+)\s+(?P=word)``::
+``\b(\w+)\s+\1\b`` can also be written as ``\b(?P<word>\w+)\s+(?P=word)\b``::
 
-   >>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
+   >>> p = re.compile(r'\b(?P<word>\w+)\s+(?P=word)\b')
    >>> p.search('Paris in the the spring').group()
    'the the'
 
@@ -1034,7 +1044,7 @@ using the following pattern methods:
 | ``sub()``        | Find all substrings where the RE matches, and |
 |                  | replace them with a different string          |
 +------------------+-----------------------------------------------+
-| ``subn()``       | Does the same thing as :meth:`sub`,  but      |
+| ``subn()``       | Does the same thing as :meth:`!sub`,  but     |
 |                  | returns the new string and the number of      |
 |                  | replacements                                  |
 +------------------+-----------------------------------------------+
@@ -1043,10 +1053,10 @@ using the following pattern methods:
 Splitting Strings
 -----------------
 
-The :meth:`split` method of a pattern splits a string apart
+The :meth:`~re.pattern.split` method of a pattern splits a string apart
 wherever the RE matches, returning a list of the pieces. It's similar to the
-:meth:`split` method of strings but provides much more generality in the
-delimiters that you can split by; string :meth:`split` only supports splitting by
+:meth:`~str.split` method of strings but provides much more generality in the
+delimiters that you can split by; string :meth:`!split` only supports splitting by
 whitespace or by a fixed string.  As you'd expect, there's a module-level
 :func:`re.split` function, too.
 
@@ -1098,7 +1108,7 @@ Search and Replace
 ------------------
 
 Another common task is to find all the matches for a pattern, and replace them
-with a different string.  The :meth:`sub` method takes a replacement value,
+with a different string.  The :meth:`~re.pattern.sub` method takes a replacement value,
 which can be either a string or a function, and the string to be processed.
 
 .. method:: .sub(replacement, string[, count=0])
@@ -1112,7 +1122,7 @@ which can be either a string or a function, and the string to be processed.
    replaced; *count* must be a non-negative integer.  The default value of 0 means
    to replace all occurrences.
 
-Here's a simple example of using the :meth:`sub` method.  It replaces colour
+Here's a simple example of using the :meth:`~re.pattern.sub` method.  It replaces colour
 names with the word ``colour``::
 
    >>> p = re.compile('(blue|white|red)')
@@ -1121,7 +1131,7 @@ names with the word ``colour``::
    >>> p.sub('colour', 'blue socks and red shoes', count=1)
    'colour socks and red shoes'
 
-The :meth:`subn` method does the same work, but returns a 2-tuple containing the
+The :meth:`~re.pattern.subn` method does the same work, but returns a 2-tuple containing the
 new string value and the number of replacements  that were performed::
 
    >>> p = re.compile('(blue|white|red)')
@@ -1206,24 +1216,24 @@ Use String Methods
 
 Sometimes using the :mod:`re` module is a mistake.  If you're matching a fixed
 string, or a single character class, and you're not using any :mod:`re` features
-such as the :const:`IGNORECASE` flag, then the full power of regular expressions
+such as the :const:`~re.IGNORECASE` flag, then the full power of regular expressions
 may not be required. Strings have several methods for performing operations with
 fixed strings and they're usually much faster, because the implementation is a
 single small C loop that's been optimized for the purpose, instead of the large,
 more generalized regular expression engine.
 
 One example might be replacing a single fixed string with another one; for
-example, you might replace ``word`` with ``deed``.  ``re.sub()`` seems like the
-function to use for this, but consider the :meth:`replace` method.  Note that
-:func:`replace` will also replace ``word`` inside words, turning ``swordfish``
+example, you might replace ``word`` with ``deed``.  :func:`re.sub` seems like the
+function to use for this, but consider the :meth:`~str.replace` method.  Note that
+:meth:`!replace` will also replace ``word`` inside words, turning ``swordfish``
 into ``sdeedfish``, but the  naive RE ``word`` would have done that, too.  (To
 avoid performing the substitution on parts of words, the pattern would have to
 be ``\bword\b``, in order to require that ``word`` have a word boundary on
-either side.  This takes the job beyond  :meth:`replace`'s abilities.)
+either side.  This takes the job beyond  :meth:`!replace`'s abilities.)
 
 Another common task is deleting every occurrence of a single character from a
 string or replacing it with another single character.  You might do this with
-something like ``re.sub('\n', ' ', S)``, but :meth:`translate` is capable of
+something like ``re.sub('\n', ' ', S)``, but :meth:`~str.translate` is capable of
 doing both tasks and will be faster than any regular expression operation can
 be.
 
@@ -1234,18 +1244,18 @@ can be solved with a faster and simpler string method.
 match() versus search()
 -----------------------
 
-The :func:`match` function only checks if the RE matches at the beginning of the
-string while :func:`search` will scan forward through the string for a match.
-It's important to keep this distinction in mind.  Remember,  :func:`match` will
+The :func:`~re.match` function only checks if the RE matches at the beginning of the
+string while :func:`~re.search` will scan forward through the string for a match.
+It's important to keep this distinction in mind.  Remember,  :func:`!match` will
 only report a successful match which will start at 0; if the match wouldn't
-start at zero,  :func:`match` will *not* report it. ::
+start at zero,  :func:`!match` will *not* report it. ::
 
    >>> print(re.match('super', 'superstition').span())
    (0, 5)
    >>> print(re.match('super', 'insuperable'))
    None
 
-On the other hand, :func:`search` will scan forward through the string,
+On the other hand, :func:`~re.search` will scan forward through the string,
 reporting the first match it finds. ::
 
    >>> print(re.search('super', 'superstition').span())
@@ -1284,12 +1294,12 @@ doesn't work because of the greedy nature of ``.*``. ::
    >>> print(re.match('<.*>', s).group())
    <html><head><title>Title</title>
 
-The RE matches the ``'<'`` in ``<html>``, and the ``.*`` consumes the rest of
+The RE matches the ``'<'`` in ``'<html>'``, and the ``.*`` consumes the rest of
 the string.  There's still more left in the RE, though, and the ``>`` can't
 match at the end of the string, so the regular expression engine has to
 backtrack character by character until it finds a match for the ``>``.   The
-final match extends from the ``'<'`` in ``<html>`` to the ``'>'`` in
-``</title>``, which isn't what you want.
+final match extends from the ``'<'`` in ``'<html>'`` to the ``'>'`` in
+``'</title>'``, which isn't what you want.
 
 In this case, the solution is to use the non-greedy qualifiers ``*?``, ``+?``,
 ``??``, or ``{m,n}?``, which match as *little* text as possible.  In the above
@@ -1315,7 +1325,7 @@ notation, but they're not terribly readable.  REs of moderate complexity can
 become lengthy collections of backslashes, parentheses, and metacharacters,
 making them difficult to read and understand.
 
-For such REs, specifying the ``re.VERBOSE`` flag when compiling the regular
+For such REs, specifying the :const:`re.VERBOSE` flag when compiling the regular
 expression can be helpful, because it allows you to format the regular
 expression more clearly.
 
@@ -1354,5 +1364,5 @@ Friedl's Mastering Regular Expressions, published by O'Reilly.  Unfortunately,
 it exclusively concentrates on Perl and Java's flavours of regular expressions,
 and doesn't contain any Python material at all, so it won't be useful as a
 reference for programming in Python.  (The first edition covered Python's
-now-removed :mod:`regex` module, which won't help you much.)  Consider checking
+now-removed :mod:`!regex` module, which won't help you much.)  Consider checking
 it out from your library.
index 2e142b1e3b71e4b0e42386fa2b67ea0bd52cf64e..df7ca6f3faa332cbf28f1bcd5e82870477300bae 100644 (file)
@@ -32,7 +32,7 @@ msg.add_alternative("""\
   <body>
     <p>Salut!</p>
     <p>Cela ressemble à un excellent
-        <a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718>
+        <a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718">
             recipie
         </a> déjeuner.
     </p>
index 015aa0de8c46d4d2fd783d057ab5055a0ed43a74..b997c70668ace413cc27502883f737e007e56239 100644 (file)
@@ -11,7 +11,7 @@ con.execute("select load_extension('./fts3.so')")
 # alternatively you can load the extension using an API call:
 # con.load_extension("./fts3.so")
 
-# disable extension laoding again
+# disable extension loading again
 con.enable_load_extension(False)
 
 # example from SQLite wiki
index 4c9a528d42e703bb4fd55f8d025cb08d9ac5f5a5..1ab05a62ad458fbbf38a56fd11e1fbaf0b443474 100644 (file)
@@ -288,7 +288,8 @@ and off individually.  They are described here in more detail.
 
    Fixes duplicate types in the second argument of :func:`isinstance`.  For
    example, ``isinstance(x, (int, int))`` is converted to ``isinstance(x,
-   (int))``.
+   int)`` and ``isinstance(x, (int, float, int))`` is converted to
+   ``isinstance(x, (int, float))``.
 
 .. 2to3fixer:: itertools_imports
 
index 6001db32df49c3b7dba692db63cb66c9457c8347..9522dd62049138b5e809e61e0f16c7f7f3a7554c 100644 (file)
@@ -278,7 +278,7 @@ The :mod:`abc` module also provides the following decorators:
        :func:`abstractmethod`, making this decorator redundant.
 
 
-.. decorator:: abstractproperty(fget=None, fset=None, fdel=None, doc=None)
+.. decorator:: abstractproperty
 
    A subclass of the built-in :func:`property`, indicating an abstract
    property.
index 1838eb95a7d52230336a56faa1c992003af8e8b0..e2ad3eb0196c93cb84ad59f5ceac563c9045f97d 100644 (file)
@@ -209,9 +209,9 @@ The fix is to call the :func:`ensure_future` function or the
 Detect exceptions never consumed
 --------------------------------
 
-Python usually calls :func:`sys.displayhook` on unhandled exceptions. If
+Python usually calls :func:`sys.excepthook` on unhandled exceptions. If
 :meth:`Future.set_exception` is called, but the exception is never consumed,
-:func:`sys.displayhook` is not called. Instead, :ref:`a log is emitted
+:func:`sys.excepthook` is not called. Instead, :ref:`a log is emitted
 <asyncio-logger>` when the future is deleted by the garbage collector, with the
 traceback where the exception was raised.
 
index 83bbb70b03792885e689bc768beaa3513cb0c2a2..27c170e3ec8472744b1196e0f0db610891f920f5 100644 (file)
@@ -500,6 +500,9 @@ Creating listening connections
    This method is a :ref:`coroutine <coroutine>`.  When completed, the
    coroutine returns a ``(transport, protocol)`` pair.
 
+   .. versionadded:: 3.5.3
+
+
 Watch file descriptors
 ----------------------
 
index d74fcb1e07f249e29d502dfc64cece6673d0292e..7970e9039dfd86b8f785d39e20b110603f35dd41 100644 (file)
@@ -148,10 +148,9 @@ process based on the calling context. A policy is an object implementing the
 :class:`AbstractEventLoopPolicy` interface.
 
 For most users of :mod:`asyncio`, policies never have to be dealt with
-explicitly, since the default global policy is sufficient.
+explicitly, since the default global policy is sufficient (see below).
 
-The default policy defines context as the current thread, and manages an event
-loop per thread that interacts with :mod:`asyncio`. The module-level functions
+The module-level functions
 :func:`get_event_loop` and :func:`set_event_loop` provide convenient access to
 event loops managed by the default policy.
 
@@ -189,6 +188,13 @@ An event loop policy must implement the following interface:
       context, :meth:`set_event_loop` must be called explicitly.
 
 
+The default policy defines context as the current thread, and manages an event
+loop per thread that interacts with :mod:`asyncio`.  If the current thread
+doesn't already have an event loop associated with it, the default policy's
+:meth:`~AbstractEventLoopPolicy.get_event_loop` method creates one when
+called from the main thread, but raises :exc:`RuntimeError` otherwise.
+
+
 Access to the global loop policy
 --------------------------------
 
@@ -200,3 +206,24 @@ Access to the global loop policy
 
    Set the current event loop policy. If *policy* is ``None``, the default
    policy is restored.
+
+
+Customizing the event loop policy
+---------------------------------
+
+To implement a new event loop policy, it is recommended you subclass the
+concrete default event loop policy :class:`DefaultEventLoopPolicy`
+and override the methods for which you want to change behavior, for example::
+
+    class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+
+        def get_event_loop(self):
+            """Get the event loop.
+
+            This may be None or an instance of EventLoop.
+            """
+            loop = super().get_event_loop()
+            # Do something with loop ...
+            return loop
+
+    asyncio.set_event_loop_policy(MyEventLoopPolicy())
index 5298c11058c4b1864165e571249927b73d21b4d5..cc8fffb0659f24743ca96d05ebea2ec7f2b5bf47 100644 (file)
@@ -216,7 +216,7 @@ Future
      raise an exception when the future isn't done yet.
 
    - Callbacks registered with :meth:`add_done_callback` are always called
-     via the event loop's :meth:`~AbstractEventLoop.call_soon_threadsafe`.
+     via the event loop's :meth:`~AbstractEventLoop.call_soon`.
 
    - This class is not compatible with the :func:`~concurrent.futures.wait` and
      :func:`~concurrent.futures.as_completed` functions in the
index 1d84d4587fd9c009c4eb207fac24476609897666..5c60b604c68301e020144e582d45247038ffebc6 100644 (file)
@@ -21,7 +21,7 @@ program is killed by a signal not handled by Python, when a Python fatal
 internal error is detected, or when :func:`os._exit` is called.
 
 
-.. function:: register(func, *args, **kargs)
+.. function:: register(func, *args, **kwargs)
 
    Register *func* as a function to be executed at termination.  Any optional
    arguments that are to be passed to *func* must be passed as arguments to
index b9c1868d5956d152f63594eeebac6381559af014..6e249ecf2b1af4fc5f2bea6d513d6bbf24ff6f81 100644 (file)
@@ -802,7 +802,7 @@ The design is such that one can use the factory functions returned by the
 :func:`lookup` function to construct the instance.
 
 
-.. class:: StreamReaderWriter(stream, Reader, Writer, errors)
+.. class:: StreamReaderWriter(stream, Reader, Writer, errors='strict')
 
    Creates a :class:`StreamReaderWriter` instance. *stream* must be a file-like
    object. *Reader* and *Writer* must be factory functions or classes providing the
@@ -826,7 +826,7 @@ The design is such that one can use the factory functions returned by the
 :func:`lookup` function to construct the instance.
 
 
-.. class:: StreamRecoder(stream, encode, decode, Reader, Writer, errors)
+.. class:: StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict')
 
    Creates a :class:`StreamRecoder` instance which implements a two-way conversion:
    *encode* and *decode* work on the frontend — the data visible to
index 58b03b9bd76804226c664328071a0a2312b036fa..60154532094423bdcd61336d78cbbc06c530fa68 100644 (file)
@@ -107,7 +107,12 @@ ABC                        Inherits from          Abstract Methods        Mixin
 .. class:: Iterable
 
    ABC for classes that provide the :meth:`__iter__` method.
-   See also the definition of :term:`iterable`.
+
+   Checking ``isinstance(obj, Iterable)`` detects classes that are registered
+   as :class:`Iterable` or that have an :meth:`__iter__` method, but it does
+   not detect classes that iterate with the :meth:`__getitem__` method.
+   The only reliable way to determine whether an object is :term:`iterable`
+   is to call ``iter(obj)``.
 
 .. class:: Collection
 
index 43714f7479283d63a07318af65244f5ecdd01a85..e1290d4c9b5c83bd660013c7fcc6d6f39215e42d 100644 (file)
@@ -172,7 +172,7 @@ The :mod:`csv` module defines the following classes:
    A short usage example::
 
        >>> import csv
-       >>> with open('names.csv') as csvfile:
+       >>> with open('names.csv', newline='') as csvfile:
        ...     reader = csv.DictReader(csvfile)
        ...     for row in reader:
        ...         print(row['first_name'], row['last_name'])
@@ -211,7 +211,7 @@ The :mod:`csv` module defines the following classes:
 
        import csv
 
-       with open('names.csv', 'w') as csvfile:
+       with open('names.csv', 'w', newline='') as csvfile:
            fieldnames = ['first_name', 'last_name']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
 
@@ -270,7 +270,7 @@ The :mod:`csv` module defines the following classes:
 
 An example for :class:`Sniffer` use::
 
-   with open('example.csv') as csvfile:
+   with open('example.csv', newline='') as csvfile:
        dialect = csv.Sniffer().sniff(csvfile.read(1024))
        csvfile.seek(0)
        reader = csv.reader(csvfile, dialect)
index b6ac2517335cf59455a3479f4300335c3498d7b7..04b2a260af09468f89ea7f8e85bec4162206acaf 100644 (file)
@@ -176,14 +176,12 @@ C library:
 
    Checks for a non-ASCII character (ordinal values 0x80 and above).
 
-These functions accept either integers or strings; when the argument is a
+These functions accept either integers or single-character strings; when the argument is a
 string, it is first converted using the built-in function :func:`ord`.
 
-Note that all these functions check ordinal bit values derived from the  first
+Note that all these functions check ordinal bit values derived from the
 character of the string you pass in; they do not actually know anything about
-the host machine's character encoding.  For functions  that know about the
-character encoding (and handle internationalization properly) see the
-:mod:`string` module.
+the host machine's character encoding.
 
 The following two functions take either a single-character string or integer
 byte value; they return a value of the same type.
index c99c37a5651bad151aea4a47808ae126ea2b22c2..d770c03c8375f468a5e026f14598c428eb3a40cc 100644 (file)
@@ -74,7 +74,7 @@ Panel objects have the following methods:
 
 .. method:: Panel.hidden()
 
-   Returns true if the panel is hidden (not visible), false otherwise.
+   Returns ``True`` if the panel is hidden (not visible), ``False`` otherwise.
 
 
 .. method:: Panel.hide()
index 668d2826b0a1b34dcb3718ab01eac6226f862ae4..14e32d78e0d16a8a392d721f30cd79d981ac2d22 100644 (file)
@@ -19,6 +19,14 @@ for Windows, DOS, and possibly other systems as well.  This extension module is
 designed to match the API of ncurses, an open-source curses library hosted on
 Linux and the BSD variants of Unix.
 
+.. note::
+
+   Whenever the documentation mentions a *character* it can be specified
+   as an integer, a one-character Unicode string or a one-byte byte string.
+
+   Whenever the documentation mentions a *character string* it can be specified
+   as a Unicode string or a byte string.
+
 .. note::
 
    Since version 5.4, the ncurses library decides how to interpret non-ASCII data
@@ -104,8 +112,8 @@ The module :mod:`curses` defines the following functions:
 .. function:: color_content(color_number)
 
    Return the intensity of the red, green, and blue (RGB) components in the color
-   *color_number*, which must be between ``0`` and :const:`COLORS`.  A 3-tuple is
-   returned, containing the R,G,B values for the given color, which will be between
+   *color_number*, which must be between ``0`` and :const:`COLORS`.  Return a 3-tuple,
+   containing the R,G,B values for the given color, which will be between
    ``0`` (no component) and ``1000`` (maximum amount of component).
 
 
@@ -119,9 +127,9 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: curs_set(visibility)
 
-   Set the cursor state.  *visibility* can be set to 0, 1, or 2, for invisible,
-   normal, or very visible.  If the terminal supports the visibility requested, the
-   previous cursor state is returned; otherwise, an exception is raised.  On many
+   Set the cursor state.  *visibility* can be set to ``0``, ``1``, or ``2``, for invisible,
+   normal, or very visible.  If the terminal supports the visibility requested, return the
+   previous cursor state; otherwise raise an exception.  On many
    terminals, the "visible" mode is an underline cursor and the "very visible" mode
    is a block cursor.
 
@@ -154,12 +162,12 @@ The module :mod:`curses` defines the following functions:
    representing the desired next state.  The :func:`doupdate` ground updates the
    physical screen to match the virtual screen.
 
-   The virtual screen may be updated by a :meth:`noutrefresh` call after write
-   operations such as :meth:`addstr` have been performed on a window.  The normal
-   :meth:`refresh` call is simply :meth:`noutrefresh` followed by :func:`doupdate`;
+   The virtual screen may be updated by a :meth:`~window.noutrefresh` call after write
+   operations such as :meth:`~window.addstr` have been performed on a window.  The normal
+   :meth:`~window.refresh` call is simply :meth:`!noutrefresh` followed by :func:`!doupdate`;
    if you have to update multiple windows, you can speed performance and perhaps
-   reduce screen flicker by issuing :meth:`noutrefresh` calls on all windows,
-   followed by a single :func:`doupdate`.
+   reduce screen flicker by issuing :meth:`!noutrefresh` calls on all windows,
+   followed by a single :func:`!doupdate`.
 
 
 .. function:: echo()
@@ -175,7 +183,7 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: erasechar()
 
-   Return the user's current erase character.  Under Unix operating systems this
+   Return the user's current erase character as a one-byte bytes object.  Under Unix operating systems this
    is a property of the controlling tty of the curses program, and is not set by
    the curses library itself.
 
@@ -183,9 +191,9 @@ The module :mod:`curses` defines the following functions:
 .. function:: filter()
 
    The :func:`.filter` routine, if used, must be called before :func:`initscr` is
-   called.  The effect is that, during those calls, :envvar:`LINES` is set to 1; the
-   capabilities clear, cup, cud, cud1, cuu1, cuu, vpa are disabled; and the home
-   string is set to the value of cr. The effect is that the cursor is confined to
+   called.  The effect is that, during those calls, :envvar:`LINES` is set to ``1``; the
+   capabilities ``clear``, ``cup``, ``cud``, ``cud1``, ``cuu1``, ``cuu``, ``vpa`` are disabled; and the ``home``
+   string is set to the value of ``cr``. The effect is that the cursor is confined to
    the current line, and so are screen updates.  This may be used for enabling
    character-at-a-time  line editing without touching the rest of the screen.
 
@@ -205,7 +213,7 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: getmouse()
 
-   After :meth:`getch` returns :const:`KEY_MOUSE` to signal a mouse event, this
+   After :meth:`~window.getch` returns :const:`KEY_MOUSE` to signal a mouse event, this
    method should be call to retrieve the queued mouse event, represented as a
    5-tuple ``(id, x, y, z, bstate)``. *id* is an ID value used to distinguish
    multiple devices, and *x*, *y*, *z* are the event's coordinates.  (*z* is
@@ -219,8 +227,8 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: getsyx()
 
-   Return the current coordinates of the virtual screen cursor in y and x.  If
-   leaveok is currently true, then -1,-1 is returned.
+   Return the current coordinates of the virtual screen cursor as a tuple
+   ``(y, x)``.  If :meth:`leaveok <window.leaveok>` is currently ``True``, then return ``(-1, -1)``.
 
 
 .. function:: getwin(file)
@@ -260,7 +268,7 @@ The module :mod:`curses` defines the following functions:
 
    Used for half-delay mode, which is similar to cbreak mode in that characters
    typed by the user are immediately available to the program. However, after
-   blocking for *tenths* tenths of seconds, an exception is raised if nothing has
+   blocking for *tenths* tenths of seconds, raise an exception if nothing has
    been typed.  The value of *tenths* must be a number between ``1`` and ``255``.  Use
    :func:`nocbreak` to leave half-delay mode.
 
@@ -273,7 +281,7 @@ The module :mod:`curses` defines the following functions:
    :const:`COLORS`.  Each of *r*, *g*, *b*, must be a value between ``0`` and
    ``1000``.  When :func:`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 :func:`can_change_color` returns ``1``.
+   most terminals; it is active only if :func:`can_change_color` returns ``True``.
 
 
 .. function:: init_pair(pair_number, fg, bg)
@@ -313,32 +321,32 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: keyname(k)
 
-   Return the name of the key numbered *k*.  The name of a key generating printable
+   Return the name of the key numbered *k* as a bytes object.  The name of a key generating printable
    ASCII character is the key's character.  The name of a control-key combination
-   is a two-character string consisting of a caret followed by the corresponding
+   is a two-byte bytes object consisting of a caret (``b'^'``) followed by the corresponding
    printable ASCII character.  The name of an alt-key combination (128--255) is a
-   string consisting of the prefix 'M-' followed by the name of the corresponding
+   bytes object consisting of the prefix ``b'M-'`` followed by the name of the corresponding
    ASCII character.
 
 
 .. function:: killchar()
 
-   Return the user's current line kill character. Under Unix operating systems
+   Return the user's current line kill character as a one-byte bytes object. Under Unix operating systems
    this is a property of the controlling tty of the curses program, and is not set
    by the curses library itself.
 
 
 .. function:: longname()
 
-   Return a string containing the terminfo long name field describing the current
+   Return a bytes object containing 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 :func:`initscr`.
 
 
-.. function:: meta(yes)
+.. function:: meta(flag)
 
-   If *yes* is 1, allow 8-bit characters to be input. If *yes* is 0,  allow only
-   7-bit chars.
+   If *flag* is ``True``, allow 8-bit characters to be input.  If
+   *flag* is ``False``,  allow only 7-bit chars.
 
 
 .. function:: mouseinterval(interval)
@@ -352,7 +360,7 @@ The module :mod:`curses` defines the following functions:
 
    Set the mouse events to be reported, and 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
+   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.
 
@@ -365,13 +373,13 @@ The module :mod:`curses` defines the following functions:
 .. function:: newpad(nlines, ncols)
 
    Create and return a pointer to a new pad data structure with the given number
-   of lines and columns.  A pad is returned as a window object.
+   of lines and columns.  Return a pad as a window object.
 
    A pad is like a window, except that it is not restricted by the screen size, and
    is not necessarily associated with a particular part of the screen.  Pads can be
    used when a large window is needed, and only a part of the window will be on the
    screen at one time.  Automatic refreshes of pads (such as from scrolling or
-   echoing of input) do not occur.  The :meth:`refresh` and :meth:`noutrefresh`
+   echoing of input) do not occur.  The :meth:`~window.refresh` and :meth:`~window.noutrefresh`
    methods of a pad require 6 arguments to specify the part of the pad to be
    displayed and the location on the screen to be used for the display. The
    arguments are *pminrow*, *pmincol*, *sminrow*, *smincol*, *smaxrow*, *smaxcol*; the *p*
@@ -419,9 +427,9 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: noqiflush()
 
-   When the :func:`noqiflush` routine is used, normal flush of input and output queues
-   associated with the INTR, QUIT and SUSP characters will not be done.  You may
-   want to call :func:`noqiflush` in a signal handler if you want output to
+   When the :func:`!noqiflush` routine is used, normal flush of input and output queues
+   associated with the ``INTR``, ``QUIT`` and ``SUSP`` characters will not be done.  You may
+   want to call :func:`!noqiflush` in a signal handler if you want output to
    continue as though the interrupt had not occurred, after the handler exits.
 
 
@@ -442,14 +450,14 @@ The module :mod:`curses` defines the following functions:
    :func:`color_pair` is the counterpart to this function.
 
 
-.. function:: putp(string)
+.. function:: putp(str)
 
    Equivalent to ``tputs(str, 1, putchar)``; emit the value of a specified
    terminfo capability for the current terminal.  Note that the output of :func:`putp`
    always goes to standard output.
 
 
-.. function:: qiflush( [flag] )
+.. function:: qiflush([flag])
 
    If *flag* is ``False``, the effect is the same as calling :func:`noqiflush`. If
    *flag* is ``True``, or no argument is provided, the queues will be flushed when
@@ -486,7 +494,7 @@ The module :mod:`curses` defines the following functions:
    Backend function used by :func:`resizeterm`, performing most of the work;
    when resizing the windows, :func:`resize_term` blank-fills the areas that are
    extended.  The calling application should fill in these areas with
-   appropriate data.  The :func:`resize_term` function attempts to resize all
+   appropriate data.  The :func:`!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.
 
@@ -506,16 +514,17 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: setsyx(y, x)
 
-   Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then
-   leaveok is set.
+   Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both ``-1``, then
+   :meth:`leaveok <window.leaveok>` is set ``True``.
 
 
-.. function:: setupterm([termstr, fd])
+.. function:: setupterm(term=None, fd=-1)
 
-   Initialize the terminal.  *termstr* is a string giving the terminal name; if
-   omitted, the value of the :envvar:`TERM` environment variable will be used.  *fd* is the
+   Initialize the terminal.  *term* is a string giving
+   the terminal name, or ``None``; if omitted or ``None``, the value of the
+   :envvar:`TERM` environment variable will be used.  *fd* is the
    file descriptor to which any initialization sequences will be sent; if not
-   supplied, the file descriptor for ``sys.stdout`` will be used.
+   supplied or ``-1``, the file descriptor for ``sys.stdout`` will be used.
 
 
 .. function:: start_color()
@@ -540,13 +549,14 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: termname()
 
-   Return the value of the environment variable :envvar:`TERM`, truncated to 14 characters.
+   Return the value of the environment variable :envvar:`TERM`, as a bytes object,
+   truncated to 14 characters.
 
 
 .. function:: tigetflag(capname)
 
    Return the value of the Boolean capability corresponding to the terminfo
-   capability name *capname*.  The value ``-1`` is returned if *capname* is not a
+   capability name *capname* as an integer.  Return the value ``-1`` if *capname* is not a
    Boolean capability, or ``0`` if it is canceled or absent from the terminal
    description.
 
@@ -554,7 +564,7 @@ The module :mod:`curses` defines the following functions:
 .. function:: tigetnum(capname)
 
    Return the value of the numeric capability corresponding to the terminfo
-   capability name *capname*.  The value ``-2`` is returned if *capname* is not a
+   capability name *capname* as an integer.  Return the value ``-2`` if *capname* is not a
    numeric capability, or ``-1`` if it is canceled or absent from the terminal
    description.
 
@@ -562,13 +572,14 @@ The module :mod:`curses` defines the following functions:
 .. function:: tigetstr(capname)
 
    Return the value of the string capability corresponding to the terminfo
-   capability name *capname*.  ``None`` is returned if *capname* is not a string
-   capability, or is canceled or absent from the terminal description.
+   capability name *capname* as a bytes object.  Return ``None`` if *capname*
+   is not a terminfo "string capability", or is canceled or absent from the
+   terminal description.
 
 
 .. function:: tparm(str[, ...])
 
-   Instantiate the string *str* with the supplied parameters, where *str* should
+   Instantiate the bytes object *str* with the supplied parameters, where *str* should
    be a parameterized string obtained from the terminfo database.  E.g.
    ``tparm(tigetstr("cup"), 5, 3)`` could result in ``b'\033[6;4H'``, the exact
    result depending on terminal type.
@@ -588,18 +599,18 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: unctrl(ch)
 
-   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.
+   Return a bytes object which is a printable representation of the character *ch*.
+   Control characters are represented as a caret followed by the character, for
+   example as ``b'^C'``. Printing characters are left as they are.
 
 
 .. function:: ungetch(ch)
 
-   Push *ch* so the next :meth:`getch` will return it.
+   Push *ch* so the next :meth:`~window.getch` will return it.
 
    .. note::
 
-      Only one *ch* can be pushed before :meth:`getch` is called.
+      Only one *ch* can be pushed before :meth:`!getch` is called.
 
 
 .. function:: update_lines_cols()
@@ -611,11 +622,11 @@ The module :mod:`curses` defines the following functions:
 
 .. function:: unget_wch(ch)
 
-   Push *ch* so the next :meth:`get_wch` will return it.
+   Push *ch* so the next :meth:`~window.get_wch` will return it.
 
    .. note::
 
-      Only one *ch* can be pushed before :meth:`get_wch` is called.
+      Only one *ch* can be pushed before :meth:`!get_wch` is called.
 
    .. versionadded:: 3.3
 
@@ -640,7 +651,7 @@ The module :mod:`curses` defines the following functions:
 
    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. After calling this function,  ``init_pair(x,
+   to the color number ``-1``. After calling this function,  ``init_pair(x,
    curses.COLOR_RED, -1)`` initializes, for instance, color pair *x* to a red
    foreground color on the default background.
 
@@ -652,7 +663,7 @@ The module :mod:`curses` defines the following functions:
    this function will restore the terminal to a sane state before re-raising the
    exception and generating a traceback.  The callable object *func* is then passed
    the main window 'stdscr' as its first argument, followed by any other arguments
-   passed to :func:`wrapper`.  Before calling *func*, :func:`wrapper` turns on
+   passed to :func:`!wrapper`.  Before calling *func*, :func:`!wrapper` turns on
    cbreak mode, turns off echo, enables the terminal keypad, and initializes colors
    if the terminal has color support.  On exit (whether normally or by exception)
    it restores cooked mode, turns on echo, and disables the terminal keypad.
@@ -670,13 +681,6 @@ the following methods and attributes:
 .. method:: window.addch(ch[, attr])
             window.addch(y, x, ch[, attr])
 
-   .. note::
-
-      A *character* means a C character (an ASCII code), rather than a Python
-      character (a string of length 1). (This note is true whenever the
-      documentation mentions a character.) The built-in :func:`ord` is handy for
-      conveying strings to codes.
-
    Paint character *ch* at ``(y, x)`` with attributes *attr*, overwriting any
    character previously painter at that location.  By default, the character
    position and attributes are the current settings for the window object.
@@ -685,15 +689,16 @@ the following methods and attributes:
 .. method:: window.addnstr(str, n[, attr])
             window.addnstr(y, x, str, n[, attr])
 
-   Paint at most *n* characters of the  string *str* at ``(y, x)`` with attributes
+   Paint at most *n* characters of the character string *str* at
+   ``(y, x)`` with attributes
    *attr*, overwriting anything previously on the display.
 
 
 .. method:: window.addstr(str[, attr])
             window.addstr(y, x, str[, attr])
 
-   Paint the string *str* at ``(y, x)`` with attributes *attr*, overwriting
-   anything previously on the display.
+   Paint the character string *str* at ``(y, x)`` with attributes
+   *attr*, overwriting anything previously on the display.
 
 
 .. method:: window.attroff(attr)
@@ -710,8 +715,8 @@ the following methods and attributes:
 
 .. method:: window.attrset(attr)
 
-   Set the "background" set of attributes to *attr*.  This set is initially 0 (no
-   attributes).
+   Set the "background" set of attributes to *attr*.  This set is initially
+   ``0`` (no attributes).
 
 
 .. method:: window.bkgd(ch[, attr])
@@ -741,8 +746,7 @@ the following methods and attributes:
 
    Draw a border around the edges of the window. Each parameter specifies  the
    character to use for a specific part of the border; see the table below for more
-   details.  The characters can be specified as integers or as one-character
-   strings.
+   details.
 
    .. note::
 
@@ -783,11 +787,11 @@ the following methods and attributes:
             window.chgat(y, x, num, attr)
 
    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
-   :meth:`touchline` method so that the contents will be redisplayed by the next
-   window refresh.
+   position ``(y, x)`` if supplied. If *num* is not given or is ``-1``,
+   the attribute will be set on all the characters to the end of the line.  This
+   function moves cursor to position ``(y, x)`` if supplied. The changed line
+   will be touched using the :meth:`touchline` method so that the contents will
+   be redisplayed by the next window refresh.
 
 
 .. method:: window.clear()
@@ -796,9 +800,9 @@ the following methods and attributes:
    call to :meth:`refresh`.
 
 
-.. method:: window.clearok(yes)
+.. method:: window.clearok(flag)
 
-   If *yes* is 1, the next call to :meth:`refresh` will clear the window
+   If *flag* is ``True``, the next call to :meth:`refresh` will clear the window
    completely.
 
 
@@ -880,15 +884,16 @@ the following methods and attributes:
 .. method:: window.getch([y, x])
 
    Get a character. Note that 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 :func:`getch` waits
-   until a key is pressed.
+   range: function keys, keypad keys and so on are represented by numbers higher
+   than 255.  In no-delay mode, return ``-1`` if there is no input, otherwise
+   wait until a key is pressed.
 
 
 .. method:: window.get_wch([y, x])
 
    Get a wide character. Return a character for most keys, or an integer for
    function keys, keypad keys, and other special keys.
+   In no-delay mode, raise an exception if there is no input.
 
    .. versionadded:: 3.3
 
@@ -897,7 +902,7 @@ the following methods and attributes:
 
    Get a character, returning a string instead of an integer, as :meth:`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
+   string containing the key name.  In no-delay mode, raise an exception if
    there is no input.
 
 
@@ -909,13 +914,16 @@ the following methods and attributes:
 .. method:: window.getparyx()
 
    Return the beginning coordinates of this window relative to its parent window
-   into two integer variables y and x.  Return ``-1, -1`` if this window has no
+   as a tuple ``(y, x)``.  Return ``(-1, -1)`` if this window has no
    parent.
 
 
-.. method:: window.getstr([y, x])
+.. method:: window.getstr()
+            window.getstr(n)
+            window.getstr(y, x)
+            window.getstr(y, x, n)
 
-   Read a string from the user, with primitive line editing capacity.
+   Read a bytes object from the user, with primitive line editing capacity.
 
 
 .. method:: window.getyx()
@@ -939,9 +947,9 @@ the following methods and attributes:
    insert/delete is enabled by default.
 
 
-.. method:: window.idlok(yes)
+.. method:: window.idlok(flag)
 
-   If called with *yes* equal to 1, :mod:`curses` will try and use hardware line
+   If *flag* is ``True``, :mod:`curses` will try and use hardware line
    editing facilities. Otherwise, line insertion/deletion are disabled.
 
 
@@ -1003,7 +1011,7 @@ the following methods and attributes:
 .. method:: window.instr([n])
             window.instr(y, x[, n])
 
-   Return a string of characters, extracted from the window starting at the
+   Return a bytes object 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, :meth:`instr` returns a string
    at most *n* characters long (exclusive of the trailing NUL).
@@ -1022,20 +1030,20 @@ the following methods and attributes:
    :meth:`refresh`; otherwise return ``False``.
 
 
-.. method:: window.keypad(yes)
+.. method:: window.keypad(flag)
 
-   If *yes* is 1, escape sequences generated by some keys (keypad,  function keys)
-   will be interpreted by :mod:`curses`. If *yes* is 0, escape sequences will be
+   If *flag* is ``True``, escape sequences generated by some keys (keypad,  function keys)
+   will be interpreted by :mod:`curses`. If *flag* is ``False``, escape sequences will be
    left as is in the input stream.
 
 
-.. method:: window.leaveok(yes)
+.. method:: window.leaveok(flag)
 
-   If *yes* is 1, cursor is left where it is on update, instead of being at "cursor
+   If *flag* is ``True``, cursor is left where it is on update, instead of being at "cursor
    position."  This reduces cursor movement where possible. If possible the cursor
    will be made invisible.
 
-   If *yes* is 0, cursor will always be at "cursor position" after an update.
+   If *flag* is ``False``, cursor will always be at "cursor position" after an update.
 
 
 .. method:: window.move(new_y, new_x)
@@ -1055,16 +1063,16 @@ the following methods and attributes:
    Move the window so its upper-left corner is at ``(new_y, new_x)``.
 
 
-.. method:: window.nodelay(yes)
+.. method:: window.nodelay(flag)
 
-   If *yes* is ``1``, :meth:`getch` will be non-blocking.
+   If *flag* is ``True``, :meth:`getch` will be non-blocking.
 
 
-.. method:: window.notimeout(yes)
+.. method:: window.notimeout(flag)
 
-   If *yes* is ``1``, escape sequences will not be timed out.
+   If *flag* is ``True``, escape sequences will not be timed out.
 
-   If *yes* is ``0``, after a few milliseconds, an escape sequence will not be
+   If *flag* is ``False``, after a few milliseconds, an escape sequence will not be
    interpreted, and will be left in the input stream as is.
 
 
@@ -1153,8 +1161,8 @@ the following methods and attributes:
 
    Control what happens when the cursor of a window is moved off the edge of the
    window or scrolling region, either as a result of a newline action on the bottom
-   line, or typing the last character of the last line.  If *flag* is false, the
-   cursor is left on the bottom line.  If *flag* is true, the window is scrolled up
+   line, or typing the last character of the last line.  If *flag* is ``False``, the
+   cursor is left on the bottom line.  If *flag* is ``True``, the window is scrolled up
    one line.  Note that in order to get the physical scrolling effect on the
    terminal, it is also necessary to call :meth:`idlok`.
 
@@ -1202,7 +1210,7 @@ the following methods and attributes:
 
 .. method:: window.syncok(flag)
 
-   If called with *flag* set to ``True``, then :meth:`syncup` is called automatically
+   If *flag* is ``True``, then :meth:`syncup` is called automatically
    whenever there is a change in the window.
 
 
@@ -1216,9 +1224,9 @@ the following methods and attributes:
 
    Set blocking or non-blocking read behavior for the window.  If *delay* is
    negative, blocking read is used (which will wait indefinitely for input).  If
-   *delay* is zero, then non-blocking read is used, and -1 will be returned by
-   :meth:`getch` if no input is waiting.  If *delay* is positive, then
-   :meth:`getch` will block for *delay* milliseconds, and return -1 if there is
+   *delay* is zero, then non-blocking read is used, and :meth:`getch` will
+   return ``-1`` if no input is waiting.  If *delay* is positive, then
+   :meth:`getch` will block for *delay* milliseconds, and return ``-1`` if there is
    still no input at the end of that time.
 
 
@@ -1226,7 +1234,7 @@ the following methods and attributes:
 
    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*\ =1) or unchanged (*changed*\ =0).
+   having been changed (*changed*\ ``=True``) or unchanged (*changed*\ ``=False``).
 
 
 .. method:: window.touchwin()
@@ -1268,7 +1276,7 @@ The :mod:`curses` module defines the following data members:
 
 .. data:: version
 
-   A string representing the current version of the module.  Also available as
+   A bytes object representing the current version of the module.  Also available as
    :const:`__version__`.
 
 Some constants are available to specify character cell attributes.
index c795782034a4648dad9c3badbfaf986bd38c117f..c68b15a9d450096240563af5442dfe56f66ebbb8 100644 (file)
@@ -1053,7 +1053,7 @@ All of the following opcodes use their arguments.
    Pops all function arguments, and the function itself off the stack, and
    pushes the return value. Note that this opcode pops at most three items
    from the stack. Var-positional and var-keyword arguments are packed
-   by :opcode:`BUILD_MAP_UNPACK_WITH_CALL` and
+   by :opcode:`BUILD_TUPLE_UNPACK_WITH_CALL` and
    :opcode:`BUILD_MAP_UNPACK_WITH_CALL`.
 
    .. versionadded:: 3.6
index c797f63326d1a26b690c6df3172bed649c1e70ed..652339e57f31aba9bfa6b405afe950a4a8ada026 100644 (file)
@@ -78,6 +78,9 @@ options:
 
 Providing both of the script selection options will trigger an exception.
 
+.. versionchanged:: 3.6.3
+   The exit status is non-zero if the command fails.
+
 
 Module API
 ----------
index bd4c94fcae19af881efe0b835eccc06d7359f894..7a7a84d1d424dff6b89b8999607e2df6c078eff6 100644 (file)
@@ -182,9 +182,9 @@ are always available.  They are listed here in alphabetical order.
    base 16).  :exc:`ValueError` will be raised if *i* is outside that range.
 
 
-.. function:: classmethod(function)
+.. decorator:: classmethod
 
-   Return a class method for *function*.
+   Transform a method into a class method.
 
    A class method receives the class as implicit first argument, just like an
    instance method receives the instance. To declare a class method, use this
@@ -1384,9 +1384,9 @@ are always available.  They are listed here in alphabetical order.
 
    For sorting examples and a brief sorting tutorial, see :ref:`sortinghowto`.
 
-.. function:: staticmethod(function)
+.. decorator:: staticmethod
 
-   Return a static method for *function*.
+   Transform a method into a static method.
 
    A static method does not receive an implicit first argument. To declare a static
    method, use this idiom::
@@ -1405,12 +1405,21 @@ are always available.  They are listed here in alphabetical order.
    :func:`classmethod` for a variant that is useful for creating alternate class
    constructors.
 
+   Like all decorators, it is also possible to call ``staticmethod`` as
+   a regular function and do something with its result.  This is needed
+   in some cases where you need a reference to a function from a class
+   body and you want to avoid the automatic transformation to instance
+   method.  For these cases, use this idiom:
+
+      class C:
+          builtin_open = staticmethod(open)
+
    For more information on static methods, consult the documentation on the
    standard type hierarchy in :ref:`types`.
 
-   .. index::
-      single: string; str() (built-in function)
 
+.. index::
+   single: string; str() (built-in function)
 
 .. _func-str:
 .. class:: str(object='')
index 9a8defee546bf3a9b3084ed736e4c83dc3a6833d..28062c11890ed10304a4ede90a0a1452180dda11 100644 (file)
@@ -264,9 +264,9 @@ The :mod:`functools` module defines the following functions:
           return value
 
 
-.. decorator:: singledispatch(default)
+.. decorator:: singledispatch
 
-   Transforms a function into a :term:`single-dispatch <single
+   Transform a function into a :term:`single-dispatch <single
    dispatch>` :term:`generic function`.
 
    To define a generic function, decorate it with the ``@singledispatch``
index 053d9d3840cfc09f13f5fc2692cbb9a97e912d34..407853c2d7efadbdc2109c51248ec165c7b78df4 100644 (file)
@@ -134,7 +134,7 @@ Class-based API
 
 The class-based API of the :mod:`gettext` module gives you more flexibility and
 greater convenience than the GNU :program:`gettext` API.  It is the recommended
-way of localizing your Python applications and modules.  :mod:`gettext` defines
+way of localizing your Python applications and modules.  :mod:`!gettext` defines
 a "translations" class which implements the parsing of GNU :file:`.mo` format
 files, and has methods for returning strings. Instances of this "translations"
 class can also install themselves in the built-in namespace as the function
@@ -219,7 +219,7 @@ Translation classes are what actually implement the translation of original
 source file message strings to translated message strings. The base class used
 by all translation classes is :class:`NullTranslations`; this provides the basic
 interface you can use to write your own specialized translation classes.  Here
-are the methods of :class:`NullTranslations`:
+are the methods of :class:`!NullTranslations`:
 
 
 .. class:: NullTranslations(fp=None)
@@ -247,13 +247,13 @@ are the methods of :class:`NullTranslations`:
 
    .. method:: gettext(message)
 
-      If a fallback has been set, forward :meth:`.gettext` to the fallback.
+      If a fallback has been set, forward :meth:`!gettext` to the fallback.
       Otherwise, return *message*.  Overridden in derived classes.
 
 
    .. method:: ngettext(singular, plural, n)
 
-      If a fallback has been set, forward :meth:`ngettext` to the fallback.
+      If a fallback has been set, forward :meth:`!ngettext` to the fallback.
       Otherwise, return *singular* if *n* is 1; return *plural* otherwise.
       Overridden in derived classes.
 
@@ -261,7 +261,7 @@ are the methods of :class:`NullTranslations`:
    .. method:: lgettext(message)
    .. method:: lngettext(singular, plural, n)
 
-      Equivalent to :meth:`.gettext` and :meth:`ngettext`, but the translation
+      Equivalent to :meth:`.gettext` and :meth:`.ngettext`, but the translation
       is returned as a byte string encoded in the preferred system encoding
       if no encoding was explicitly set with :meth:`set_output_charset`.
       Overridden in derived classes.
index 725dce6fa15f0fc5f96703d1dac2ede7470d5ea2..3a27a5b566f58dad62ce605e8923f06e2899cf3b 100644 (file)
@@ -510,15 +510,19 @@ to users and later verify them to make sure they weren't tampered with::
     ...     h.update(cookie)
     ...     return h.hexdigest().encode('utf-8')
     >>>
-    >>> cookie = b'user:vatrogasac'
+    >>> def verify(cookie, sig):
+    ...     good_sig = sign(cookie)
+    ...     return compare_digest(good_sig, sig)
+    >>>
+    >>> cookie = b'user-alice'
     >>> sig = sign(cookie)
     >>> print("{0},{1}".format(cookie.decode('utf-8'), sig))
-    user:vatrogasac,349cf904533767ed2d755279a8df84d0
-    >>> compare_digest(cookie, sig)
+    user-alice,b'43b3c982cf697e0c5ab22172d1ca7421'
+    >>> verify(cookie, sig)
     True
-    >>> compare_digest(b'user:policajac', sig)
+    >>> verify(b'user-bob', sig)
     False
-    >>> compare_digest(cookie, b'0102030405060708090a0b0c0d0e0f00')
+    >>> verify(cookie, b'0102030405060708090a0b0c0d0e0f00')
     False
 
 Even though there's a native keyed hashing mode, BLAKE2 can, of course, be used
index 6406e306c49faa3e103b34846183098c670d46a5..d194362fb003c25abbf5a564f1922102a8a557b5 100644 (file)
@@ -1045,7 +1045,15 @@ find and load modules.
 
 .. class:: ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)
 
-   A specification for a module's import-system-related state.
+   A specification for a module's import-system-related state.  This is
+   typically exposed as the module's ``__spec__`` attribute.  In the
+   descriptions below, the names in parentheses give the corresponding
+   attribute available directly on the module object.
+   E.g. ``module.__spec__.origin == module.__file__``.  Note however that
+   while the *values* are usually equivalent, they can differ since there is
+   no synchronization between the two objects.  Thus it is possible to update
+   the module's ``__path__`` at runtime, and this will not be automatically
+   reflected in ``__spec__.submodule_search_locations``.
 
    .. versionadded:: 3.4
 
index b0d0a8c8c8ccd7f346f403ec6ab9eef9798eb2a8..594af39f60f1f51a894b0c2aae022794c22bdca1 100644 (file)
@@ -53,7 +53,7 @@ Iterator                        Arguments                       Results
 :func:`compress`                data, selectors                 (d[0] if s[0]), (d[1] if s[1]), ...                 ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F``
 :func:`dropwhile`               pred, seq                       seq[n], seq[n+1], starting when pred fails          ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1``
 :func:`filterfalse`             pred, seq                       elements of seq where pred(elem) is false           ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8``
-:func:`groupby`                 iterable[, keyfunc]             sub-iterators grouped by value of keyfunc(v)
+:func:`groupby`                 iterable[, key]                 sub-iterators grouped by value of key(v)
 :func:`islice`                  seq, [start,] stop [, step]     elements from seq[start:stop:step]                  ``islice('ABCDEFG', 2, None) --> C D E F G``
 :func:`starmap`                 func, seq                       func(\*seq[0]), func(\*seq[1]), ...                 ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000``
 :func:`takewhile`               pred, seq                       seq[0], seq[1], until pred fails                    ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4``
@@ -753,15 +753,16 @@ which incur interpreter overhead.
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
        # Recipe credited to George Sakkis
-       pending = len(iterables)
+       num_active = len(iterables)
        nexts = cycle(iter(it).__next__ for it in iterables)
-       while pending:
+       while num_active:
            try:
                for next in nexts:
                    yield next()
            except StopIteration:
-               pending -= 1
-               nexts = cycle(islice(nexts, pending))
+               # Remove the iterator we just exhausted from the cycle.
+               num_active -= 1
+               nexts = cycle(islice(nexts, num_active))
 
    def partition(pred, iterable):
        'Use a predicate to partition entries into false entries and true entries'
index 5aaf4a398f744147c75a21badf66f2907e2789eb..b04442bc16234af6afe4c920895c9c00cd7eb811 100644 (file)
@@ -542,17 +542,23 @@ library.
 Access to message catalogs
 --------------------------
 
+.. function:: gettext(msg)
+.. function:: dgettext(domain, msg)
+.. function:: dcgettext(domain, msg, category)
+.. function:: textdomain(domain)
+.. function:: bindtextdomain(domain, dir)
+
 The locale module exposes the C library's gettext interface on systems that
-provide this interface.  It consists of the functions :func:`gettext`,
-:func:`dgettext`, :func:`dcgettext`, :func:`textdomain`, :func:`bindtextdomain`,
-and :func:`bind_textdomain_codeset`.  These are similar to the same functions in
+provide this interface.  It consists of the functions :func:`!gettext`,
+:func:`!dgettext`, :func:`!dcgettext`, :func:`!textdomain`, :func:`!bindtextdomain`,
+and :func:`!bind_textdomain_codeset`.  These are similar to the same functions in
 the :mod:`gettext` module, but use the C library's binary format for message
 catalogs, and the C library's search algorithms for locating message catalogs.
 
 Python applications should normally find no need to invoke these functions, and
 should use :mod:`gettext` instead.  A known exception to this rule are
 applications that link with additional C libraries which internally invoke
-:c:func:`gettext` or :func:`dcgettext`.  For these applications, it may be
+:c:func:`gettext` or :c:func:`dcgettext`.  For these applications, it may be
 necessary to bind the text domain, so that the libraries can properly locate
 their message catalogs.
 
index 0a420329748cb306b802e016db298195ad8ae28c..854431742ed26985d23c0b04f8a166622727d848 100644 (file)
@@ -124,9 +124,9 @@ structures.
 
 .. seealso::
 
-   `FCICreateFile <https://msdn.microsoft.com/library?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_
-   `UuidCreate <https://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_
-   `UuidToString <https://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_
+   `FCICreate <https://msdn.microsoft.com/en-us/library/bb432265.aspx>`_
+   `UuidCreate <https://msdn.microsoft.com/en-us/library/windows/desktop/aa379205.aspx>`_
+   `UuidToString <https://msdn.microsoft.com/en-us/library/windows/desktop/aa379352.aspx>`_
 
 .. _database-objects:
 
@@ -155,9 +155,9 @@ Database Objects
 
 .. seealso::
 
-   `MSIDatabaseOpenView <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_
-   `MSIDatabaseCommit <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_
-   `MSIGetSummaryInformation <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_
+   `MSIDatabaseOpenView <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370082.aspx>`_
+   `MSIDatabaseCommit <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370075.aspx>`_
+   `MSIGetSummaryInformation <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370301.aspx>`_
 
 .. _view-objects:
 
@@ -203,11 +203,11 @@ View Objects
 
 .. seealso::
 
-   `MsiViewExecute <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewexecute.asp>`_
-   `MSIViewGetColumnInfo <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_
-   `MsiViewFetch <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewfetch.asp>`_
-   `MsiViewModify <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewmodify.asp>`_
-   `MsiViewClose <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewclose.asp>`_
+   `MsiViewExecute <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370513.aspx>`_
+   `MSIViewGetColumnInfo <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370516.aspx>`_
+   `MsiViewFetch <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370514.aspx>`_
+   `MsiViewModify <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370519.aspx>`_
+   `MsiViewClose <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370510.aspx>`_
 
 .. _summary-objects:
 
@@ -247,10 +247,10 @@ Summary Information Objects
 
 .. seealso::
 
-   `MsiSummaryInfoGetProperty <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_
-   `MsiSummaryInfoGetPropertyCount <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_
-   `MsiSummaryInfoSetProperty <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_
-   `MsiSummaryInfoPersist <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_
+   `MsiSummaryInfoGetProperty <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370409.aspx>`_
+   `MsiSummaryInfoGetPropertyCount <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370488.aspx>`_
+   `MsiSummaryInfoSetProperty <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370491.aspx>`_
+   `MsiSummaryInfoPersist <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370490.aspx>`_
 
 .. _record-objects:
 
@@ -301,18 +301,18 @@ Record Objects
 
 .. seealso::
 
-   `MsiRecordGetFieldCount <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_
-   `MsiRecordSetString <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_
-   `MsiRecordSetStream <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_
-   `MsiRecordSetInteger <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_
-   `MsiRecordClear <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordclear.asp>`_
+   `MsiRecordGetFieldCount <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370366.aspx>`_
+   `MsiRecordSetString <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370373.aspx>`_
+   `MsiRecordSetStream <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370372.aspx>`_
+   `MsiRecordSetInteger <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370371.aspx>`_
+   `MsiRecordClearData <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370364.aspx>`_
 
 .. _msi-errors:
 
 Errors
 ------
 
-All wrappers around MSI functions raise :exc:`MsiError`; the string inside the
+All wrappers around MSI functions raise :exc:`MSIError`; the string inside the
 exception will contain more detail.
 
 
@@ -392,15 +392,15 @@ Directory Objects
 
    .. method:: remove_pyc()
 
-      Remove ``.pyc``/``.pyo`` files on uninstall.
+      Remove ``.pyc`` files on uninstall.
 
 
 .. seealso::
 
-   `Directory Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/directory_table.asp>`_
-   `File Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/file_table.asp>`_
-   `Component Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/component_table.asp>`_
-   `FeatureComponents Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_
+   `Directory Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368295.aspx>`_
+   `File Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368596.aspx>`_
+   `Component Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368007.aspx>`_
+   `FeatureComponents Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368579.aspx>`_
 
 .. _features:
 
@@ -425,7 +425,7 @@ Features
 
 .. seealso::
 
-   `Feature Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/feature_table.asp>`_
+   `Feature Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368585.aspx>`_
 
 .. _msi-gui:
 
@@ -520,13 +520,13 @@ for installing Python packages.
 
 .. seealso::
 
-   `Dialog Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/dialog_table.asp>`_
-   `Control Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/control_table.asp>`_
-   `Control Types <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controls.asp>`_
-   `ControlCondition Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlcondition_table.asp>`_
-   `ControlEvent Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlevent_table.asp>`_
-   `EventMapping Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/eventmapping_table.asp>`_
-   `RadioButton Table <https://msdn.microsoft.com/library?url=/library/en-us/msi/setup/radiobutton_table.asp>`_
+   `Dialog Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368286.aspx>`_
+   `Control Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368044.aspx>`_
+   `Control Types <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368039.aspx>`_
+   `ControlCondition Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368035.aspx>`_
+   `ControlEvent Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368037.aspx>`_
+   `EventMapping Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa368559.aspx>`_
+   `RadioButton Table <https://msdn.microsoft.com/en-us/library/windows/desktop/aa370962.aspx>`_
 
 .. _msi-tables:
 
index 2f770b6322309e77a15f66396146375c760699e0..9521f77c694b00461cfb673f7286dbe76c55b246 100644 (file)
@@ -1821,8 +1821,8 @@ Running the following commands creates a server for a single shared queue which
 remote clients can access::
 
    >>> from multiprocessing.managers import BaseManager
-   >>> import queue
-   >>> queue = queue.Queue()
+   >>> from queue import Queue
+   >>> queue = Queue()
    >>> class QueueManager(BaseManager): pass
    >>> QueueManager.register('get_queue', callable=lambda:queue)
    >>> m = QueueManager(address=('', 50000), authkey=b'abracadabra')
@@ -2165,7 +2165,7 @@ with the :class:`Pool` class.
 
       .. versionadded:: 3.3
 
-   .. method:: starmap_async(func, iterable[, chunksize[, callback[, error_back]]])
+   .. method:: starmap_async(func, iterable[, chunksize[, callback[, error_callback]]])
 
       A combination of :meth:`starmap` and :meth:`map_async` that iterates over
       *iterable* of iterables and calls *func* with the iterables unpacked.
@@ -2280,7 +2280,7 @@ multiple connections at the same time.
    If a welcome message is not received, then
    :exc:`~multiprocessing.AuthenticationError` is raised.
 
-.. function:: Client(address[, family[, authenticate[, authkey]]])
+.. function:: Client(address[, family[, authkey]])
 
    Attempt to set up a connection to the listener which is using address
    *address*, returning a :class:`~multiprocessing.Connection`.
@@ -2289,14 +2289,13 @@ multiple connections at the same time.
    generally be omitted since it can usually be inferred from the format of
    *address*. (See :ref:`multiprocessing-address-formats`)
 
-   If *authenticate* is ``True`` or *authkey* is a byte string then digest
-   authentication is used.  The key used for authentication will be either
-   *authkey* or ``current_process().authkey`` if *authkey* is ``None``.
-   If authentication fails then
-   :exc:`~multiprocessing.AuthenticationError` is raised.  See
-   :ref:`multiprocessing-auth-keys`.
+   If *authkey* is given and not None, it should be a byte string and will be
+   used as the secret key for an HMAC-based authentication challenge. No
+   authentication is done if *authkey* is None.
+   :exc:`~multiprocessing.AuthenticationError` is raised if authentication fails.
+   See :ref:`multiprocessing-auth-keys`.
 
-.. class:: Listener([address[, family[, backlog[, authenticate[, authkey]]]]])
+.. class:: Listener([address[, family[, backlog[, authkey]]]])
 
    A wrapper for a bound socket or Windows named pipe which is 'listening' for
    connections.
@@ -2325,17 +2324,10 @@ multiple connections at the same time.
    to the :meth:`~socket.socket.listen` method of the socket once it has been
    bound.
 
-   If *authenticate* is ``True`` (``False`` by default) or *authkey* is not
-   ``None`` then digest authentication is used.
-
-   If *authkey* is a byte string then it will be used as the
-   authentication key; otherwise it must be ``None``.
-
-   If *authkey* is ``None`` and *authenticate* is ``True`` then
-   ``current_process().authkey`` is used as the authentication key.  If
-   *authkey* is ``None`` and *authenticate* is ``False`` then no
-   authentication is done.  If authentication fails then
-   :exc:`~multiprocessing.AuthenticationError` is raised.
+   If *authkey* is given and not None, it should be a byte string and will be
+   used as the secret key for an HMAC-based authentication challenge. No
+   authentication is done if *authkey* is None.
+   :exc:`~multiprocessing.AuthenticationError` is raised if authentication fails.
    See :ref:`multiprocessing-auth-keys`.
 
    .. method:: accept()
index 8121b480cb65743110fd92f8969591341665c32a..60bf23a549b114379aa1a79d763406fb80e45824 100644 (file)
 
 The :mod:`operator` module exports a set of efficient functions corresponding to
 the intrinsic operators of Python.  For example, ``operator.add(x, y)`` is
-equivalent to the expression ``x+y``.  The function names are those used for
-special class methods; variants without leading and trailing ``__`` are also
-provided for convenience.
+equivalent to the expression ``x+y``. Many function names are those used for
+special methods, without the double underscores.  For backward compatibility,
+many of these have a variant with the double underscores kept. The variants
+without the double underscores are preferred for clarity.
 
 The functions fall into categories that perform object comparisons, logical
 operations, mathematical operations and sequence operations.
index 56fc4ed2c9420d804d05b1cbdca27a34fd48209a..fae8945f8b87ecf5b0c9bbcd33234221f5c99ee4 100644 (file)
@@ -14,8 +14,9 @@
 This module provides regular expression matching operations similar to
 those found in Perl.
 
-Both patterns and strings to be searched can be Unicode strings as well as
-8-bit strings. However, Unicode strings and 8-bit strings cannot be mixed:
+Both patterns and strings to be searched can be Unicode strings (:class:`str`)
+as well as 8-bit strings (:class:`bytes`).
+However, Unicode strings and 8-bit strings cannot be mixed:
 that is, you cannot match a Unicode string with a byte pattern or
 vice-versa; similarly, when asking for a substitution, the replacement
 string must be of the same type as both the pattern and the search string.
@@ -81,9 +82,7 @@ strings to be matched ``'in single quotes'``.)
 
 Some characters, like ``'|'`` or ``'('``, are special. Special
 characters either stand for classes of ordinary characters, or affect
-how the regular expressions around them are interpreted. Regular
-expression pattern strings may not contain null bytes, but can specify
-the null byte using a ``\number`` notation such as ``'\x00'``.
+how the regular expressions around them are interpreted.
 
 Repetition qualifiers (``*``, ``+``, ``?``, ``{m,n}``, etc) cannot be
 directly nested. This avoids ambiguity with the non-greedy modifier suffix
@@ -94,16 +93,16 @@ the expression ``(?:a{6})*`` matches any multiple of six ``'a'`` characters.
 
 The special characters are:
 
-``'.'``
+``.``
    (Dot.)  In the default mode, this matches any character except a newline.  If
    the :const:`DOTALL` flag has been specified, this matches any character
    including a newline.
 
-``'^'``
+``^``
    (Caret.)  Matches the start of the string, and in :const:`MULTILINE` mode also
    matches immediately after each newline.
 
-``'$'``
+``$``
    Matches the end of the string or just before the newline at the end of the
    string, and in :const:`MULTILINE` mode also matches before a newline.  ``foo``
    matches both 'foo' and 'foobar', while the regular expression ``foo$`` matches
@@ -112,28 +111,28 @@ The special characters are:
    a single ``$`` in ``'foo\n'`` will find two (empty) matches: one just before
    the newline, and one at the end of the string.
 
-``'*'``
+``*``
    Causes the resulting RE to match 0 or more repetitions of the preceding RE, as
    many repetitions as are possible.  ``ab*`` will match 'a', 'ab', or 'a' followed
    by any number of 'b's.
 
-``'+'``
+``+``
    Causes the resulting RE to match 1 or more repetitions of the preceding RE.
    ``ab+`` will match 'a' followed by any non-zero number of 'b's; it will not
    match just 'a'.
 
-``'?'``
+``?``
    Causes the resulting RE to match 0 or 1 repetitions of the preceding RE.
    ``ab?`` will match either 'a' or 'ab'.
 
 ``*?``, ``+?``, ``??``
    The ``'*'``, ``'+'``, and ``'?'`` qualifiers are all :dfn:`greedy`; they match
    as much text as possible.  Sometimes this behaviour isn't desired; if the RE
-   ``<.*>`` is matched against ``<a> b <c>``, it will match the entire
-   string, and not just ``<a>``.  Adding ``?`` after the qualifier makes it
+   ``<.*>`` is matched against ``'<a> b <c>'``, it will match the entire
+   string, and not just ``'<a>'``.  Adding ``?`` after the qualifier makes it
    perform the match in :dfn:`non-greedy` or :dfn:`minimal` fashion; as *few*
    characters as possible will be matched.  Using the RE ``<.*?>`` will match
-   only ``<a>``.
+   only ``'<a>'``.
 
 ``{m}``
    Specifies that exactly *m* copies of the previous RE should be matched; fewer
@@ -145,8 +144,8 @@ The special characters are:
    RE, attempting to match as many repetitions as possible.  For example,
    ``a{3,5}`` will match from 3 to 5 ``'a'`` characters.  Omitting *m* specifies a
    lower bound of zero,  and omitting *n* specifies an infinite upper bound.  As an
-   example, ``a{4,}b`` will match ``aaaab`` or a thousand ``'a'`` characters
-   followed by a ``b``, but not ``aaab``. The comma may not be omitted or the
+   example, ``a{4,}b`` will match ``'aaaab'`` or a thousand ``'a'`` characters
+   followed by a ``'b'``, but not ``'aaab'``. The comma may not be omitted or the
    modifier would be confused with the previously described form.
 
 ``{m,n}?``
@@ -156,7 +155,7 @@ The special characters are:
    6-character string ``'aaaaaa'``, ``a{3,5}`` will match 5 ``'a'`` characters,
    while ``a{3,5}?`` will only match 3 characters.
 
-``'\'``
+``\``
    Either escapes special characters (permitting you to match characters like
    ``'*'``, ``'?'``, and so forth), or signals a special sequence; special
    sequences are discussed below.
@@ -179,8 +178,8 @@ The special characters are:
      them by a ``'-'``, for example ``[a-z]`` will match any lowercase ASCII letter,
      ``[0-5][0-9]`` will match all the two-digits numbers from ``00`` to ``59``, and
      ``[0-9A-Fa-f]`` will match any hexadecimal digit.  If ``-`` is escaped (e.g.
-     ``[a\-z]``) or if it's placed as the first or last character (e.g. ``[a-]``),
-     it will match a literal ``'-'``.
+     ``[a\-z]``) or if it's placed as the first or last character
+     (e.g. ``[-a]`` or ``[a-]``), it will match a literal ``'-'``.
 
    * Special characters lose their special meaning inside sets.  For example,
      ``[(+*)]`` will match any of the literal characters ``'('``, ``'+'``,
@@ -201,13 +200,13 @@ The special characters are:
      place it at the beginning of the set.  For example, both ``[()[\]{}]`` and
      ``[]()[{}]`` will both match a parenthesis.
 
-``'|'``
-   ``A|B``, where A and B can be arbitrary REs, creates a regular expression that
-   will match either A or B.  An arbitrary number of REs can be separated by the
+``|``
+   ``A|B``, where *A* and *B* can be arbitrary REs, creates a regular expression that
+   will match either *A* or *B*.  An arbitrary number of REs can be separated by the
    ``'|'`` in this way.  This can be used inside groups (see below) as well.  As
    the target string is scanned, REs separated by ``'|'`` are tried from left to
    right. When one pattern completely matches, that branch is accepted. This means
-   that once ``A`` matches, ``B`` will not be tested further, even if it would
+   that once *A* matches, *B* will not be tested further, even if it would
    produce a longer overall match.  In other words, the ``'|'`` operator is never
    greedy.  To match a literal ``'|'``, use ``\|``, or enclose it inside a
    character class, as in ``[|]``.
@@ -217,7 +216,7 @@ The special characters are:
    start and end of a group; the contents of a group can be retrieved after a match
    has been performed, and can be matched later in the string with the ``\number``
    special sequence, described below.  To match the literals ``'('`` or ``')'``,
-   use ``\(`` or ``\)``, or enclose them inside a character class: ``[(] [)]``.
+   use ``\(`` or ``\)``, or enclose them inside a character class: ``[(]``, ``[)]``.
 
 ``(?...)``
    This is an extension notation (a ``'?'`` following a ``'('`` is not meaningful
@@ -232,10 +231,11 @@ The special characters are:
    letters set the corresponding flags: :const:`re.A` (ASCII-only matching),
    :const:`re.I` (ignore case), :const:`re.L` (locale dependent),
    :const:`re.M` (multi-line), :const:`re.S` (dot matches all),
-   and :const:`re.X` (verbose), for the entire regular expression. (The
-   flags are described in :ref:`contents-of-module-re`.) This
-   is useful if you wish to include the flags as part of the regular
-   expression, instead of passing a *flag* argument to the
+   :const:`re.U` (Unicode matching), and :const:`re.X` (verbose),
+   for the entire regular expression.
+   (The flags are described in :ref:`contents-of-module-re`.)
+   This is useful if you wish to include the flags as part of the
+   regular expression, instead of passing a *flag* argument to the
    :func:`re.compile` function.  Flags should be used first in the
    expression string.
 
@@ -272,10 +272,10 @@ The special characters are:
    | in the same pattern itself            | * ``(?P=quote)`` (as shown)      |
    |                                       | * ``\1``                         |
    +---------------------------------------+----------------------------------+
-   | when processing match object ``m``    | * ``m.group('quote')``           |
+   | when processing match object *m*      | * ``m.group('quote')``           |
    |                                       | * ``m.end('quote')`` (etc.)      |
    +---------------------------------------+----------------------------------+
-   | in a string passed to the ``repl``    | * ``\g<quote>``                  |
+   | in a string passed to the *repl*      | * ``\g<quote>``                  |
    | argument of ``re.sub()``              | * ``\g<1>``                      |
    |                                       | * ``\1``                         |
    +---------------------------------------+----------------------------------+
@@ -289,18 +289,18 @@ The special characters are:
 
 ``(?=...)``
    Matches if ``...`` matches next, but doesn't consume any of the string.  This is
-   called a lookahead assertion.  For example, ``Isaac (?=Asimov)`` will match
+   called a :dfn:`lookahead assertion`.  For example, ``Isaac (?=Asimov)`` will match
    ``'Isaac '`` only if it's followed by ``'Asimov'``.
 
 ``(?!...)``
-   Matches if ``...`` doesn't match next.  This is a negative lookahead assertion.
+   Matches if ``...`` doesn't match next.  This is a :dfn:`negative lookahead assertion`.
    For example, ``Isaac (?!Asimov)`` will match ``'Isaac '`` only if it's *not*
    followed by ``'Asimov'``.
 
 ``(?<=...)``
    Matches if the current position in the string is preceded by a match for ``...``
    that ends at the current position.  This is called a :dfn:`positive lookbehind
-   assertion`. ``(?<=abc)def`` will find a match in ``abcdef``, since the
+   assertion`. ``(?<=abc)def`` will find a match in ``'abcdef'``, since the
    lookbehind will back up 3 characters and check if the contained pattern matches.
    The contained pattern must only match strings of some fixed length, meaning that
    ``abc`` or ``a|b`` are allowed, but ``a*`` and ``a{3,4}`` are not.  Note that
@@ -358,26 +358,26 @@ character ``'$'``.
 
 ``\b``
    Matches the empty string, but only at the beginning or end of a word.
-   A word is defined as a sequence of Unicode alphanumeric or underscore
-   characters, so the end of a word is indicated by whitespace or a
-   non-alphanumeric, non-underscore Unicode character.  Note that formally,
+   A word is defined as a sequence of word characters.  Note that formally,
    ``\b`` is defined as the boundary between a ``\w`` and a ``\W`` character
    (or vice versa), or between ``\w`` and the beginning/end of the string.
    This means that ``r'\bfoo\b'`` matches ``'foo'``, ``'foo.'``, ``'(foo)'``,
    ``'bar foo baz'`` but not ``'foobar'`` or ``'foo3'``.
 
-   By default Unicode alphanumerics are the ones used, but this can  be changed
-   by using the :const:`ASCII` flag.  Inside a character range, ``\b``
-   represents the backspace character, for compatibility with Python's string
-   literals.
+   By default Unicode alphanumerics are the ones used in Unicode patterns, but
+   this can be changed by using the :const:`ASCII` flag.  Word boundaries are
+   determined by the current locale if the :const:`LOCALE` flag is used.
+   Inside a character range, ``\b`` represents the backspace character, for
+   compatibility with Python's string literals.
 
 ``\B``
    Matches the empty string, but only when it is *not* at the beginning or end
    of a word.  This means that ``r'py\B'`` matches ``'python'``, ``'py3'``,
    ``'py2'``, but not ``'py'``, ``'py.'``, or ``'py!'``.
-   ``\B`` is just the opposite of ``\b``, so word characters are
-   Unicode alphanumerics or the underscore, although this can be changed
-   by using the :const:`ASCII` flag.
+   ``\B`` is just the opposite of ``\b``, so word characters in Unicode
+   patterns are Unicode alphanumerics or the underscore, although this can
+   be changed by using the :const:`ASCII` flag.  Word boundaries are
+   determined by the current locale if the :const:`LOCALE` flag is used.
 
 ``\d``
    For Unicode (str) patterns:
@@ -387,11 +387,12 @@ character ``'$'``.
       used only ``[0-9]`` is matched (but the flag affects the entire
       regular expression, so in such cases using an explicit ``[0-9]``
       may be a better choice).
+
    For 8-bit (bytes) patterns:
       Matches any decimal digit; this is equivalent to ``[0-9]``.
 
 ``\D``
-   Matches any character which is not a Unicode decimal digit. This is
+   Matches any character which is not a decimal digit. This is
    the opposite of ``\d``. If the :const:`ASCII` flag is used this
    becomes the equivalent of ``[^0-9]`` (but the flag affects the entire
    regular expression, so in such cases using an explicit ``[^0-9]`` may
@@ -412,7 +413,7 @@ character ``'$'``.
       this is equivalent to ``[ \t\n\r\f\v]``.
 
 ``\S``
-   Matches any character which is not a Unicode whitespace character. This is
+   Matches any character which is not a whitespace character. This is
    the opposite of ``\s``. If the :const:`ASCII` flag is used this
    becomes the equivalent of ``[^ \t\n\r\f\v]`` (but the flag affects the entire
    regular expression, so in such cases using an explicit ``[^ \t\n\r\f\v]`` may
@@ -426,16 +427,21 @@ character ``'$'``.
       ``[a-zA-Z0-9_]`` is matched (but the flag affects the entire
       regular expression, so in such cases using an explicit
       ``[a-zA-Z0-9_]`` may be a better choice).
+
    For 8-bit (bytes) patterns:
       Matches characters considered alphanumeric in the ASCII character set;
-      this is equivalent to ``[a-zA-Z0-9_]``.
+      this is equivalent to ``[a-zA-Z0-9_]``.  If the :const:`LOCALE` flag is
+      used, matches characters considered alphanumeric in the current locale
+      and the underscore.
 
 ``\W``
-   Matches any character which is not a Unicode word character. This is
+   Matches any character which is not a word character. This is
    the opposite of ``\w``. If the :const:`ASCII` flag is used this
    becomes the equivalent of ``[^a-zA-Z0-9_]`` (but the flag affects the
    entire regular expression, so in such cases using an explicit
-   ``[^a-zA-Z0-9_]`` may be a better choice).
+   ``[^a-zA-Z0-9_]`` may be a better choice).  If the :const:`LOCALE` flag is
+   used, matches characters considered alphanumeric in the current locale
+   and the underscore.
 
 ``\Z``
    Matches only at the end of the string.
@@ -451,7 +457,7 @@ accepted by the regular expression parser::
 only inside character classes.)
 
 ``'\u'`` and ``'\U'`` escape sequences are only recognized in Unicode
-patterns.  In bytes patterns they are not treated specially.
+patterns.  In bytes patterns they are errors.
 
 Octal escapes are included in a limited form.  If the first digit is a 0, or if
 there are three octal digits, it is considered an octal escape. Otherwise, it is
@@ -526,6 +532,7 @@ form.
    Make ``\w``, ``\W``, ``\b``, ``\B``, ``\d``, ``\D``, ``\s`` and ``\S``
    perform ASCII-only matching instead of full Unicode matching.  This is only
    meaningful for Unicode patterns, and is ignored for byte patterns.
+   Corresponds to the inline flag ``(?a)``.
 
    Note that for backward compatibility, the :const:`re.U` flag still
    exists (as well as its synonym :const:`re.UNICODE` and its embedded
@@ -537,26 +544,40 @@ form.
 .. data:: DEBUG
 
    Display debug information about compiled expression.
+   No corresponding inline flag.
 
 
 .. data:: I
           IGNORECASE
 
    Perform case-insensitive matching; expressions like ``[A-Z]`` will also
-   match lowercase letters.  The current locale does not change the effect of
-   this flag.  Full Unicode matching (such as ``Ü`` matching ``ü``) also
-   works unless the :const:`re.ASCII` flag is also used to disable non-ASCII
-   matches.
-
+   match lowercase letters.  Full Unicode matching (such as ``Ü`` matching
+   ``ü``) also works unless the :const:`re.ASCII` flag is used to disable
+   non-ASCII matches.  The current locale does not change the effect of this
+   flag unless the :const:`re.LOCALE` flag is also used.
+   Corresponds to the inline flag ``(?i)``.
+
+   Note that when the Unicode patterns ``[a-z]`` or ``[A-Z]`` are used in
+   combination with the :const:`IGNORECASE` flag, they will match the 52 ASCII
+   letters and 4 additional non-ASCII letters: 'İ' (U+0130, Latin capital
+   letter I with dot above), 'ı' (U+0131, Latin small letter dotless i),
+   'ſ' (U+017F, Latin small letter long s) and 'K' (U+212A, Kelvin sign).
+   If the :const:`ASCII` flag is used, only letters 'a' to 'z'
+   and 'A' to 'Z' are matched (but the flag affects the entire regular
+   expression, so in such cases using an explicit ``(?-i:[a-zA-Z])`` may be
+   a better choice).
 
 .. data:: L
           LOCALE
 
-   Make ``\w``, ``\W``, ``\b``, ``\B``, ``\s`` and ``\S`` dependent on the
-   current locale. The use of this flag is discouraged as the locale mechanism
-   is very unreliable, and it only handles one "culture" at a time anyway;
-   you should use Unicode matching instead, which is the default in Python 3
-   for Unicode (str) patterns. This flag can be used only with bytes patterns.
+   Make ``\w``, ``\W``, ``\b``, ``\B`` and case-insensitive matching
+   dependent on the current locale.  This flag can be used only with bytes
+   patterns.  The use of this flag is discouraged as the locale mechanism
+   is very unreliable, it only handles one "culture" at a time, and it only
+   works with 8-bit locales.  Unicode matching is already enabled by default
+   in Python 3 for Unicode (str) patterns, and it is able to handle different
+   locales/languages.
+   Corresponds to the inline flag ``(?L)``.
 
    .. versionchanged:: 3.6
       :const:`re.LOCALE` can be used only with bytes patterns and is
@@ -572,6 +593,7 @@ form.
    end of each line (immediately preceding each newline).  By default, ``'^'``
    matches only at the beginning of the string, and ``'$'`` only at the end of the
    string and immediately before the newline (if any) at the end of the string.
+   Corresponds to the inline flag ``(?m)``.
 
 
 .. data:: S
@@ -579,6 +601,7 @@ form.
 
    Make the ``'.'`` special character match any character at all, including a
    newline; without this flag, ``'.'`` will match anything *except* a newline.
+   Corresponds to the inline flag ``(?s)``.
 
 
 .. data:: X
@@ -587,7 +610,8 @@ form.
    This flag allows you to write regular expressions that look nicer and are
    more readable by allowing you to visually separate logical sections of the
    pattern and add comments. Whitespace within the pattern is ignored, except
-   when in a character class or when preceded by an unescaped backslash.
+   when in a character class, or when preceded by an unescaped backslash,
+   or within tokens like ``*?``, ``(?:`` or ``(?P<...>``.
    When a line contains a ``#`` that is not in a character class and is not
    preceded by an unescaped backslash, all characters from the leftmost such
    ``#`` through the end of the line are ignored.
@@ -600,7 +624,7 @@ form.
                          \d *  # some fractional digits""", re.X)
       b = re.compile(r"\d+\.\d*")
 
-
+   Corresponds to the inline flag ``(?x)``.
 
 
 .. function:: search(pattern, string, flags=0)
@@ -644,20 +668,20 @@ form.
    splits occur, and the remainder of the string is returned as the final element
    of the list. ::
 
-      >>> re.split('\W+', 'Words, words, words.')
+      >>> re.split(r'\W+', 'Words, words, words.')
       ['Words', 'words', 'words', '']
-      >>> re.split('(\W+)', 'Words, words, words.')
+      >>> re.split(r'(\W+)', 'Words, words, words.')
       ['Words', ', ', 'words', ', ', 'words', '.', '']
-      >>> re.split('\W+', 'Words, words, words.', 1)
+      >>> re.split(r'\W+', 'Words, words, words.', 1)
       ['Words', 'words, words.']
       >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
       ['0', '3', '9']
 
    If there are capturing groups in the separator and it matches at the start of
    the string, the result will start with an empty string.  The same holds for
-   the end of the string:
+   the end of the string::
 
-      >>> re.split('(\W+)', '...words, words...')
+      >>> re.split(r'(\W+)', '...words, words...')
       ['', '...', 'words', ', ', 'words', '...', '']
 
    That way, separator components are always found at the same relative
@@ -666,7 +690,7 @@ form.
    .. note::
 
       :func:`split` doesn't currently split a string on an empty pattern match.
-      For example:
+      For example::
 
          >>> re.split('x*', 'axbc')
          ['a', 'bc']
@@ -723,7 +747,7 @@ form.
    converted to a single newline character, ``\r`` is converted to a carriage return, and
    so forth.  Unknown escapes such as ``\&`` are left alone.  Backreferences, such
    as ``\6``, are replaced with the substring matched by group 6 in the pattern.
-   For example:
+   For example::
 
       >>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
       ...        r'static PyObject*\npy_\1(void)\n{',
@@ -731,8 +755,8 @@ form.
       'static PyObject*\npy_myfunc(void)\n{'
 
    If *repl* is a function, it is called for every non-overlapping occurrence of
-   *pattern*.  The function takes a single match object argument, and returns the
-   replacement string.  For example:
+   *pattern*.  The function takes a single :ref:`match object <match-objects>`
+   argument, and returns the replacement string.  For example::
 
       >>> def dashrepl(matchobj):
       ...     if matchobj.group(0) == '-': return ' '
@@ -742,7 +766,7 @@ form.
       >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
       'Baked Beans & Spam'
 
-   The pattern may be a string or an RE object.
+   The pattern may be a string or a :ref:`pattern object <re-objects>`.
 
    The optional argument *count* is the maximum number of pattern occurrences to be
    replaced; *count* must be a non-negative integer.  If omitted or zero, all
@@ -804,6 +828,14 @@ form.
       >>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
       \/|\-|\+|\*\*|\*
 
+   This functions must not be used for the replacement string in :func:`sub`
+   and :func:`subn`, only backslashes should be escaped.  For example::
+
+      >>> digits_re = r'\d+'
+      >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'
+      >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))
+      /usr/sbin/sendmail - \d+ errors, \d+ warnings
+
    .. versionchanged:: 3.3
       The ``'_'`` character is no longer escaped.
 
@@ -871,12 +903,12 @@ attributes:
    from *pos* to ``endpos - 1`` will be searched for a match.  If *endpos* is less
    than *pos*, no match will be found; otherwise, if *rx* is a compiled regular
    expression object, ``rx.search(string, 0, 50)`` is equivalent to
-   ``rx.search(string[:50], 0)``.
+   ``rx.search(string[:50], 0)``. ::
 
-   >>> pattern = re.compile("d")
-   >>> pattern.search("dog")     # Match at index 0
-   <_sre.SRE_Match object; span=(0, 1), match='d'>
-   >>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
+      >>> pattern = re.compile("d")
+      >>> pattern.search("dog")     # Match at index 0
+      <_sre.SRE_Match object; span=(0, 1), match='d'>
+      >>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
 
 
 .. method:: regex.match(string[, pos[, endpos]])
@@ -887,12 +919,12 @@ attributes:
    different from a zero-length match.
 
    The optional *pos* and *endpos* parameters have the same meaning as for the
-   :meth:`~regex.search` method.
+   :meth:`~regex.search` method. ::
 
-   >>> pattern = re.compile("o")
-   >>> pattern.match("dog")      # No match as "o" is not at the start of "dog".
-   >>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog".
-   <_sre.SRE_Match object; span=(1, 2), match='o'>
+      >>> pattern = re.compile("o")
+      >>> pattern.match("dog")      # No match as "o" is not at the start of "dog".
+      >>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog".
+      <_sre.SRE_Match object; span=(1, 2), match='o'>
 
    If you want to locate a match anywhere in *string*, use
    :meth:`~regex.search` instead (see also :ref:`search-vs-match`).
@@ -905,13 +937,13 @@ attributes:
    match the pattern; note that this is different from a zero-length match.
 
    The optional *pos* and *endpos* parameters have the same meaning as for the
-   :meth:`~regex.search` method.
+   :meth:`~regex.search` method. ::
 
-   >>> pattern = re.compile("o[gh]")
-   >>> pattern.fullmatch("dog")      # No match as "o" is not at the start of "dog".
-   >>> pattern.fullmatch("ogre")     # No match as not the full string matches.
-   >>> pattern.fullmatch("doggie", 1, 3)   # Matches within given limits.
-   <_sre.SRE_Match object; span=(1, 3), match='og'>
+      >>> pattern = re.compile("o[gh]")
+      >>> pattern.fullmatch("dog")      # No match as "o" is not at the start of "dog".
+      >>> pattern.fullmatch("ogre")     # No match as not the full string matches.
+      >>> pattern.fullmatch("doggie", 1, 3)   # Matches within given limits.
+      <_sre.SRE_Match object; span=(1, 3), match='og'>
 
    .. versionadded:: 3.4
 
@@ -925,14 +957,14 @@ attributes:
 
    Similar to the :func:`findall` function, using the compiled pattern, but
    also accepts optional *pos* and *endpos* parameters that limit the search
-   region like for :meth:`match`.
+   region like for :meth:`search`.
 
 
 .. method:: regex.finditer(string[, pos[, endpos]])
 
    Similar to the :func:`finditer` function, using the compiled pattern, but
    also accepts optional *pos* and *endpos* parameters that limit the search
-   region like for :meth:`match`.
+   region like for :meth:`search`.
 
 
 .. method:: regex.sub(repl, string, count=0)
@@ -1010,7 +1042,7 @@ Match objects support the following methods and attributes:
    pattern, an :exc:`IndexError` exception is raised. If a group is contained in a
    part of the pattern that did not match, the corresponding result is ``None``.
    If a group is contained in a part of the pattern that matched multiple times,
-   the last match is returned.
+   the last match is returned. ::
 
       >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
       >>> m.group(0)       # The entire match
@@ -1027,7 +1059,7 @@ Match objects support the following methods and attributes:
    string argument is not used as a group name in the pattern, an :exc:`IndexError`
    exception is raised.
 
-   A moderately complicated example:
+   A moderately complicated example::
 
       >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
       >>> m.group('first_name')
@@ -1035,14 +1067,14 @@ Match objects support the following methods and attributes:
       >>> m.group('last_name')
       'Reynolds'
 
-   Named groups can also be referred to by their index:
+   Named groups can also be referred to by their index::
 
       >>> m.group(1)
       'Malcolm'
       >>> m.group(2)
       'Reynolds'
 
-   If a group matches multiple times, only the last match is accessible:
+   If a group matches multiple times, only the last match is accessible::
 
       >>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
       >>> m.group(1)                        # Returns only the last match.
@@ -1052,7 +1084,7 @@ Match objects support the following methods and attributes:
 .. method:: match.__getitem__(g)
 
    This is identical to ``m.group(g)``.  This allows easier access to
-   an individual group from a match:
+   an individual group from a match::
 
       >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
       >>> m[0]       # The entire match
@@ -1071,7 +1103,7 @@ Match objects support the following methods and attributes:
    many groups are in the pattern.  The *default* argument is used for groups that
    did not participate in the match; it defaults to ``None``.
 
-   For example:
+   For example::
 
       >>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
       >>> m.groups()
@@ -1079,7 +1111,7 @@ Match objects support the following methods and attributes:
 
    If we make the decimal place and everything after it optional, not all groups
    might participate in the match.  These groups will default to ``None`` unless
-   the *default* argument is given:
+   the *default* argument is given::
 
       >>> m = re.match(r"(\d+)\.?(\d+)?", "24")
       >>> m.groups()      # Second group defaults to None.
@@ -1092,7 +1124,7 @@ Match objects support the following methods and attributes:
 
    Return a dictionary containing all the *named* subgroups of the match, keyed by
    the subgroup name.  The *default* argument is used for groups that did not
-   participate in the match; it defaults to ``None``.  For example:
+   participate in the match; it defaults to ``None``.  For example::
 
       >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
       >>> m.groupdict()
@@ -1115,7 +1147,7 @@ Match objects support the following methods and attributes:
    ``m.start(0)`` is 1, ``m.end(0)`` is 2, ``m.start(1)`` and ``m.end(1)`` are both
    2, and ``m.start(2)`` raises an :exc:`IndexError` exception.
 
-   An example that will remove *remove_this* from email addresses:
+   An example that will remove *remove_this* from email addresses::
 
       >>> email = "tony@tiremove_thisger.net"
       >>> m = re.search("remove_this", email)
@@ -1161,7 +1193,7 @@ Match objects support the following methods and attributes:
 
 .. attribute:: match.re
 
-   The regular expression object whose :meth:`~regex.match` or
+   The :ref:`regular expression object <re-objects>` whose :meth:`~regex.match` or
    :meth:`~regex.search` method produced this match instance.
 
 
@@ -1194,7 +1226,7 @@ a 5-character string with each character representing a card, "a" for ace, "k"
 for king, "q" for queen, "j" for jack, "t" for 10, and "2" through "9"
 representing the card with that value.
 
-To see if a given string is a valid hand, one could do the following:
+To see if a given string is a valid hand, one could do the following::
 
    >>> valid = re.compile(r"^[a2-9tjqk]{5}$")
    >>> displaymatch(valid.match("akt5q"))  # Valid.
@@ -1205,7 +1237,7 @@ To see if a given string is a valid hand, one could do the following:
    "<Match: '727ak', groups=()>"
 
 That last hand, ``"727ak"``, contained a pair, or two of the same valued cards.
-To match this with a regular expression, one could use backreferences as such:
+To match this with a regular expression, one could use backreferences as such::
 
    >>> pair = re.compile(r".*(.).*\1")
    >>> displaymatch(pair.match("717ak"))     # Pair of 7s.
@@ -1307,7 +1339,7 @@ restrict the match at the beginning of the string::
 
 Note however that in :const:`MULTILINE` mode :func:`match` only matches at the
 beginning of the string, whereas using :func:`search` with a regular expression
-beginning with ``'^'`` will match at the beginning of each line.
+beginning with ``'^'`` will match at the beginning of each line. ::
 
    >>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
    >>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
@@ -1323,7 +1355,7 @@ easily read and modified by Python as demonstrated in the following example that
 creates a phonebook.
 
 First, here is the input.  Normally it may come from a file, here we are using
-triple-quoted string syntax:
+triple-quoted string syntax::
 
    >>> text = """Ross McFluff: 834.345.1254 155 Elm Street
    ...
@@ -1398,7 +1430,7 @@ Finding all Adverbs
 :func:`findall` matches *all* occurrences of a pattern, not just the first
 one as :func:`search` does.  For example, if one was a writer and wanted to
 find all of the adverbs in some text, he or she might use :func:`findall` in
-the following manner:
+the following manner::
 
    >>> text = "He was carefully disguised but captured quickly by police."
    >>> re.findall(r"\w+ly", text)
@@ -1412,7 +1444,7 @@ If one wants more information about all matches of a pattern than the matched
 text, :func:`finditer` is useful as it provides :ref:`match objects
 <match-objects>` instead of strings.  Continuing with the previous example, if
 one was a writer who wanted to find all of the adverbs *and their positions* in
-some text, he or she would use :func:`finditer` in the following manner:
+some text, he or she would use :func:`finditer` in the following manner::
 
    >>> text = "He was carefully disguised but captured quickly by police."
    >>> for m in re.finditer(r"\w+ly", text):
@@ -1427,7 +1459,7 @@ Raw String Notation
 Raw string notation (``r"text"``) keeps regular expressions sane.  Without it,
 every backslash (``'\'``) in a regular expression would have to be prefixed with
 another one to escape it.  For example, the two following lines of code are
-functionally identical:
+functionally identical::
 
    >>> re.match(r"\W(.)\1\W", " ff ")
    <_sre.SRE_Match object; span=(0, 4), match=' ff '>
@@ -1437,7 +1469,7 @@ functionally identical:
 When one wants to match a literal backslash, it must be escaped in the regular
 expression.  With raw string notation, this means ``r"\\"``.  Without raw string
 notation, one must use ``"\\\\"``, making the following lines of code
-functionally identical:
+functionally identical::
 
    >>> re.match(r"\\", r"\\")
    <_sre.SRE_Match object; span=(0, 1), match='\\'>
index 54c54b461ce7e43ed006829a04b10dd5ad104601..837816e952ad566954c664b7b563df5615efbed8 100644 (file)
@@ -312,13 +312,13 @@ sessions, by only appending the new history. ::
 
    try:
        readline.read_history_file(histfile)
-       h_len = readline.get_history_length()
+       h_len = readline.get_current_history_length()
    except FileNotFoundError:
        open(histfile, 'wb').close()
        h_len = 0
 
    def save(prev_h_len, histfile):
-       new_h_len = readline.get_history_length()
+       new_h_len = readline.get_current_history_length()
        readline.set_history_length(1000)
        readline.append_history_file(new_h_len - prev_h_len, histfile)
    atexit.register(save, h_len, histfile)
index 4d4a6161057cc5cec1d2133459c51982012b6273..6094a7b871454ed10004528d94fd29edfc7f4612 100644 (file)
@@ -69,7 +69,7 @@ Scheduler Objects
    Schedule a new event. The *time* argument should be a numeric type compatible
    with the return value of the *timefunc* function passed  to the constructor.
    Events scheduled for the same *time* will be executed in the order of their
-   *priority*.
+   *priority*. A lower number represents a higher priority.
 
    Executing the event means executing ``action(*argument, **kwargs)``.
    *argument* is a sequence holding the positional arguments for *action*.
index 218a31c848aa1b1960e742b4c50ad08f06ec433d..e12c8c97844fa71b785679382bc98b77b197b863 100644 (file)
@@ -289,7 +289,7 @@ Server Objects
    .. XXX should the default implementations of these be documented, or should
       it be assumed that the user will look at socketserver.py?
 
-   .. method:: finish_request()
+   .. method:: finish_request(request, client_address)
 
       Actually processes the request by instantiating :attr:`RequestHandlerClass` and
       calling its :meth:`~BaseRequestHandler.handle` method.
index 9fef7d7f03f1f00d7761bd6f01e241d8207b9454..ef0c0bf64cdadd76c2465da52ccb9b3689e9f0d5 100644 (file)
@@ -421,6 +421,10 @@ Connection Objects
       If you want to clear any previously installed progress handler, call the
       method with :const:`None` for *handler*.
 
+      Returning a non-zero value from the handler function will terminate the
+      currently executing query and cause it to raise an :exc:`OperationalError`
+      exception.
+
 
    .. method:: set_trace_callback(trace_callback)
 
index d7e0467239bce83e9c98896b535a0da7d0172164..495cd590f8972e27f7f042885db0100c33ca326d 100644 (file)
@@ -218,7 +218,7 @@ instead.
 
    The *ciphers* parameter sets the available ciphers for this SSL object.
    It should be a string in the `OpenSSL cipher list format
-   <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`_.
+   <https://wiki.openssl.org/index.php/Manual:Ciphers(1)#CIPHER_LIST_FORMAT>`_.
 
    The parameter ``do_handshake_on_connect`` specifies whether to do the SSL
    handshake automatically after doing a :meth:`socket.connect`, or whether the
@@ -1445,7 +1445,7 @@ to speed up repeated connections from the same clients.
 
    Set the available ciphers for sockets created with this context.
    It should be a string in the `OpenSSL cipher list format
-   <https://www.openssl.org/docs/apps/ciphers.html#CIPHER-LIST-FORMAT>`_.
+   <https://wiki.openssl.org/index.php/Manual:Ciphers(1)#CIPHER_LIST_FORMAT>`_.
    If no cipher can be selected (because compile-time options or other
    configuration forbids use of all the specified ciphers), an
    :class:`SSLError` will be raised.
index b8c4d59363d2a6557962b5f39baa3eb295f32d2f..75e97b9d8f5bbecfcabc258537f022ac69869ac5 100644 (file)
@@ -2564,8 +2564,9 @@ arbitrary binary data.
             bytearray.partition(sep)
 
    Split the sequence at the first occurrence of *sep*, and return a 3-tuple
-   containing the part before the separator, the separator, and the part
-   after the separator.  If the separator is not found, return a 3-tuple
+   containing the part before the separator, the separator itself or its
+   bytearray copy, and the part after the separator.
+   If the separator is not found, return a 3-tuple
    containing a copy of the original sequence, followed by two empty bytes or
    bytearray objects.
 
@@ -2620,8 +2621,9 @@ arbitrary binary data.
             bytearray.rpartition(sep)
 
    Split the sequence at the last occurrence of *sep*, and return a 3-tuple
-   containing the part before the separator, the separator, and the part
-   after the separator.  If the separator is not found, return a 3-tuple
+   containing the part before the separator, the separator itself or its
+   bytearray copy, and the part after the separator.
+   If the separator is not found, return a 3-tuple
    containing a copy of the original sequence, followed by two empty bytes or
    bytearray objects.
 
index a0977b6461339429952926be9a2054a2c7440a88..7a9fcc38bbded80ab5c6750e6f44317c4e44ee95 100644 (file)
@@ -746,8 +746,18 @@ to parse template strings.  To do this, you can override these class attributes:
 
 * *idpattern* -- This is the regular expression describing the pattern for
   non-braced placeholders (the braces will be added automatically as
-  appropriate).  The default value is the regular expression
-  ``[_a-z][_a-z0-9]*``.
+  appropriate). The default value is the regular expression
+  ``(?-i:[_a-zA-Z][_a-zA-Z0-9]*)``.
+
+  .. note::
+
+     Since default *flags* is ``re.IGNORECASE``, pattern ``[a-z]`` can match
+     with some non-ASCII characters. That's why we use local ``-i`` flag here.
+
+     While *flags* is kept to ``re.IGNORECASE`` for backward compatibility,
+     you can override it to ``0`` or ``re.IGNORECASE | re.ASCII`` when
+     subclassing.
+
 
 * *flags* -- The regular expression flags that will be applied when compiling
   the regular expression used for recognizing substitutions.  The default value
index 27f3e825961e1a1b7d6a8f1c3de2894c848926c0..ea7e664f578bbc0fb8de64886ea9e28ff8b5a45d 100644 (file)
@@ -584,7 +584,7 @@ Instances of the :class:`Popen` class have the following methods:
 .. method:: Popen.poll()
 
    Check if child process has terminated.  Set and return
-   :attr:`~Popen.returncode` attribute.
+   :attr:`~Popen.returncode` attribute. Otherwise, returns ``None``.
 
 
 .. method:: Popen.wait(timeout=None)
index ad6a9f7c972dae03d39a69d3ef2535dbf5fc2566..7693ecd02789ccb37cd43d4b1891a9be4d8b9d6a 100644 (file)
@@ -12,7 +12,7 @@
 --------------
 
 This module provides an interface to the POSIX calls for tty I/O control. For a
-complete description of these calls, see :manpage:`termios(2)` Unix manual
+complete description of these calls, see :manpage:`termios(3)` Unix manual
 page.  It is only available for those Unix versions that support POSIX
 *termios* style tty I/O control configured during installation.
 
index 9d4ff7ad8b45a3830ba1e319455e230ba7022205..1a3f8f9c5dce1c106e876f3fb19e6e5ca68de6ae 100644 (file)
@@ -440,7 +440,7 @@ The :mod:`test.support` module defines the following functions:
    otherwise.
 
 
-.. decorator:: skip_unless_symlink()
+.. decorator:: skip_unless_symlink
 
    A decorator for running tests that require support for symbolic links.
 
index 021e29e7124840c81e9f6956cf26261eca50e15a..c375754629e1f44af390dee57de023f1af558822 100644 (file)
@@ -291,10 +291,10 @@ since it is impossible to detect the termination of alien threads.
    .. attribute:: ident
 
       The 'thread identifier' of this thread or ``None`` if the thread has not
-      been started.  This is a nonzero integer.  See the
-      :func:`_thread.get_ident()` function.  Thread identifiers may be recycled
-      when a thread exits and another thread is created.  The identifier is
-      available even after the thread has exited.
+      been started.  This is a nonzero integer.  See the :func:`get_ident`
+      function.  Thread identifiers may be recycled when a thread exits and
+      another thread is created.  The identifier is available even after the
+      thread has exited.
 
    .. method:: is_alive()
 
index d2e2ac4410aba363a39cb321a954dcba3eba59b6..0624099f67524dfebe22f181ebdbffac2e7a9f96 100644 (file)
@@ -118,14 +118,10 @@ An explanation of some terminology and conventions is in order.
   +-------------------------+-------------------------+-------------------------+
 
 
-The module defines the following functions and data items:
-
-.. data:: altzone
-
-   The offset of the local DST timezone, in seconds west of UTC, if one is defined.
-   This is negative if the local DST timezone is east of UTC (as in Western Europe,
-   including the UK).  Only use this if ``daylight`` is nonzero.
+.. _time-functions:
 
+Functions
+---------
 
 .. function:: asctime([t])
 
@@ -165,7 +161,8 @@ The module defines the following functions and data items:
 
 .. function:: clock_getres(clk_id)
 
-   Return the resolution (precision) of the specified clock *clk_id*.
+   Return the resolution (precision) of the specified clock *clk_id*.  Refer to
+   :ref:`time-clock-id-constants` for a list of accepted values for *clk_id*.
 
    Availability: Unix.
 
@@ -174,7 +171,8 @@ The module defines the following functions and data items:
 
 .. function:: clock_gettime(clk_id)
 
-   Return the time of the specified clock *clk_id*.
+   Return the time of the specified clock *clk_id*.  Refer to
+   :ref:`time-clock-id-constants` for a list of accepted values for *clk_id*.
 
    Availability: Unix.
 
@@ -183,66 +181,8 @@ The module defines the following functions and data items:
 
 .. function:: clock_settime(clk_id, time)
 
-   Set the time of the specified clock *clk_id*.
-
-   Availability: Unix.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_HIGHRES
-
-   The Solaris OS has a CLOCK_HIGHRES timer that attempts to use an optimal
-   hardware source, and may give close to nanosecond resolution.  CLOCK_HIGHRES
-   is the nonadjustable, high-resolution clock.
-
-   Availability: Solaris.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_MONOTONIC
-
-   Clock that cannot be set and represents monotonic time since some unspecified
-   starting point.
-
-   Availability: Unix.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_MONOTONIC_RAW
-
-   Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw
-   hardware-based time that is not subject to NTP adjustments.
-
-   Availability: Linux 2.6.28 or later.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_PROCESS_CPUTIME_ID
-
-   High-resolution per-process timer from the CPU.
-
-   Availability: Unix.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_REALTIME
-
-   System-wide real-time clock.  Setting this clock requires appropriate
-   privileges.
-
-   Availability: Unix.
-
-   .. versionadded:: 3.3
-
-
-.. data:: CLOCK_THREAD_CPUTIME_ID
-
-   Thread-specific CPU-time clock.
+   Set the time of the specified clock *clk_id*.  Currently,
+   :data:`CLOCK_REALTIME` is the only accepted value for *clk_id*.
 
    Availability: Unix.
 
@@ -257,11 +197,6 @@ The module defines the following functions and data items:
    ``asctime(localtime(secs))``. Locale information is not used by :func:`ctime`.
 
 
-.. data:: daylight
-
-   Nonzero if a DST timezone is defined.
-
-
 .. function:: get_clock_info(name)
 
    Get information on the specified clock as a namespace object.
@@ -279,7 +214,7 @@ The module defines the following functions and data items:
    - *adjustable*: ``True`` if the clock can be changed automatically (e.g. by
      a NTP daemon) or manually by the system administrator, ``False`` otherwise
    - *implementation*: The name of the underlying C function used to get
-     the clock value
+     the clock value.  Refer to :ref:`time-clock-id-constants` for possible values.
    - *monotonic*: ``True`` if the clock cannot go backward,
      ``False`` otherwise
    - *resolution*: The resolution of the clock in seconds (:class:`float`)
@@ -607,18 +542,6 @@ The module defines the following functions and data items:
    :class:`struct_time` object is returned, from which the components
    of the calendar date may be accessed as attributes.
 
-.. data:: timezone
-
-   The offset of the local (non-DST) timezone, in seconds west of UTC (negative in
-   most of Western Europe, positive in the US, zero in the UK).
-
-
-.. data:: tzname
-
-   A tuple of two strings: the first is the name of the local non-DST timezone, the
-   second is the name of the local DST timezone.  If no DST timezone is defined,
-   the second string should not be used.
-
 
 .. function:: tzset()
 
@@ -703,6 +626,111 @@ The module defines the following functions and data items:
       ('EET', 'EEST')
 
 
+.. _time-clock-id-constants:
+
+Clock ID Constants
+------------------
+
+These constants are used as parameters for :func:`clock_getres` and
+:func:`clock_gettime`.
+
+.. data:: CLOCK_HIGHRES
+
+   The Solaris OS has a ``CLOCK_HIGHRES`` timer that attempts to use an optimal
+   hardware source, and may give close to nanosecond resolution.
+   ``CLOCK_HIGHRES`` is the nonadjustable, high-resolution clock.
+
+   Availability: Solaris.
+
+   .. versionadded:: 3.3
+
+
+.. data:: CLOCK_MONOTONIC
+
+   Clock that cannot be set and represents monotonic time since some unspecified
+   starting point.
+
+   Availability: Unix.
+
+   .. versionadded:: 3.3
+
+
+.. data:: CLOCK_MONOTONIC_RAW
+
+   Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw
+   hardware-based time that is not subject to NTP adjustments.
+
+   Availability: Linux 2.6.28 or later.
+
+   .. versionadded:: 3.3
+
+
+.. data:: CLOCK_PROCESS_CPUTIME_ID
+
+   High-resolution per-process timer from the CPU.
+
+   Availability: Unix.
+
+   .. versionadded:: 3.3
+
+
+.. data:: CLOCK_THREAD_CPUTIME_ID
+
+   Thread-specific CPU-time clock.
+
+   Availability: Unix.
+
+   .. versionadded:: 3.3
+
+
+The following constant is the only parameter that can be sent to
+:func:`clock_settime`.
+
+.. data:: CLOCK_REALTIME
+
+   System-wide real-time clock.  Setting this clock requires appropriate
+   privileges.
+
+   Availability: Unix.
+
+   .. versionadded:: 3.3
+
+
+.. _time-timezone-constants:
+
+Timezone Constants
+-------------------
+
+.. data:: altzone
+
+   The offset of the local DST timezone, in seconds west of UTC, if one is defined.
+   This is negative if the local DST timezone is east of UTC (as in Western Europe,
+   including the UK).  Only use this if ``daylight`` is nonzero.  See note below.
+
+.. data:: daylight
+
+   Nonzero if a DST timezone is defined.  See note below.
+
+.. data:: timezone
+
+   The offset of the local (non-DST) timezone, in seconds west of UTC (negative in
+   most of Western Europe, positive in the US, zero in the UK).  See note below.
+
+.. data:: tzname
+
+   A tuple of two strings: the first is the name of the local non-DST timezone, the
+   second is the name of the local DST timezone.  If no DST timezone is defined,
+   the second string should not be used.  See note below.
+
+.. note::
+
+   For the above Timezone constants (:data:`altzone`, :data:`daylight`, :data:`timezone`,
+   and :data:`tzname`), the value is determined by the timezone rules in effect
+   at module load time or the last time :func:`tzset` is called and may be incorrect
+   for times in the past.  It is recommended to use the :attr:`tm_gmtoff` and
+   :attr:`tm_zone` results from :func:`localtime` to obtain timezone information.
+
+
 .. seealso::
 
    Module :mod:`datetime`
index 3e1faed8c7b8d5dea16f43320ef3c223898c5fe0..f51add2b41fe46bf06c8a7f63f5966a8b76ec2cd 100644 (file)
@@ -154,7 +154,7 @@ background material, while the second half can be taken to the keyboard as a
 handy reference.
 
 When trying to answer questions of the form "how do I do blah", it is often best
-to find out how to do"blah" in straight Tk, and then convert this back into the
+to find out how to do "blah" in straight Tk, and then convert this back into the
 corresponding :mod:`tkinter` call. Python programmers can often guess at the
 correct Python command by looking at the Tk documentation. This means that in
 order to use Tkinter, you will have to know a little bit about Tk. This document
index 3dad182cccdf8973e3910f3c34ec4415ed45462b..927f7f3c6c1b717ac03145a34b75822b1aa7229b 100644 (file)
@@ -1099,26 +1099,42 @@ ttk.Treeview
       If *selop* is not specified, returns selected items. Otherwise, it will
       act according to the following selection methods.
 
+      .. deprecated-removed:: 3.6 3.8
+         Using ``selection()`` for changing the selection state is deprecated.
+         Use the following selection methods instead.
 
-   .. method:: selection_set(items)
+
+   .. method:: selection_set(*items)
 
       *items* becomes the new selection.
 
+      .. versionchanged:: 3.6
+         *items* can be passed as separate arguments, not just as a single tuple.
+
 
-   .. method:: selection_add(items)
+   .. method:: selection_add(*items)
 
       Add *items* to the selection.
 
+      .. versionchanged:: 3.6
+         *items* can be passed as separate arguments, not just as a single tuple.
+
 
-   .. method:: selection_remove(items)
+   .. method:: selection_remove(*items)
 
       Remove *items* from the selection.
 
+      .. versionchanged:: 3.6
+         *items* can be passed as separate arguments, not just as a single tuple.
 
-   .. method:: selection_toggle(items)
+
+   .. method:: selection_toggle(*items)
 
       Toggle the selection state of each item in *items*.
 
+      .. versionchanged:: 3.6
+         *items* can be passed as separate arguments, not just as a single tuple.
+
 
    .. method:: set(item, column=None, value=None)
 
index 1e48fecdbf78a474fb1f3b93766f9011c69707f6..9c4777ac2fe5803c9cf1c4e13a9ea6ff35f68715 100644 (file)
@@ -111,8 +111,7 @@ More precisely, the expression ``some_value is Derived(some_value)`` is always
 true at runtime.
 
 This also means that it is not possible to create a subtype of ``Derived``
-since it is an identity function at runtime, not an actual type. Similarly, it
-is not possible to create another :func:`NewType` based on a ``Derived`` type::
+since it is an identity function at runtime, not an actual type::
 
    from typing import NewType
 
@@ -121,9 +120,16 @@ is not possible to create another :func:`NewType` based on a ``Derived`` type::
    # Fails at runtime and does not typecheck
    class AdminUserId(UserId): pass
 
-   # Also does not typecheck
+However, it is possible to create a :func:`NewType` based on a 'derived' ``NewType``::
+
+   from typing import NewType
+
+   UserId = NewType('UserId', int)
+
    ProUserId = NewType('ProUserId', UserId)
 
+and typechecking for ``ProUserId`` will work as expected.
+
 See :pep:`484` for more details.
 
 .. note::
@@ -140,6 +146,8 @@ See :pep:`484` for more details.
    ``Derived`` is expected. This is useful when you want to prevent logic
    errors with minimal runtime cost.
 
+.. versionadded:: 3.5.2
+
 Callable
 --------
 
@@ -488,6 +496,8 @@ The module defines the following classes, functions and decorators:
    ``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent
    to ``type``, which is the root of Python's metaclass hierarchy.
 
+   .. versionadded:: 3.5.2
+
 .. class:: Iterable(Generic[T_co])
 
     A generic version of :class:`collections.abc.Iterable`.
@@ -668,6 +678,8 @@ The module defines the following classes, functions and decorators:
 
    A generic version of :class:`collections.defaultdict`.
 
+   .. versionadded:: 3.5.2
+
 .. class:: Counter(collections.Counter, Dict[T, int])
 
    A generic version of :class:`collections.Counter`.
@@ -756,13 +768,15 @@ The module defines the following classes, functions and decorators:
        def add_unicode_checkmark(text: Text) -> Text:
            return text + u' \u2713'
 
+   .. versionadded:: 3.5.2
+
 .. class:: io
 
    Wrapper namespace for I/O stream types.
 
-   This defines the generic type ``IO[AnyStr]`` and aliases ``TextIO``
-   and ``BinaryIO`` for respectively ``IO[str]`` and ``IO[bytes]``.
-   These represent the types of I/O streams such as returned by
+   This defines the generic type ``IO[AnyStr]`` and subclasses ``TextIO``
+   and ``BinaryIO``, deriving from ``IO[str]`` and ``IO[bytes]``,
+   respectively. These represent the types of I/O streams such as returned by
    :func:`open`.
 
    These types are also accessible directly as ``typing.IO``,
@@ -841,6 +855,8 @@ The module defines the following classes, functions and decorators:
       UserId = NewType('UserId', int)
       first_user = UserId(1)
 
+   .. versionadded:: 3.5.2
+
 .. function:: cast(typ, val)
 
    Cast a value to a type.
@@ -891,17 +907,17 @@ The module defines the following classes, functions and decorators:
 
    See :pep:`484` for details and comparison with other typing semantics.
 
-.. decorator:: no_type_check(arg)
+.. decorator:: no_type_check
 
    Decorator to indicate that annotations are not type hints.
 
-   The argument must be a class or function; if it is a class, it
+   This works as class or function :term:`decorator`.  With a class, it
    applies recursively to all methods defined in that class (but not
    to methods defined in its superclasses or subclasses).
 
    This mutates the function(s) in place.
 
-.. decorator:: no_type_check_decorator(decorator)
+.. decorator:: no_type_check_decorator
 
    Decorator to give another decorator the :func:`no_type_check` effect.
 
@@ -1048,3 +1064,5 @@ The module defines the following classes, functions and decorators:
    "forward reference", to hide the ``expensive_mod`` reference from the
    interpreter runtime.  Type annotations for local variables are not
    evaluated, so the second annotation does not need to be enclosed in quotes.
+
+   .. versionadded:: 3.5.2
index 2099bd1e2e979c0d10b44d41db01cd43a17abeb6..e52f140029c57ab56ac683c68ab09cd60801f55f 100644 (file)
@@ -402,10 +402,14 @@ you can do it yourself::
 
    def suite():
        suite = unittest.TestSuite()
-       suite.addTest(WidgetTestCase('test_default_size'))
-       suite.addTest(WidgetTestCase('test_resize'))
+       suite.addTest(WidgetTestCase('test_default_widget_size'))
+       suite.addTest(WidgetTestCase('test_widget_resize'))
        return suite
 
+   if __name__ == '__main__':
+       runner = unittest.TextTestRunner()
+       runner.run(suite())
+
 You can place the definitions of test cases and test suites in the same modules
 as the code they are to test (such as :file:`widget.py`), but there are several
 advantages to placing the test code in a separate module, such as
index 7d31932f9656e49c3863bb8e63cec7673756d946..e3b90e673caaf0c67ac5ec93f53622268bb04fe3 100644 (file)
@@ -69,10 +69,10 @@ structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html.
    .. method:: request_rate(useragent)
 
       Returns the contents of the ``Request-rate`` parameter from
-      ``robots.txt`` in the form of a :func:`~collections.namedtuple`
-      ``(requests, seconds)``.  If there is no such parameter or it doesn't
-      apply to the *useragent* specified or the ``robots.txt`` entry for this
-      parameter has invalid syntax, return ``None``.
+      ``robots.txt`` as a :term:`named tuple` ``RequestRate(requests, seconds)``.
+      If there is no such parameter or it doesn't apply to the *useragent*
+      specified or the ``robots.txt`` entry for this parameter has invalid
+      syntax, return ``None``.
 
       .. versionadded:: 3.6
 
index 4b425a482096b1d3d704b7c4df0575ad26eecfbf..dca9362400455c87bc53fa1b9e93896971d417b2 100644 (file)
@@ -773,7 +773,6 @@ Is semantically equivalent to::
     mgr = (EXPR)
     aexit = type(mgr).__aexit__
     aenter = type(mgr).__aenter__(mgr)
-    exc = True
 
     VAR = await aenter
     try:
index d92be975aacef362336ff676a385bc8114591301..ff890a815b5bbe3481656730b4aabf702cdd4f84 100644 (file)
@@ -1692,8 +1692,8 @@ precedence and have a left-to-right chaining feature as described in the
 | ``+``, ``-``                                  | Addition and subtraction            |
 +-----------------------------------------------+-------------------------------------+
 | ``*``, ``@``, ``/``, ``//``, ``%``            | Multiplication, matrix              |
-|                                               | multiplication division,            |
-|                                               | remainder [#]_                      |
+|                                               | multiplication, division, floor     |
+|                                               | division, remainder [#]_            |
 +-----------------------------------------------+-------------------------------------+
 | ``+x``, ``-x``, ``~x``                        | Positive, negative, bitwise NOT     |
 +-----------------------------------------------+-------------------------------------+
index 8cf16cad4c9c9c94ddd8792532d6dca6ff0c8ab2..7fbf8ed9d789a4487956915ac95f17035cb18992 100644 (file)
@@ -519,8 +519,9 @@ and the loader that executes it.  Most importantly, it allows the
 import machinery to perform the boilerplate operations of loading,
 whereas without a module spec the loader had that responsibility.
 
-See :class:`~importlib.machinery.ModuleSpec` for more specifics on what
-information a module's spec may hold.
+The module's spec is exposed as the ``__spec__`` attribute on a module object.
+See :class:`~importlib.machinery.ModuleSpec` for details on the contents of
+the module spec.
 
 .. versionadded:: 3.4
 
index c2fd2b74caa7f89ac19dfda068bf3fcd3185b838..4a5abf627681556f852fac12c95706e11093c3af 100644 (file)
@@ -446,9 +446,6 @@ instance of the :class:`bytes` type instead of the :class:`str` type.  They
 may only contain ASCII characters; bytes with a numeric value of 128 or greater
 must be expressed with escapes.
 
-As of Python 3.3 it is possible again to prefix string literals with a
-``u`` prefix to simplify maintenance of dual 2.x and 3.x codebases.
-
 Both string and bytes literals may optionally be prefixed with a letter ``'r'``
 or ``'R'``; such strings are called :dfn:`raw strings` and treat backslashes as
 literal characters.  As a result, in string literals, ``'\U'`` and ``'\u'``
@@ -799,10 +796,6 @@ Some examples of floating point literals::
 
    3.14    10.    .001    1e100    3.14e-10    0e0    3.14_15_93
 
-Note that numeric literals do not include a sign; a phrase like ``-1`` is
-actually an expression composed of the unary operator ``-`` and the literal
-``1``.
-
 .. versionchanged:: 3.6
    Underscores are now allowed for grouping purposes in literals.
 
index 8786d73f68a369ce83d99a783c9bc7d0f98de2a3..8d17383853a3c4ac6e3961d147eec12137aadb38 100644 (file)
@@ -931,7 +931,7 @@ annotation.
 
 .. impl-detail::
 
-   The current implementation does not enforce some of these restriction, but
+   The current implementation does not enforce some of these restrictions, but
    programs should not abuse this freedom, as future implementations may enforce
    them or silently change the meaning of the program.
 
index bd31faca4c60589c7856b60101d8e41b5d479c40..c450f5eafffc891f4d72e86f3881a79ee77f7b62 100644 (file)
@@ -13,8 +13,6 @@
     '3.7': 'dev (3.7)',
     '3.6': '3.6',
     '3.5': '3.5',
-    '3.4': '3.4',
-    '3.3': '3.3',
     '2.7': '2.7',
   };
 
index 6cd5a32878fc464fcf5473606580ed62d92b3dee..482ffc0bde8ae7489e9455224b4bb3c0389a9d5a 100644 (file)
@@ -130,9 +130,6 @@ library/exceptions,,:err,err.object[err.start:err.end]
 library/functions,,:step,a[start:stop:step]
 library/functions,,:stop,"a[start:stop, i]"
 library/functions,,:stop,a[start:stop:step]
-library/hashlib,,:vatrogasac,>>> cookie = b'user:vatrogasac'
-library/hashlib,,:vatrogasac,"user:vatrogasac,349cf904533767ed2d755279a8df84d0"
-library/hashlib,,:policajac,">>> compare_digest(b'user:policajac', sig)"
 library/hashlib,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH,"
 library/http.client,,:port,host:port
 library/http.cookies,,`,!#$%&'*+-.^_`|~:
index 413c0a7699cbe83563121f3592d079c3e5a35d25..c73c406426a26240f5ce6a381097bf19a26cec13 100644 (file)
@@ -2,9 +2,9 @@
 <p><a href="{{ pathto('download') }}">{% trans %}Download these documents{% endtrans %}</a></p>
 <h3>{% trans %}Docs for other versions{% endtrans %}</h3>
 <ul>
-  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (stable){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.5/">{% trans %}Python 3.5 (stable){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (in development){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/3.5/">{% trans %}Python 3.5 (stable){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (stable){% endtrans %}</a></li>
   <li><a href="https://www.python.org/doc/versions/">{% trans %}Old versions{% endtrans %}</a></li>
 </ul>
 
index 8956aa5a2613503ed2dab3a6a5124df2436b9416..6415ae66ab877477574719c667d25fb815adcb53 100644 (file)
@@ -212,6 +212,13 @@ to each other are automatically concatenated. ::
    >>> 'Py' 'thon'
    'Python'
 
+This feature is particularly useful when you want to break long strings::
+
+   >>> text = ('Put several strings within parentheses '
+   ...         'to have them joined together.')
+   >>> text
+   'Put several strings within parentheses to have them joined together.'
+
 This only works with two literals though, not with variables or expressions::
 
    >>> prefix = 'Py'
@@ -227,13 +234,6 @@ If you want to concatenate variables or a variable and a literal, use ``+``::
    >>> prefix + 'thon'
    'Python'
 
-This feature is particularly useful when you want to break long strings::
-
-   >>> text = ('Put several strings within parentheses '
-   ...         'to have them joined together.')
-   >>> text
-   'Put several strings within parentheses to have them joined together.'
-
 Strings can be *indexed* (subscripted), with the first character having index 0.
 There is no separate character type; a character is simply a string of size
 one::
index 40a06b9adc06ef165badce57912e1b27261eac33..9ffb714963169a6414d2765636de5cf3ffbb3f17 100644 (file)
@@ -387,8 +387,6 @@ Miscellaneous options
    Skip the first line of the source, allowing use of non-Unix forms of
    ``#!cmd``.  This is intended for a DOS specific hack only.
 
-   .. note:: The line numbers in error messages will be off by one.
-
 
 .. cmdoption:: -X
 
index 53f431b5cfda6c661efab334ba87848c24eb0ff5..4292592ba7a25b82ef6182b35b52d6f750323324 100644 (file)
@@ -33,7 +33,7 @@ On Windows, invoke the ``venv`` command as follows::
 Alternatively, if you configured the ``PATH`` and ``PATHEXT`` variables for
 your :ref:`Python installation <using-on-windows>`::
 
-    c:\>python -m venv myenv c:\path\to\myenv
+    c:\>python -m venv c:\path\to\myenv
 
 The command, if run with ``-h``, will show the available options::
 
index 1301f4ca1d8c54836abe6fd5222b0774bbbf807d..847b50140a6671cb591d57654f54c464ec93aadc 100644 (file)
@@ -1852,6 +1852,11 @@ Build and C API Changes
 * The :c:func:`PyUnicode_FSConverter` and :c:func:`PyUnicode_FSDecoder`
   functions will now accept :term:`path-like objects <path-like object>`.
 
+* The ``PyExc_RecursionErrorInst`` singleton that was part of the public API
+  has been removed as its members being never cleared may cause a segfault
+  during finalization of the interpreter. Contributed by Xavier de Gaye in
+  :issue:`22898` and :issue:`30697`.
+
 
 Other Improvements
 ==================
index f06b6549e74be1640e26bb13a0db816b4fca8d01..e909bb240b8ebff6bcc5117c0accdfd1d7364f5d 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION       3
 #define PY_MINOR_VERSION       6
-#define PY_MICRO_VERSION       3
+#define PY_MICRO_VERSION       4
 #define PY_RELEASE_LEVEL       PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL      0
 
 /* Version as a string */
-#define PY_VERSION             "3.6.3"
+#define PY_VERSION             "3.6.4"
 /*--end constants--*/
 
 /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
index 3c21697073a4a6be6efb3c0e0e57fdc0dfd11f86..b09dde48083dec3c96fc4f2986b39e8c954eba1f 100644 (file)
@@ -7,14 +7,9 @@
 ** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards
 ** against multiple definition of wchar_t.
 */
-#ifdef _BSD_WCHAR_T_DEFINED_
+#ifdef _BSD_WCHAR_T_DEFINED_
 #define _WCHAR_T
 #endif
-
-/* the following define is necessary for OS X 10.6; without it, the
-   Apple-supplied ncurses.h sets NCURSES_OPAQUE to 1, and then Python
-   can't get at the WINDOW flags field. */
-#define NCURSES_OPAQUE 0
 #endif /* __APPLE__ */
 
 #ifdef __FreeBSD__
@@ -22,7 +17,7 @@
 ** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards
 ** against multiple definition of wchar_t and wint_t.
 */
-#ifdef _XOPEN_SOURCE_EXTENDED
+#ifdef _XOPEN_SOURCE_EXTENDED
 #ifndef __FreeBSD_version
 #include <osreldate.h>
 #endif
 #endif
 #endif
 
+#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
+/* The following definition is necessary for ncurses 5.7; without it,
+   some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python
+   can't get at the WINDOW flags field. */
+#define NCURSES_OPAQUE 0
+#endif
+
 #ifdef HAVE_NCURSES_H
 #include <ncurses.h>
 #else
 #include <curses.h>
-#ifdef HAVE_TERM_H
-/* for tigetstr, which is not declared in SysV curses */
-#include <term.h>
-#endif
 #endif
 
 #ifdef HAVE_NCURSES_H
 /* configure was checking <curses.h>, but we will
-   use <ncurses.h>, which has all these features. */
-#ifndef WINDOW_HAS_FLAGS
+   use <ncurses.h>, which has some or all these features. */
+#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0)
 #define WINDOW_HAS_FLAGS 1
 #endif
+#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906
+#define HAVE_CURSES_IS_PAD 1
+#endif
 #ifndef MVWDELCH_IS_EXPRESSION
 #define MVWDELCH_IS_EXPRESSION 1
 #endif
@@ -74,12 +75,12 @@ extern "C" {
 /* Type declarations */
 
 typedef struct {
-       PyObject_HEAD
-       WINDOW *win;
-       char *encoding;
+    PyObject_HEAD
+    WINDOW *win;
+    char *encoding;
 } PyCursesWindowObject;
 
-#define PyCursesWindow_Check(v)         (Py_TYPE(v) == &PyCursesWindow_Type)
+#define PyCursesWindow_Check(v)  (Py_TYPE(v) == &PyCursesWindow_Type)
 
 #define PyCurses_CAPSULE_NAME "_curses._C_API"
 
index 8c1dbc5047b5f2535a163a50b38d3adfae846917..c28c1373f82f2b75a1ac6a025d2fc11eb4473a60 100644 (file)
@@ -219,8 +219,6 @@ PyAPI_DATA(PyObject *) PyExc_IOError;
 PyAPI_DATA(PyObject *) PyExc_WindowsError;
 #endif
 
-PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst;
-
 /* Predefined warning categories */
 PyAPI_DATA(PyObject *) PyExc_Warning;
 PyAPI_DATA(PyObject *) PyExc_UserWarning;
index a814af6786738ab3cebf81a2e5343856772c708b..9cfd071ea17ba8d80360dea4a7f5c7fd25e44b74 100644 (file)
@@ -16,7 +16,7 @@ PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
 #define _PyHASH_MULTIPLIER 1000003UL  /* 0xf4243 */
 
 /* Parameters used for the numeric hash implementation.  See notes for
-   _Py_HashDouble in Objects/object.c.  Numeric hashes are based on
+   _Py_HashDouble in Python/pyhash.c.  Numeric hashes are based on
    reduction modulo the prime 2**_PyHASH_BITS - 1. */
 
 #if SIZEOF_VOID_P >= 8
index 87ac7fcbbad5141376eb4b50f10dd2dbb1124491..158c460aee6aa9dbdae69c4eafa606c111dcd307 100644 (file)
@@ -29,9 +29,20 @@ typedef enum {
     _PyTime_ROUND_CEILING=1,
     /* Round to nearest with ties going to nearest even integer.
        For example, used to round from a Python float. */
-    _PyTime_ROUND_HALF_EVEN
+    _PyTime_ROUND_HALF_EVEN=2,
+    /* Round away from zero
+       For example, used for timeout. _PyTime_ROUND_CEILING rounds
+       -1e-9 to 0 milliseconds which causes bpo-31786 issue.
+       _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
+       the timeout sign as expected. select.poll(timeout) must block
+       for negative values." */
+    _PyTime_ROUND_UP=3,
+    /* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
+       used for timeouts. */
+    _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
 } _PyTime_round_t;
 
+
 /* Convert a time_t to a PyLong. */
 PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
     time_t sec);
index a4967b854c5e68d9d689d0a446ba091aee0e2ba6..8cc655c79f8b5868cba55c9aab1c48bc348b3475 100644 (file)
@@ -1222,6 +1222,11 @@ class BaseEventLoop(events.AbstractEventLoop):
         handler is set, and can be called by a custom exception
         handler that wants to defer to the default behavior.
 
+        This default handler logs the error message and other
+        context-dependent information.  In debug mode, a truncated
+        stack trace is also appended showing where the given object
+        (e.g. a handle or future or task) was created, if any.
+
         The context parameter has the same meaning as in
         `call_exception_handler()`.
         """
index f9e123281e2e3b204dbae6f09f6b22fe06ed06e5..e74209e149d7ce17901470820345db314630c2c2 100644 (file)
@@ -5,3 +5,8 @@ LOG_THRESHOLD_FOR_CONNLOST_WRITES = 5
 
 # Seconds to wait before retrying accept().
 ACCEPT_RETRY_DELAY = 1
+
+# Number of stack entries to capture in debug mode.
+# The large the number, the slower the operation in debug mode
+# (see extract_stack() in events.py)
+DEBUG_STACK_DEPTH = 10
index b2adaadfc2cd6d120eec1748068a9f1b048485f7..520a309f846049e9b9bb719037e0a54f34798ace 100644 (file)
@@ -10,6 +10,7 @@ import traceback
 import types
 
 from . import compat
+from . import constants
 from . import events
 from . import base_futures
 from .log import logger
@@ -91,7 +92,7 @@ class CoroWrapper:
         assert inspect.isgenerator(gen) or inspect.iscoroutine(gen), gen
         self.gen = gen
         self.func = func  # Used to unwrap @coroutine decorator
-        self._source_traceback = traceback.extract_stack(sys._getframe(1))
+        self._source_traceback = events.extract_stack(sys._getframe(1))
         self.__name__ = getattr(gen, '__name__', None)
         self.__qualname__ = getattr(gen, '__qualname__', None)
 
@@ -183,8 +184,9 @@ class CoroWrapper:
             tb = getattr(self, '_source_traceback', ())
             if tb:
                 tb = ''.join(traceback.format_list(tb))
-                msg += ('\nCoroutine object created at '
-                        '(most recent call last):\n')
+                msg += (f'\nCoroutine object created at '
+                        f'(most recent call last, truncated to '
+                        f'{constants.DEBUG_STACK_DEPTH} last lines):\n')
                 msg += tb.rstrip()
             logger.error(msg)
 
index d41f3f5b7559d26be739dee29d33fe4b7302e6f9..05dc8969f44a6a9b526117f82b1a42458f78e8c2 100644 (file)
@@ -19,7 +19,8 @@ import sys
 import threading
 import traceback
 
-from asyncio import compat
+from . import compat
+from . import constants
 
 
 def _get_function_source(func):
@@ -77,6 +78,23 @@ def _format_callback_source(func, args):
     return func_repr
 
 
+def extract_stack(f=None, limit=None):
+    """Replacement for traceback.extract_stack() that only does the
+    necessary work for asyncio debug mode.
+    """
+    if f is None:
+        f = sys._getframe().f_back
+    if limit is None:
+        # Limit the amount of work to a reasonable amount, as extract_stack()
+        # can be called for each coroutine and future in debug mode.
+        limit = constants.DEBUG_STACK_DEPTH
+    stack = traceback.StackSummary.extract(traceback.walk_stack(f),
+                                           limit=limit,
+                                           lookup_lines=False)
+    stack.reverse()
+    return stack
+
+
 class Handle:
     """Object returned by callback registration methods."""
 
@@ -90,7 +108,7 @@ class Handle:
         self._cancelled = False
         self._repr = None
         if self._loop.get_debug():
-            self._source_traceback = traceback.extract_stack(sys._getframe(1))
+            self._source_traceback = extract_stack(sys._getframe(1))
         else:
             self._source_traceback = None
 
index cff9590e4ead5f3f5dd755891b8a979faf0034a6..9ff143039a3280d7784c25497e97115428ef5789 100644 (file)
@@ -112,11 +112,13 @@ class Future:
 
     Differences:
 
+    - This class is not thread-safe.
+
     - result() and exception() do not take a timeout argument and
       raise an exception when the future isn't done yet.
 
     - Callbacks registered with add_done_callback() are always called
-      via the event loop's call_soon_threadsafe().
+      via the event loop's call_soon().
 
     - This class is not compatible with the wait() and as_completed()
       methods in the concurrent.futures package.
@@ -141,8 +143,7 @@ class Future:
     #   `yield Future()` (incorrect).
     _asyncio_future_blocking = False
 
-    _log_traceback = False   # Used for Python 3.4 and later
-    _tb_logger = None        # Used for Python 3.3 only
+    _log_traceback = False
 
     def __init__(self, *, loop=None):
         """Initialize the future.
@@ -157,7 +158,7 @@ class Future:
             self._loop = loop
         self._callbacks = []
         if self._loop.get_debug():
-            self._source_traceback = traceback.extract_stack(sys._getframe(1))
+            self._source_traceback = events.extract_stack(sys._getframe(1))
 
     _repr_info = base_futures._future_repr_info
 
@@ -238,9 +239,6 @@ class Future:
         if self._state != _FINISHED:
             raise InvalidStateError('Result is not ready.')
         self._log_traceback = False
-        if self._tb_logger is not None:
-            self._tb_logger.clear()
-            self._tb_logger = None
         if self._exception is not None:
             raise self._exception
         return self._result
@@ -258,9 +256,6 @@ class Future:
         if self._state != _FINISHED:
             raise InvalidStateError('Exception is not set.')
         self._log_traceback = False
-        if self._tb_logger is not None:
-            self._tb_logger.clear()
-            self._tb_logger = None
         return self._exception
 
     def add_done_callback(self, fn):
index 2d38972c0de29d70f88c651ae3cf7e29f2f3249e..1c66d67b041304fc7f569acab652b0b8587bd19c 100644 (file)
@@ -167,6 +167,12 @@ class Queue:
                 yield from getter
             except:
                 getter.cancel()  # Just in case getter is not done yet.
+
+                try:
+                    self._getters.remove(getter)
+                except ValueError:
+                    pass
+
                 if not self.empty() and not getter.cancelled():
                     # We were woken up by put_nowait(), but can't take
                     # the call.  Wake up the next in line.
index 9dbe550b01774ad9960ebd263893b4a9f65a864e..942b627a1c1db648d41d21ffb129e65d23f029b7 100644 (file)
@@ -363,25 +363,25 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         if self._debug and sock.gettimeout() != 0:
             raise ValueError("the socket must be non-blocking")
         fut = self.create_future()
-        self._sock_recv(fut, False, sock, n)
+        self._sock_recv(fut, None, sock, n)
         return fut
 
-    def _sock_recv(self, fut, registered, sock, n):
+    def _sock_recv(self, fut, registered_fd, sock, n):
         # _sock_recv() can add itself as an I/O callback if the operation can't
         # be done immediately. Don't use it directly, call sock_recv().
-        fd = sock.fileno()
-        if registered:
+        if registered_fd is not None:
             # Remove the callback early.  It should be rare that the
             # selector says the fd is ready but the call still returns
             # EAGAIN, and I am willing to take a hit in that case in
             # order to simplify the common case.
-            self.remove_reader(fd)
+            self.remove_reader(registered_fd)
         if fut.cancelled():
             return
         try:
             data = sock.recv(n)
         except (BlockingIOError, InterruptedError):
-            self.add_reader(fd, self._sock_recv, fut, True, sock, n)
+            fd = sock.fileno()
+            self.add_reader(fd, self._sock_recv, fut, fd, sock, n)
         except Exception as exc:
             fut.set_exception(exc)
         else:
@@ -402,16 +402,14 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
             raise ValueError("the socket must be non-blocking")
         fut = self.create_future()
         if data:
-            self._sock_sendall(fut, False, sock, data)
+            self._sock_sendall(fut, None, sock, data)
         else:
             fut.set_result(None)
         return fut
 
-    def _sock_sendall(self, fut, registered, sock, data):
-        fd = sock.fileno()
-
-        if registered:
-            self.remove_writer(fd)
+    def _sock_sendall(self, fut, registered_fd, sock, data):
+        if registered_fd is not None:
+            self.remove_writer(registered_fd)
         if fut.cancelled():
             return
 
@@ -428,7 +426,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
         else:
             if n:
                 data = data[n:]
-            self.add_writer(fd, self._sock_sendall, fut, True, sock, data)
+            fd = sock.fileno()
+            self.add_writer(fd, self._sock_sendall, fut, fd, sock, data)
 
     @coroutine
     def sock_connect(self, sock, address):
index 7948c4c3b4efe69fbd1db2e3c76ecc667093d073..f4d8a48418236cf65cbb7ed88f04ab7a9ed4146b 100644 (file)
@@ -294,11 +294,10 @@ class _SSLPipe(object):
 class _SSLProtocolTransport(transports._FlowControlMixin,
                             transports.Transport):
 
-    def __init__(self, loop, ssl_protocol, app_protocol):
+    def __init__(self, loop, ssl_protocol):
         self._loop = loop
         # SSLProtocol instance
         self._ssl_protocol = ssl_protocol
-        self._app_protocol = app_protocol
         self._closed = False
 
     def get_extra_info(self, name, default=None):
@@ -306,10 +305,10 @@ class _SSLProtocolTransport(transports._FlowControlMixin,
         return self._ssl_protocol._get_extra_info(name, default)
 
     def set_protocol(self, protocol):
-        self._app_protocol = protocol
+        self._ssl_protocol._app_protocol = protocol
 
     def get_protocol(self):
-        return self._app_protocol
+        return self._ssl_protocol._app_protocol
 
     def is_closing(self):
         return self._closed
@@ -436,8 +435,7 @@ class SSLProtocol(protocols.Protocol):
         self._waiter = waiter
         self._loop = loop
         self._app_protocol = app_protocol
-        self._app_transport = _SSLProtocolTransport(self._loop,
-                                                    self, self._app_protocol)
+        self._app_transport = _SSLProtocolTransport(self._loop, self)
         # _SSLPipe instance (None until the connection is made)
         self._sslpipe = None
         self._session_established = False
index a82cc79acaa3fb371a01d8367456be75cc997086..4089b0e00afaf8fa62157dfacb9b15f17f337da7 100644 (file)
@@ -35,6 +35,9 @@ class IncompleteReadError(EOFError):
         self.partial = partial
         self.expected = expected
 
+    def __reduce__(self):
+        return type(self), (self.partial, self.expected)
+
 
 class LimitOverrunError(Exception):
     """Reached the buffer limit while looking for a separator.
@@ -46,6 +49,9 @@ class LimitOverrunError(Exception):
         super().__init__(message)
         self.consumed = consumed
 
+    def __reduce__(self):
+        return type(self), (self.args[0], self.consumed)
+
 
 @coroutine
 def open_connection(host=None, port=None, *,
index 39ec8454acd93940b58af428c1ee500be8fe6feb..fd6c6f59d42bbfcd2c439f215def7ac023061478 100644 (file)
@@ -479,15 +479,17 @@ class StreamReader(Codec):
             self.charbuffer = self._empty_charbuffer.join(self.linebuffer)
             self.linebuffer = None
 
+        if chars < 0:
+            # For compatibility with other read() methods that take a
+            # single argument
+            chars = size
+
         # read until we get the required number of characters (if available)
         while True:
             # can the request be satisfied from the character buffer?
             if chars >= 0:
                 if len(self.charbuffer) >= chars:
                     break
-            elif size >= 0:
-                if len(self.charbuffer) >= size:
-                    break
             # we need more data
             if size < 0:
                 newdata = self.stream.read()
index d892b59898589fc8981c8cba7fc34e31683770ca..d378392ebe28443d36fe6eae9aafad7927b8cc46 100644 (file)
@@ -1,4 +1,5 @@
 import unittest
+import test.support
 from ctypes import *
 
 class AnonTest(unittest.TestCase):
@@ -35,6 +36,18 @@ class AnonTest(unittest.TestCase):
                                                       {"_fields_": [],
                                                        "_anonymous_": ["x"]}))
 
+    @test.support.cpython_only
+    def test_issue31490(self):
+        # There shouldn't be an assertion failure in case the class has an
+        # attribute whose name is specified in _anonymous_ but not in _fields_.
+
+        # AttributeError: 'x' is specified in _anonymous_ but not in _fields_
+        with self.assertRaises(AttributeError):
+            class Name(Structure):
+                _fields_ = []
+                _anonymous_ = ["x"]
+                x = 42
+
     def test_nested(self):
         class ANON_S(Structure):
             _fields_ = [("a", c_int)]
index 7ab38f1b031f1f5851b9d731d15cc56fe70b93bc..55c244356b30d0e2913c31e8f0159ab810a32191 100644 (file)
@@ -121,12 +121,21 @@ class Test(unittest.TestCase):
             (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int))
 
     def test_abstract(self):
+        from ctypes import _Pointer, _SimpleCData, _CFuncPtr
+
         self.assertRaises(TypeError, Array.from_buffer, bytearray(10))
         self.assertRaises(TypeError, Structure.from_buffer, bytearray(10))
         self.assertRaises(TypeError, Union.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _CFuncPtr.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _Pointer.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _SimpleCData.from_buffer, bytearray(10))
+
         self.assertRaises(TypeError, Array.from_buffer_copy, b"123")
         self.assertRaises(TypeError, Structure.from_buffer_copy, b"123")
         self.assertRaises(TypeError, Union.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _CFuncPtr.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _Pointer.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _SimpleCData.from_buffer_copy, b"123")
 
 if __name__ == '__main__':
     unittest.main()
index f34734b164ebad45c4e02aec67e61e9096cfc0f8..e0b9b54e97f67346f111dd32f48c8adc8aca290d 100644 (file)
@@ -123,5 +123,10 @@ class CFuncPtrTestCase(unittest.TestCase):
         self.assertEqual(strtok(None, b"\n"), b"c")
         self.assertEqual(strtok(None, b"\n"), None)
 
+    def test_abstract(self):
+        from ctypes import _CFuncPtr
+
+        self.assertRaises(TypeError, _CFuncPtr, 13, "name", 42, "iid")
+
 if __name__ == '__main__':
     unittest.main()
index 363f58612dbdf93d88cf7a9359bf68416a24f13c..e4c25fd880cefbbe1b62b65382a7ca1f4f588c54 100644 (file)
@@ -1,5 +1,6 @@
 import unittest
 from ctypes.test import need_symbol
+import test.support
 
 class SimpleTypesTestCase(unittest.TestCase):
 
@@ -169,6 +170,36 @@ class SimpleTypesTestCase(unittest.TestCase):
         # ArgumentError: argument 1: ValueError: 99
         self.assertRaises(ArgumentError, func, 99)
 
+    def test_abstract(self):
+        from ctypes import (Array, Structure, Union, _Pointer,
+                            _SimpleCData, _CFuncPtr)
+
+        self.assertRaises(TypeError, Array.from_param, 42)
+        self.assertRaises(TypeError, Structure.from_param, 42)
+        self.assertRaises(TypeError, Union.from_param, 42)
+        self.assertRaises(TypeError, _CFuncPtr.from_param, 42)
+        self.assertRaises(TypeError, _Pointer.from_param, 42)
+        self.assertRaises(TypeError, _SimpleCData.from_param, 42)
+
+    @test.support.cpython_only
+    def test_issue31311(self):
+        # __setstate__ should neither raise a SystemError nor crash in case
+        # of a bad __dict__.
+        from ctypes import Structure
+
+        class BadStruct(Structure):
+            @property
+            def __dict__(self):
+                pass
+        with self.assertRaises(TypeError):
+            BadStruct().__setstate__({}, b'foo')
+
+        class WorseStruct(Structure):
+            @property
+            def __dict__(self):
+                1/0
+        with self.assertRaises(ZeroDivisionError):
+            WorseStruct().__setstate__({}, b'foo')
 
 ################################################################
 
index 751f85fd11f59a36af6ae728648770d0d1579450..e97515879f1f0e09f529e84d91e6e9bfaeed7182 100644 (file)
@@ -213,6 +213,11 @@ class PointersTestCase(unittest.TestCase):
         from ctypes import _pointer_type_cache
         del _pointer_type_cache[id(P)]
 
+    def test_abstract(self):
+        from ctypes import _Pointer
+
+        self.assertRaises(TypeError, _Pointer.set_type, 42)
+
 
 if __name__ == '__main__':
     unittest.main()
index 22eb3b0cd7b8b9171ee20b3fc79bc59a930cfb20..8045cc82679cc1e10c2a4a0723f6da64ea9abd7d 100644 (file)
@@ -46,5 +46,29 @@ class StructFieldsTestCase(unittest.TestCase):
         Y._fields_ = []
         self.assertRaises(AttributeError, setattr, X, "_fields_", [])
 
+    # __set__ and __get__ should raise a TypeError in case their self
+    # argument is not a ctype instance.
+    def test___set__(self):
+        class MyCStruct(Structure):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCStruct.field.__set__, 'wrong type self', 42)
+
+        class MyCUnion(Union):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCUnion.field.__set__, 'wrong type self', 42)
+
+    def test___get__(self):
+        class MyCStruct(Structure):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCStruct.field.__get__, 'wrong type self', 42)
+
+        class MyCUnion(Union):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCUnion.field.__get__, 'wrong type self', 42)
+
 if __name__ == "__main__":
     unittest.main()
index b95536fb7afc02b2b4f9691c2d2bec4363ced121..150664ea3b6570f04bc4df145ffca896f20373e1 100644 (file)
@@ -827,7 +827,7 @@ class date:
             month = self._month
         if day is None:
             day = self._day
-        return date(year, month, day)
+        return type(self)(year, month, day)
 
     # Comparisons of date objects with other.
 
@@ -1315,7 +1315,7 @@ class time:
             tzinfo = self.tzinfo
         if fold is None:
             fold = self._fold
-        return time(hour, minute, second, microsecond, tzinfo, fold=fold)
+        return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold)
 
     # Pickle support.
 
@@ -1596,7 +1596,7 @@ class datetime(date):
             tzinfo = self.tzinfo
         if fold is None:
             fold = self.fold
-        return datetime(year, month, day, hour, minute, second,
+        return type(self)(year, month, day, hour, minute, second,
                           microsecond, tzinfo, fold=fold)
 
     def _local_timezone(self):
index 9b9697f77346a60ab37321f46c4b58845135bd1a..3ebbbe5383abaa084e23ad2e5ef1e0a08eb9b494 100644 (file)
@@ -96,90 +96,6 @@ EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%')
 def quote_string(value):
     return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"'
 
-#
-# Accumulator for header folding
-#
-
-class _Folded:
-
-    def __init__(self, maxlen, policy):
-        self.maxlen = maxlen
-        self.policy = policy
-        self.lastlen = 0
-        self.stickyspace = None
-        self.firstline = True
-        self.done = []
-        self.current = []
-
-    def newline(self):
-        self.done.extend(self.current)
-        self.done.append(self.policy.linesep)
-        self.current.clear()
-        self.lastlen = 0
-
-    def finalize(self):
-        if self.current:
-            self.newline()
-
-    def __str__(self):
-        return ''.join(self.done)
-
-    def append(self, stoken):
-        self.current.append(stoken)
-
-    def append_if_fits(self, token, stoken=None):
-        if stoken is None:
-            stoken = str(token)
-        l = len(stoken)
-        if self.stickyspace is not None:
-            stickyspace_len = len(self.stickyspace)
-            if self.lastlen + stickyspace_len + l <= self.maxlen:
-                self.current.append(self.stickyspace)
-                self.lastlen += stickyspace_len
-                self.current.append(stoken)
-                self.lastlen += l
-                self.stickyspace = None
-                self.firstline = False
-                return True
-            if token.has_fws:
-                ws = token.pop_leading_fws()
-                if ws is not None:
-                    self.stickyspace += str(ws)
-                    stickyspace_len += len(ws)
-                token._fold(self)
-                return True
-            if stickyspace_len and l + 1 <= self.maxlen:
-                margin = self.maxlen - l
-                if 0 < margin < stickyspace_len:
-                    trim = stickyspace_len - margin
-                    self.current.append(self.stickyspace[:trim])
-                    self.stickyspace = self.stickyspace[trim:]
-                    stickyspace_len = trim
-                self.newline()
-                self.current.append(self.stickyspace)
-                self.current.append(stoken)
-                self.lastlen = l + stickyspace_len
-                self.stickyspace = None
-                self.firstline = False
-                return True
-            if not self.firstline:
-                self.newline()
-            self.current.append(self.stickyspace)
-            self.current.append(stoken)
-            self.stickyspace = None
-            self.firstline = False
-            return True
-        if self.lastlen + l <= self.maxlen:
-            self.current.append(stoken)
-            self.lastlen += l
-            return True
-        if l < self.maxlen:
-            self.newline()
-            self.current.append(stoken)
-            self.lastlen = l
-            return True
-        return False
-
 #
 # TokenList and its subclasses
 #
@@ -187,6 +103,8 @@ class _Folded:
 class TokenList(list):
 
     token_type = None
+    syntactic_break = True
+    ew_combine_allowed = True
 
     def __init__(self, *args, **kw):
         super().__init__(*args, **kw)
@@ -207,84 +125,13 @@ class TokenList(list):
     def all_defects(self):
         return sum((x.all_defects for x in self), self.defects)
 
-    #
-    # Folding API
-    #
-    # parts():
-    #
-    # return a list of objects that constitute the "higher level syntactic
-    # objects" specified by the RFC as the best places to fold a header line.
-    # The returned objects must include leading folding white space, even if
-    # this means mutating the underlying parse tree of the object.  Each object
-    # is only responsible for returning *its* parts, and should not drill down
-    # to any lower level except as required to meet the leading folding white
-    # space constraint.
-    #
-    # _fold(folded):
-    #
-    #   folded: the result accumulator.  This is an instance of _Folded.
-    #       (XXX: I haven't finished factoring this out yet, the folding code
-    #       pretty much uses this as a state object.) When the folded.current
-    #       contains as much text as will fit, the _fold method should call
-    #       folded.newline.
-    #  folded.lastlen: the current length of the test stored in folded.current.
-    #  folded.maxlen: The maximum number of characters that may appear on a
-    #       folded line.  Differs from the policy setting in that "no limit" is
-    #       represented by +inf, which means it can be used in the trivially
-    #       logical fashion in comparisons.
-    #
-    # Currently no subclasses implement parts, and I think this will remain
-    # true.  A subclass only needs to implement _fold when the generic version
-    # isn't sufficient.  _fold will need to be implemented primarily when it is
-    # possible for encoded words to appear in the specialized token-list, since
-    # there is no generic algorithm that can know where exactly the encoded
-    # words are allowed.  A _fold implementation is responsible for filling
-    # lines in the same general way that the top level _fold does. It may, and
-    # should, call the _fold method of sub-objects in a similar fashion to that
-    # of the top level _fold.
-    #
-    # XXX: I'm hoping it will be possible to factor the existing code further
-    # to reduce redundancy and make the logic clearer.
-
-    @property
-    def parts(self):
-        klass = self.__class__
-        this = []
-        for token in self:
-            if token.startswith_fws():
-                if this:
-                    yield this[0] if len(this)==1 else klass(this)
-                    this.clear()
-            end_ws = token.pop_trailing_ws()
-            this.append(token)
-            if end_ws:
-                yield klass(this)
-                this = [end_ws]
-        if this:
-            yield this[0] if len(this)==1 else klass(this)
-
     def startswith_fws(self):
         return self[0].startswith_fws()
 
-    def pop_leading_fws(self):
-        if self[0].token_type == 'fws':
-            return self.pop(0)
-        return self[0].pop_leading_fws()
-
-    def pop_trailing_ws(self):
-        if self[-1].token_type == 'cfws':
-            return self.pop(-1)
-        return self[-1].pop_trailing_ws()
-
     @property
-    def has_fws(self):
-        for part in self:
-            if part.has_fws:
-                return True
-        return False
-
-    def has_leading_comment(self):
-        return self[0].has_leading_comment()
+    def as_ew_allowed(self):
+        """True if all top level tokens of this part may be RFC2047 encoded."""
+        return all(part.as_ew_allowed for part in self)
 
     @property
     def comments(self):
@@ -294,69 +141,13 @@ class TokenList(list):
         return comments
 
     def fold(self, *, policy):
-        # max_line_length 0/None means no limit, ie: infinitely long.
-        maxlen = policy.max_line_length or float("+inf")
-        folded = _Folded(maxlen, policy)
-        self._fold(folded)
-        folded.finalize()
-        return str(folded)
-
-    def as_encoded_word(self, charset):
-        # This works only for things returned by 'parts', which include
-        # the leading fws, if any, that should be used.
-        res = []
-        ws = self.pop_leading_fws()
-        if ws:
-            res.append(ws)
-        trailer = self.pop(-1) if self[-1].token_type=='fws' else ''
-        res.append(_ew.encode(str(self), charset))
-        res.append(trailer)
-        return ''.join(res)
-
-    def cte_encode(self, charset, policy):
-        res = []
-        for part in self:
-            res.append(part.cte_encode(charset, policy))
-        return ''.join(res)
-
-    def _fold(self, folded):
-        encoding = 'utf-8' if folded.policy.utf8 else 'ascii'
-        for part in self.parts:
-            tstr = str(part)
-            tlen = len(tstr)
-            try:
-                str(part).encode(encoding)
-            except UnicodeEncodeError:
-                if any(isinstance(x, errors.UndecodableBytesDefect)
-                        for x in part.all_defects):
-                    charset = 'unknown-8bit'
-                else:
-                    # XXX: this should be a policy setting when utf8 is False.
-                    charset = 'utf-8'
-                tstr = part.cte_encode(charset, folded.policy)
-                tlen = len(tstr)
-            if folded.append_if_fits(part, tstr):
-                continue
-            # Peel off the leading whitespace if any and make it sticky, to
-            # avoid infinite recursion.
-            ws = part.pop_leading_fws()
-            if ws is not None:
-                folded.stickyspace = str(ws)
-                if folded.append_if_fits(part):
-                    continue
-            if part.has_fws:
-                part._fold(folded)
-                continue
-            # There are no fold points in this one; it is too long for a single
-            # line and can't be split...we just have to put it on its own line.
-            folded.append(tstr)
-            folded.newline()
+        return _refold_parse_tree(self, policy=policy)
 
     def pprint(self, indent=''):
-        print('\n'.join(self._pp(indent='')))
+        print(self.ppstr(indent=indent))
 
     def ppstr(self, indent=''):
-        return '\n'.join(self._pp(indent=''))
+        return '\n'.join(self._pp(indent=indent))
 
     def _pp(self, indent=''):
         yield '{}{}/{}('.format(
@@ -391,173 +182,11 @@ class UnstructuredTokenList(TokenList):
 
     token_type = 'unstructured'
 
-    def _fold(self, folded):
-        last_ew = None
-        encoding = 'utf-8' if folded.policy.utf8 else 'ascii'
-        for part in self.parts:
-            tstr = str(part)
-            is_ew = False
-            try:
-                str(part).encode(encoding)
-            except UnicodeEncodeError:
-                if any(isinstance(x, errors.UndecodableBytesDefect)
-                       for x in part.all_defects):
-                    charset = 'unknown-8bit'
-                else:
-                    charset = 'utf-8'
-                if last_ew is not None:
-                    # We've already done an EW, combine this one with it
-                    # if there's room.
-                    chunk = get_unstructured(
-                        ''.join(folded.current[last_ew:]+[tstr])).as_encoded_word(charset)
-                    oldlastlen = sum(len(x) for x in folded.current[:last_ew])
-                    schunk = str(chunk)
-                    lchunk = len(schunk)
-                    if oldlastlen + lchunk <= folded.maxlen:
-                        del folded.current[last_ew:]
-                        folded.append(schunk)
-                        folded.lastlen = oldlastlen + lchunk
-                        continue
-                tstr = part.as_encoded_word(charset)
-                is_ew = True
-            if folded.append_if_fits(part, tstr):
-                if is_ew:
-                    last_ew = len(folded.current) - 1
-                continue
-            if is_ew or last_ew:
-                # It's too big to fit on the line, but since we've
-                # got encoded words we can use encoded word folding.
-                part._fold_as_ew(folded)
-                continue
-            # Peel off the leading whitespace if any and make it sticky, to
-            # avoid infinite recursion.
-            ws = part.pop_leading_fws()
-            if ws is not None:
-                folded.stickyspace = str(ws)
-                if folded.append_if_fits(part):
-                    continue
-            if part.has_fws:
-                part._fold(folded)
-                continue
-            # It can't be split...we just have to put it on its own line.
-            folded.append(tstr)
-            folded.newline()
-            last_ew = None
-
-    def cte_encode(self, charset, policy):
-        res = []
-        last_ew = None
-        for part in self:
-            spart = str(part)
-            try:
-                spart.encode('us-ascii')
-                res.append(spart)
-            except UnicodeEncodeError:
-                if last_ew is None:
-                    res.append(part.cte_encode(charset, policy))
-                    last_ew = len(res)
-                else:
-                    tl = get_unstructured(''.join(res[last_ew:] + [spart]))
-                    res.append(tl.as_encoded_word(charset))
-        return ''.join(res)
-
 
 class Phrase(TokenList):
 
     token_type = 'phrase'
 
-    def _fold(self, folded):
-        # As with Unstructured, we can have pure ASCII with or without
-        # surrogateescape encoded bytes, or we could have unicode.  But this
-        # case is more complicated, since we have to deal with the various
-        # sub-token types and how they can be composed in the face of
-        # unicode-that-needs-CTE-encoding, and the fact that if a token a
-        # comment that becomes a barrier across which we can't compose encoded
-        # words.
-        last_ew = None
-        encoding = 'utf-8' if folded.policy.utf8 else 'ascii'
-        for part in self.parts:
-            tstr = str(part)
-            tlen = len(tstr)
-            has_ew = False
-            try:
-                str(part).encode(encoding)
-            except UnicodeEncodeError:
-                if any(isinstance(x, errors.UndecodableBytesDefect)
-                        for x in part.all_defects):
-                    charset = 'unknown-8bit'
-                else:
-                    charset = 'utf-8'
-                if last_ew is not None and not part.has_leading_comment():
-                    # We've already done an EW, let's see if we can combine
-                    # this one with it.  The last_ew logic ensures that all we
-                    # have at this point is atoms, no comments or quoted
-                    # strings.  So we can treat the text between the last
-                    # encoded word and the content of this token as
-                    # unstructured text, and things will work correctly.  But
-                    # we have to strip off any trailing comment on this token
-                    # first, and if it is a quoted string we have to pull out
-                    # the content (we're encoding it, so it no longer needs to
-                    # be quoted).
-                    if part[-1].token_type == 'cfws' and part.comments:
-                        remainder = part.pop(-1)
-                    else:
-                        remainder = ''
-                    for i, token in enumerate(part):
-                        if token.token_type == 'bare-quoted-string':
-                            part[i] = UnstructuredTokenList(token[:])
-                    chunk = get_unstructured(
-                        ''.join(folded.current[last_ew:]+[tstr])).as_encoded_word(charset)
-                    schunk = str(chunk)
-                    lchunk = len(schunk)
-                    if last_ew + lchunk <= folded.maxlen:
-                        del folded.current[last_ew:]
-                        folded.append(schunk)
-                        folded.lastlen = sum(len(x) for x in folded.current)
-                        continue
-                tstr = part.as_encoded_word(charset)
-                tlen = len(tstr)
-                has_ew = True
-            if folded.append_if_fits(part, tstr):
-                if has_ew and not part.comments:
-                    last_ew = len(folded.current) - 1
-                elif part.comments or part.token_type == 'quoted-string':
-                    # If a comment is involved we can't combine EWs.  And if a
-                    # quoted string is involved, it's not worth the effort to
-                    # try to combine them.
-                    last_ew = None
-                continue
-            part._fold(folded)
-
-    def cte_encode(self, charset, policy):
-        res = []
-        last_ew = None
-        is_ew = False
-        for part in self:
-            spart = str(part)
-            try:
-                spart.encode('us-ascii')
-                res.append(spart)
-            except UnicodeEncodeError:
-                is_ew = True
-                if last_ew is None:
-                    if not part.comments:
-                        last_ew = len(res)
-                    res.append(part.cte_encode(charset, policy))
-                elif not part.has_leading_comment():
-                    if part[-1].token_type == 'cfws' and part.comments:
-                        remainder = part.pop(-1)
-                    else:
-                        remainder = ''
-                    for i, token in enumerate(part):
-                        if token.token_type == 'bare-quoted-string':
-                            part[i] = UnstructuredTokenList(token[:])
-                    tl = get_unstructured(''.join(res[last_ew:] + [spart]))
-                    res[last_ew:] = [tl.as_encoded_word(charset)]
-            if part.comments or (not is_ew and part.token_type == 'quoted-string'):
-                last_ew = None
-        return ''.join(res)
-
 class Word(TokenList):
 
     token_type = 'word'
@@ -567,9 +196,6 @@ class CFWSList(WhiteSpaceTokenList):
 
     token_type = 'cfws'
 
-    def has_leading_comment(self):
-        return bool(self.comments)
-
 
 class Atom(TokenList):
 
@@ -579,6 +205,7 @@ class Atom(TokenList):
 class Token(TokenList):
 
     token_type = 'token'
+    encode_as_ew = False
 
 
 class EncodedWord(TokenList):
@@ -588,13 +215,6 @@ class EncodedWord(TokenList):
     charset = None
     lang = None
 
-    @property
-    def encoded(self):
-        if self.cte is not None:
-            return self.cte
-        _ew.encode(str(self), self.charset)
-
-
 
 class QuotedString(TokenList):
 
@@ -865,6 +485,7 @@ class InvalidMailbox(TokenList):
 class Domain(TokenList):
 
     token_type = 'domain'
+    as_ew_allowed = False
 
     @property
     def domain(self):
@@ -879,11 +500,13 @@ class DotAtom(TokenList):
 class DotAtomText(TokenList):
 
     token_type = 'dot-atom-text'
+    as_ew_allowed = True
 
 
 class AddrSpec(TokenList):
 
     token_type = 'addr-spec'
+    as_ew_allowed = False
 
     @property
     def local_part(self):
@@ -916,11 +539,13 @@ class AddrSpec(TokenList):
 class ObsLocalPart(TokenList):
 
     token_type = 'obs-local-part'
+    as_ew_allowed = False
 
 
 class DisplayName(Phrase):
 
     token_type = 'display-name'
+    ew_combine_allowed = False
 
     @property
     def display_name(self):
@@ -960,6 +585,7 @@ class DisplayName(Phrase):
 class LocalPart(TokenList):
 
     token_type = 'local-part'
+    as_ew_allowed = False
 
     @property
     def value(self):
@@ -995,6 +621,7 @@ class LocalPart(TokenList):
 class DomainLiteral(TokenList):
 
     token_type = 'domain-literal'
+    as_ew_allowed = False
 
     @property
     def domain(self):
@@ -1081,6 +708,7 @@ class Value(TokenList):
 class MimeParameters(TokenList):
 
     token_type = 'mime-parameters'
+    syntactic_break = False
 
     @property
     def params(self):
@@ -1165,6 +793,10 @@ class MimeParameters(TokenList):
 
 class ParameterizedHeaderValue(TokenList):
 
+    # Set this false so that the value doesn't wind up on a new line even
+    # if it and the parameters would fit there but not on the first line.
+    syntactic_break = False
+
     @property
     def params(self):
         for token in reversed(self):
@@ -1172,18 +804,11 @@ class ParameterizedHeaderValue(TokenList):
                 return token.params
         return {}
 
-    @property
-    def parts(self):
-        if self and self[-1].token_type == 'mime-parameters':
-            # We don't want to start a new line if all of the params don't fit
-            # after the value, so unwrap the parameter list.
-            return TokenList(self[:-1] + self[-1])
-        return TokenList(self).parts
-
 
 class ContentType(ParameterizedHeaderValue):
 
     token_type = 'content-type'
+    as_ew_allowed = False
     maintype = 'text'
     subtype = 'plain'
 
@@ -1191,40 +816,27 @@ class ContentType(ParameterizedHeaderValue):
 class ContentDisposition(ParameterizedHeaderValue):
 
     token_type = 'content-disposition'
+    as_ew_allowed = False
     content_disposition = None
 
 
 class ContentTransferEncoding(TokenList):
 
     token_type = 'content-transfer-encoding'
+    as_ew_allowed = False
     cte = '7bit'
 
 
 class HeaderLabel(TokenList):
 
     token_type = 'header-label'
+    as_ew_allowed = False
 
 
 class Header(TokenList):
 
     token_type = 'header'
 
-    def _fold(self, folded):
-        folded.append(str(self.pop(0)))
-        folded.lastlen = len(folded.current[0])
-        # The first line of the header is different from all others: we don't
-        # want to start a new object on a new line if it has any fold points in
-        # it that would allow part of it to be on the first header line.
-        # Further, if the first fold point would fit on the new line, we want
-        # to do that, but if it doesn't we want to put it on the first line.
-        # Folded supports this via the stickyspace attribute.  If this
-        # attribute is not None, it does the special handling.
-        folded.stickyspace = str(self.pop(0)) if self[0].token_type == 'cfws' else ''
-        rest = self.pop(0)
-        if self:
-            raise ValueError("Malformed Header token list")
-        rest._fold(folded)
-
 
 #
 # Terminal classes and instances
@@ -1232,6 +844,10 @@ class Header(TokenList):
 
 class Terminal(str):
 
+    as_ew_allowed = True
+    ew_combine_allowed = True
+    syntactic_break = True
+
     def __new__(cls, value, token_type):
         self = super().__new__(cls, value)
         self.token_type = token_type
@@ -1241,6 +857,9 @@ class Terminal(str):
     def __repr__(self):
         return "{}({})".format(self.__class__.__name__, super().__repr__())
 
+    def pprint(self):
+        print(self.__class__.__name__ + '/' + self.token_type)
+
     @property
     def all_defects(self):
         return list(self.defects)
@@ -1254,29 +873,14 @@ class Terminal(str):
             '' if not self.defects else ' {}'.format(self.defects),
             )]
 
-    def cte_encode(self, charset, policy):
-        value = str(self)
-        try:
-            value.encode('us-ascii')
-            return value
-        except UnicodeEncodeError:
-            return _ew.encode(value, charset)
-
     def pop_trailing_ws(self):
         # This terminates the recursion.
         return None
 
-    def pop_leading_fws(self):
-        # This terminates the recursion.
-        return None
-
     @property
     def comments(self):
         return []
 
-    def has_leading_comment(self):
-        return False
-
     def __getnewargs__(self):
         return(str(self), self.token_type)
 
@@ -1290,8 +894,6 @@ class WhiteSpaceTerminal(Terminal):
     def startswith_fws(self):
         return True
 
-    has_fws = True
-
 
 class ValueTerminal(Terminal):
 
@@ -1302,11 +904,6 @@ class ValueTerminal(Terminal):
     def startswith_fws(self):
         return False
 
-    has_fws = False
-
-    def as_encoded_word(self, charset):
-        return _ew.encode(str(self), charset)
-
 
 class EWWhiteSpaceTerminal(WhiteSpaceTerminal):
 
@@ -1314,15 +911,9 @@ class EWWhiteSpaceTerminal(WhiteSpaceTerminal):
     def value(self):
         return ''
 
-    @property
-    def encoded(self):
-        return self[:]
-
     def __str__(self):
         return ''
 
-    has_fws = True
-
 
 # XXX these need to become classes and used as instances so
 # that a program can't change them in a parse tree and screw
@@ -2752,7 +2343,7 @@ def get_parameter(value):
         if value[0] != "'":
             raise errors.HeaderParseError("Expected RFC2231 char/lang encoding "
                                           "delimiter, but found {!r}".format(value))
-        appendto.append(ValueTerminal("'", 'RFC2231 delimiter'))
+        appendto.append(ValueTerminal("'", 'RFC2231-delimiter'))
         value = value[1:]
         if value and value[0] != "'":
             token, value = get_attrtext(value)
@@ -2761,7 +2352,7 @@ def get_parameter(value):
             if not value or value[0] != "'":
                 raise errors.HeaderParseError("Expected RFC2231 char/lang encoding "
                                   "delimiter, but found {}".format(value))
-        appendto.append(ValueTerminal("'", 'RFC2231 delimiter'))
+        appendto.append(ValueTerminal("'", 'RFC2231-delimiter'))
         value = value[1:]
     if remainder is not None:
         # Treat the rest of value as bare quoted string content.
@@ -2966,3 +2557,255 @@ def parse_content_transfer_encoding_header(value):
             token, value = get_phrase(value)
             cte_header.append(token)
     return cte_header
+
+
+#
+# Header folding
+#
+# Header folding is complex, with lots of rules and corner cases.  The
+# following code does its best to obey the rules and handle the corner
+# cases, but you can be sure there are few bugs:)
+#
+# This folder generally canonicalizes as it goes, preferring the stringified
+# version of each token.  The tokens contain information that supports the
+# folder, including which tokens can be encoded in which ways.
+#
+# Folded text is accumulated in a simple list of strings ('lines'), each
+# one of which should be less than policy.max_line_length ('maxlen').
+#
+
+def _steal_trailing_WSP_if_exists(lines):
+    wsp = ''
+    if lines and lines[-1] and lines[-1][-1] in WSP:
+        wsp = lines[-1][-1]
+        lines[-1] = lines[-1][:-1]
+    return wsp
+
+def _refold_parse_tree(parse_tree, *, policy):
+    """Return string of contents of parse_tree folded according to RFC rules.
+
+    """
+    # max_line_length 0/None means no limit, ie: infinitely long.
+    maxlen = policy.max_line_length or float("+inf")
+    encoding = 'utf-8' if policy.utf8 else 'us-ascii'
+    lines = ['']
+    last_ew = None
+    wrap_as_ew_blocked = 0
+    want_encoding = False
+    end_ew_not_allowed = Terminal('', 'wrap_as_ew_blocked')
+    parts = list(parse_tree)
+    while parts:
+        part = parts.pop(0)
+        if part is end_ew_not_allowed:
+            wrap_as_ew_blocked -= 1
+            continue
+        tstr = str(part)
+        try:
+            tstr.encode(encoding)
+            charset = encoding
+        except UnicodeEncodeError:
+            if any(isinstance(x, errors.UndecodableBytesDefect)
+                   for x in part.all_defects):
+                charset = 'unknown-8bit'
+            else:
+                # If policy.utf8 is false this should really be taken from a
+                # 'charset' property on the policy.
+                charset = 'utf-8'
+            want_encoding = True
+        if part.token_type == 'mime-parameters':
+            # Mime parameter folding (using RFC2231) is extra special.
+            _fold_mime_parameters(part, lines, maxlen, encoding)
+            continue
+        if want_encoding and not wrap_as_ew_blocked:
+            if not part.as_ew_allowed:
+                want_encoding = False
+                last_ew = None
+                if part.syntactic_break:
+                    encoded_part = part.fold(policy=policy)[:-1] # strip nl
+                    if policy.linesep not in encoded_part:
+                        # It fits on a single line
+                        if len(encoded_part) > maxlen - len(lines[-1]):
+                            # But not on this one, so start a new one.
+                            newline = _steal_trailing_WSP_if_exists(lines)
+                            # XXX what if encoded_part has no leading FWS?
+                            lines.append(newline)
+                        lines[-1] += encoded_part
+                        continue
+                # Either this is not a major syntactic break, so we don't
+                # want it on a line by itself even if it fits, or it
+                # doesn't fit on a line by itself.  Either way, fall through
+                # to unpacking the subparts and wrapping them.
+            if not hasattr(part, 'encode'):
+                # It's not a Terminal, do each piece individually.
+                parts = list(part) + parts
+            else:
+                # It's a terminal, wrap it as an encoded word, possibly
+                # combining it with previously encoded words if allowed.
+                last_ew = _fold_as_ew(tstr, lines, maxlen, last_ew,
+                                      part.ew_combine_allowed, charset)
+            want_encoding = False
+            continue
+        if len(tstr) <= maxlen - len(lines[-1]):
+            lines[-1] += tstr
+            continue
+        # This part is too long to fit.  The RFC wants us to break at
+        # "major syntactic breaks", so unless we don't consider this
+        # to be one, check if it will fit on the next line by itself.
+        if (part.syntactic_break and
+                len(tstr) + 1 <= maxlen):
+            newline = _steal_trailing_WSP_if_exists(lines)
+            if newline or part.startswith_fws():
+                lines.append(newline + tstr)
+                continue
+        if not hasattr(part, 'encode'):
+            # It's not a terminal, try folding the subparts.
+            newparts = list(part)
+            if not part.as_ew_allowed:
+                wrap_as_ew_blocked += 1
+                newparts.append(end_ew_not_allowed)
+            parts = newparts + parts
+            continue
+        if part.as_ew_allowed and not wrap_as_ew_blocked:
+            # It doesn't need CTE encoding, but encode it anyway so we can
+            # wrap it.
+            parts.insert(0, part)
+            want_encoding = True
+            continue
+        # We can't figure out how to wrap, it, so give up.
+        newline = _steal_trailing_WSP_if_exists(lines)
+        if newline or part.startswith_fws():
+            lines.append(newline + tstr)
+        else:
+            # We can't fold it onto the next line either...
+            lines[-1] += tstr
+    return policy.linesep.join(lines) + policy.linesep
+
+def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset):
+    """Fold string to_encode into lines as encoded word, combining if allowed.
+    Return the new value for last_ew, or None if ew_combine_allowed is False.
+
+    If there is already an encoded word in the last line of lines (indicated by
+    a non-None value for last_ew) and ew_combine_allowed is true, decode the
+    existing ew, combine it with to_encode, and re-encode.  Otherwise, encode
+    to_encode.  In either case, split to_encode as necessary so that the
+    encoded segments fit within maxlen.
+
+    """
+    if last_ew is not None and ew_combine_allowed:
+        to_encode = str(
+            get_unstructured(lines[-1][last_ew:] + to_encode))
+        lines[-1] = lines[-1][:last_ew]
+    if to_encode[0] in WSP:
+        # We're joining this to non-encoded text, so don't encode
+        # the leading blank.
+        leading_wsp = to_encode[0]
+        to_encode = to_encode[1:]
+        if (len(lines[-1]) == maxlen):
+            lines.append(_steal_trailing_WSP_if_exists(lines))
+        lines[-1] += leading_wsp
+    trailing_wsp = ''
+    if to_encode[-1] in WSP:
+        # Likewise for the trailing space.
+        trailing_wsp = to_encode[-1]
+        to_encode = to_encode[:-1]
+    new_last_ew = len(lines[-1]) if last_ew is None else last_ew
+    while to_encode:
+        remaining_space = maxlen - len(lines[-1])
+        # The RFC2047 chrome takes up 7 characters plus the length
+        # of the charset name.
+        encode_as = 'utf-8' if charset == 'us-ascii' else charset
+        text_space = remaining_space - len(encode_as) - 7
+        if text_space <= 0:
+            lines.append(' ')
+            # XXX We'll get an infinite loop here if maxlen is <= 7
+            continue
+        first_part = to_encode[:text_space]
+        ew = _ew.encode(first_part, charset=encode_as)
+        excess = len(ew) - remaining_space
+        if excess > 0:
+            # encode always chooses the shortest encoding, so this
+            # is guaranteed to fit at this point.
+            first_part = first_part[:-excess]
+            ew = _ew.encode(first_part)
+        lines[-1] += ew
+        to_encode = to_encode[len(first_part):]
+        if to_encode:
+            lines.append(' ')
+            new_last_ew = len(lines[-1])
+    lines[-1] += trailing_wsp
+    return new_last_ew if ew_combine_allowed else None
+
+def _fold_mime_parameters(part, lines, maxlen, encoding):
+    """Fold TokenList 'part' into the 'lines' list as mime parameters.
+
+    Using the decoded list of parameters and values, format them according to
+    the RFC rules, including using RFC2231 encoding if the value cannot be
+    expressed in 'encoding' and/or the paramter+value is too long to fit within
+    'maxlen'.
+
+    """
+    # Special case for RFC2231 encoding: start from decoded values and use
+    # RFC2231 encoding iff needed.
+    #
+    # Note that the 1 and 2s being added to the length calculations are
+    # accounting for the possibly-needed spaces and semicolons we'll be adding.
+    #
+    for name, value in part.params:
+        # XXX What if this ';' puts us over maxlen the first time through the
+        # loop?  We should split the header value onto a newline in that case,
+        # but to do that we need to recognize the need earlier or reparse the
+        # header, so I'm going to ignore that bug for now.  It'll only put us
+        # one character over.
+        if not lines[-1].rstrip().endswith(';'):
+            lines[-1] += ';'
+        charset = encoding
+        error_handler = 'strict'
+        try:
+            value.encode(encoding)
+            encoding_required = False
+        except UnicodeEncodeError:
+            encoding_required = True
+            if utils._has_surrogates(value):
+                charset = 'unknown-8bit'
+                error_handler = 'surrogateescape'
+            else:
+                charset = 'utf-8'
+        if encoding_required:
+            encoded_value = urllib.parse.quote(
+                value, safe='', errors=error_handler)
+            tstr = "{}*={}''{}".format(name, charset, encoded_value)
+        else:
+            tstr = '{}={}'.format(name, quote_string(value))
+        if len(lines[-1]) + len(tstr) + 1 < maxlen:
+            lines[-1] = lines[-1] + ' ' + tstr
+            continue
+        elif len(tstr) + 2 <= maxlen:
+            lines.append(' ' + tstr)
+            continue
+        # We need multiple sections.  We are allowed to mix encoded and
+        # non-encoded sections, but we aren't going to.  We'll encode them all.
+        section = 0
+        extra_chrome = charset + "''"
+        while value:
+            chrome_len = len(name) + len(str(section)) + 3 + len(extra_chrome)
+            if maxlen <= chrome_len + 3:
+                # We need room for the leading blank, the trailing semicolon,
+                # and at least one character of the value.  If we don't
+                # have that, we'd be stuck, so in that case fall back to
+                # the RFC standard width.
+                maxlen = 78
+            splitpoint = maxchars = maxlen - chrome_len - 2
+            while True:
+                partial = value[:splitpoint]
+                encoded_value = urllib.parse.quote(
+                    partial, safe='', errors=error_handler)
+                if len(encoded_value) <= maxchars:
+                    break
+                splitpoint -= 1
+            lines.append(" {}*{}*={}{}".format(
+                name, section, extra_chrome, encoded_value))
+            extra_chrome = ''
+            section += 1
+            value = value[splitpoint:]
+            if value:
+                lines[-1] += ';'
index 0fc2231e5cbd2949033523b101bfd493ed440537..f5be87f4d24368e5a4a419dde0b857968c44850c 100644 (file)
@@ -245,13 +245,16 @@ class BaseHeader(str):
         the header name and the ': ' separator.
 
         """
-        # At some point we need to only put fws here if it was in the source.
+        # At some point we need to put fws here iif it was in the source.
         header = parser.Header([
             parser.HeaderLabel([
                 parser.ValueTerminal(self.name, 'header-name'),
                 parser.ValueTerminal(':', 'header-sep')]),
-            parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')]),
-                             self._parse_tree])
+            ])
+        if self._parse_tree:
+            header.append(
+                parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')]))
+        header.append(self._parse_tree)
         return header.fold(policy=policy)
 
 
index a759d23308d3026d485a46b315b796ea1a719f89..39c22406078074dd6f03db166924721241c1ad02 100644 (file)
@@ -215,6 +215,12 @@ def parsedate_to_datetime(data):
 
 
 def parseaddr(addr):
+    """
+    Parse addr into its constituent realname and email address parts.
+
+    Return a tuple of realname and email address, unless the parse fails, in
+    which case return a 2-tuple of ('', '').
+    """
     addrs = _AddressList(addr).addresslist
     if not addrs:
         return '', ''
index 9f5d15109a3c43bdb67738e39828e900f477111e..d69e09fab084e6d217439b0c7c7c7355a621631b 100644 (file)
@@ -25,7 +25,7 @@ def _run_pip(args, additional_paths=None):
 
     # Install the bundled software
     import pip
-    pip.main(args)
+    return pip.main(args)
 
 
 def version():
@@ -53,6 +53,21 @@ def bootstrap(*, root=None, upgrade=False, user=False,
     Bootstrap pip into the current Python installation (or the given root
     directory).
 
+    Note that calling this function will alter both sys.path and os.environ.
+    """
+    # Discard the return value
+    _bootstrap(root=root, upgrade=upgrade, user=user,
+               altinstall=altinstall, default_pip=default_pip,
+               verbosity=verbosity)
+
+
+def _bootstrap(*, root=None, upgrade=False, user=False,
+              altinstall=False, default_pip=False,
+              verbosity=0):
+    """
+    Bootstrap pip into the current Python installation (or the given root
+    directory). Returns pip command status code.
+
     Note that calling this function will alter both sys.path and os.environ.
     """
     if altinstall and default_pip:
@@ -99,7 +114,7 @@ def bootstrap(*, root=None, upgrade=False, user=False,
         if verbosity:
             args += ["-" + "v" * verbosity]
 
-        _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
+        return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
 
 def _uninstall_helper(*, verbosity=0):
     """Helper to support a clean default uninstall process on Windows
@@ -126,7 +141,7 @@ def _uninstall_helper(*, verbosity=0):
     if verbosity:
         args += ["-" + "v" * verbosity]
 
-    _run_pip(args + [p[0] for p in reversed(_PROJECTS)])
+    return _run_pip(args + [p[0] for p in reversed(_PROJECTS)])
 
 
 def _main(argv=None):
@@ -180,7 +195,7 @@ def _main(argv=None):
 
     args = parser.parse_args(argv)
 
-    bootstrap(
+    return _bootstrap(
         root=args.root,
         upgrade=args.upgrade,
         user=args.user,
index 77527d7a3513596852d1eb0ff8d8935a98e0cc26..03eef0dd94d0b77764cbd737f69945d04e4b1bc6 100644 (file)
@@ -1,4 +1,5 @@
 import ensurepip
+import sys
 
 if __name__ == "__main__":
-    ensurepip._main()
+    sys.exit(ensurepip._main())
index 750365ec4d04da980399c94c35668935482b9cce..b257904328d2f5dc3b5f07e7d6c883fb9e2055a9 100644 (file)
@@ -2,6 +2,7 @@
 
 import argparse
 import ensurepip
+import sys
 
 
 def _main(argv=None):
@@ -23,8 +24,8 @@ def _main(argv=None):
 
     args = parser.parse_args(argv)
 
-    ensurepip._uninstall_helper(verbosity=args.verbosity)
+    return ensurepip._uninstall_helper(verbosity=args.verbosity)
 
 
 if __name__ == "__main__":
-    _main()
+    sys.exit(_main())
index f03e9cde8c900228dea36781c9bec91013287c69..6e1f0cc95ca6c717a37dbaede52ed9676b076b48 100644 (file)
@@ -3,6 +3,61 @@ Released on 2017-09-25?
 ========================
 
 
+bpo-32164: Delete unused file idlelib/tabbedpages.py.
+Use of TabbedPageSet in configdialog was replaced by ttk.Notebook.
+
+bpo-32100: Fix old and new bugs in pathbrowser; improve tests.
+Patch mostly by Cheryl Sabella.
+
+bpo-31860: The font sample in the settings dialog is now editable.
+Edits persist while IDLE remains open.
+Patch by Serhiy Storchake and Terry Jan Reedy.
+
+bpo-31858: Restrict shell prompt manipulaton to the shell.
+Editor and output windows only see an empty last prompt line.  This
+simplifies the code and fixes a minor bug when newline is inserted.
+Sys.ps1, if present, is read on Shell start-up, but is not set or changed.
+Patch by Terry Jan Reedy.
+
+bpo-28603: Fix a TypeError that caused a shell restart when printing
+a traceback that includes an exception that is unhashable.
+Patch by Zane Bitter.
+
+bpo-13802: Use non-Latin characters in the Font settings sample.
+Even if one selects a font that defines a limited subset of the unicode
+Basic Multilingual Plane, tcl/tk will use other fonts that define a
+character.  The expanded example give users of non-Latin characters
+a better idea of what they might see in the shell and editors.
+
+To make room for the expanded sample, frames on the Font tab are
+re-arranged.  The Font/Tabs help explains a bit about the additions.
+Patch by Terry Jan Reedy
+
+bpo-31460: Simplify the API of IDLE's Module Browser.
+Passing a widget instead of an flist with a root widget opens the
+option of creating a browser frame that is only part of a window.
+Passing a full file name instead of pieces assumed to come from a
+.py file opens the possibility of browsing python files that do not
+end in .py.
+
+bpo-31649: Make _htest and _utest parameters keyword-only.
+These are used to adjust code for human and unit tests.
+
+bpo-31459: Rename module browser from Class Browser to Module Browser.
+The original module-level class and method browser became a module
+browser, with the addition of module-level functions, years ago.
+Nested classes and functions were added yesterday.  For back-
+compatibility, the virtual event <<open-class-browser>>, which
+appears on the Keys tab of the Settings dialog, is not changed.
+Patch by Cheryl Sabella.
+
+bpo-1612262: Module browser now shows nested classes and functions.
+Original patches for code and tests by Guilherme Polo and
+Cheryl Sabella, respectively.  Revisions by Terry Jan Reedy.
+
+bpo-31500: Tk's default fonts now are scaled on HiDPI displays.
+This affects all dialogs.  Patch by Serhiy Storchaka.
+
 bpo-31493: Fix code context update and font update timers.
 Canceling timers prevents a warning message when test_idle completes.
 
@@ -42,7 +97,7 @@ extension.cfg.  All take effect as soon as one clicks Apply or Ok.
 '<<zoom-height>>'.  Any (global) customizations made before 3.6.3 will
 not affect their keyset-specific customization after 3.6.3. and vice
 versa.
-  Inital patch by Charles Wohlganger, revised by Terry Jan Reedy.
+  Initial patch by Charles Wohlganger, revised by Terry Jan Reedy.
 
 bpo-31051:  Rearrange condigdialog General tab.
 Sort non-Help options into Window (Shell+Editor) and Editor (only).
diff --git a/Lib/idlelib/_pyclbr.py b/Lib/idlelib/_pyclbr.py
new file mode 100644 (file)
index 0000000..e85566d
--- /dev/null
@@ -0,0 +1,402 @@
+# A private copy of 3.7.0a1 pyclbr for use by idlelib.browser
+"""Parse a Python module and describe its classes and functions.
+
+Parse enough of a Python file to recognize imports and class and
+function definitions, and to find out the superclasses of a class.
+
+The interface consists of a single function:
+    readmodule_ex(module, path=None)
+where module is the name of a Python module, and path is an optional
+list of directories where the module is to be searched.  If present,
+path is prepended to the system search path sys.path.  The return value
+is a dictionary.  The keys of the dictionary are the names of the
+classes and functions defined in the module (including classes that are
+defined via the from XXX import YYY construct).  The values are
+instances of classes Class and Function.  One special key/value pair is
+present for packages: the key '__path__' has a list as its value which
+contains the package search path.
+
+Classes and Functions have a common superclass: _Object.  Every instance
+has the following attributes:
+    module  -- name of the module;
+    name    -- name of the object;
+    file    -- file in which the object is defined;
+    lineno  -- line in the file where the object's definition starts;
+    parent  -- parent of this object, if any;
+    children -- nested objects contained in this object.
+The 'children' attribute is a dictionary mapping names to objects.
+
+Instances of Function describe functions with the attributes from _Object.
+
+Instances of Class describe classes with the attributes from _Object,
+plus the following:
+    super   -- list of super classes (Class instances if possible);
+    methods -- mapping of method names to beginning line numbers.
+If the name of a super class is not recognized, the corresponding
+entry in the list of super classes is not a class instance but a
+string giving the name of the super class.  Since import statements
+are recognized and imported modules are scanned as well, this
+shouldn't happen often.
+"""
+
+import io
+import sys
+import importlib.util
+import tokenize
+from token import NAME, DEDENT, OP
+
+__all__ = ["readmodule", "readmodule_ex", "Class", "Function"]
+
+_modules = {}  # Initialize cache of modules we've seen.
+
+
+class _Object:
+    "Informaton about Python class or function."
+    def __init__(self, module, name, file, lineno, parent):
+        self.module = module
+        self.name = name
+        self.file = file
+        self.lineno = lineno
+        self.parent = parent
+        self.children = {}
+
+    def _addchild(self, name, obj):
+        self.children[name] = obj
+
+
+class Function(_Object):
+    "Information about a Python function, including methods."
+    def __init__(self, module, name, file, lineno, parent=None):
+        _Object.__init__(self, module, name, file, lineno, parent)
+
+
+class Class(_Object):
+    "Information about a Python class."
+    def __init__(self, module, name, super, file, lineno, parent=None):
+        _Object.__init__(self, module, name, file, lineno, parent)
+        self.super = [] if super is None else super
+        self.methods = {}
+
+    def _addmethod(self, name, lineno):
+        self.methods[name] = lineno
+
+
+def _nest_function(ob, func_name, lineno):
+    "Return a Function after nesting within ob."
+    newfunc = Function(ob.module, func_name, ob.file, lineno, ob)
+    ob._addchild(func_name, newfunc)
+    if isinstance(ob, Class):
+        ob._addmethod(func_name, lineno)
+    return newfunc
+
+def _nest_class(ob, class_name, lineno, super=None):
+    "Return a Class after nesting within ob."
+    newclass = Class(ob.module, class_name, super, ob.file, lineno, ob)
+    ob._addchild(class_name, newclass)
+    return newclass
+
+def readmodule(module, path=None):
+    """Return Class objects for the top-level classes in module.
+
+    This is the original interface, before Functions were added.
+    """
+
+    res = {}
+    for key, value in _readmodule(module, path or []).items():
+        if isinstance(value, Class):
+            res[key] = value
+    return res
+
+def readmodule_ex(module, path=None):
+    """Return a dictionary with all functions and classes in module.
+
+    Search for module in PATH + sys.path.
+    If possible, include imported superclasses.
+    Do this by reading source, without importing (and executing) it.
+    """
+    return _readmodule(module, path or [])
+
+def _readmodule(module, path, inpackage=None):
+    """Do the hard work for readmodule[_ex].
+
+    If inpackage is given, it must be the dotted name of the package in
+    which we are searching for a submodule, and then PATH must be the
+    package search path; otherwise, we are searching for a top-level
+    module, and path is combined with sys.path.
+    """
+    # Compute the full module name (prepending inpackage if set).
+    if inpackage is not None:
+        fullmodule = "%s.%s" % (inpackage, module)
+    else:
+        fullmodule = module
+
+    # Check in the cache.
+    if fullmodule in _modules:
+        return _modules[fullmodule]
+
+    # Initialize the dict for this module's contents.
+    tree = {}
+
+    # Check if it is a built-in module; we don't do much for these.
+    if module in sys.builtin_module_names and inpackage is None:
+        _modules[module] = tree
+        return tree
+
+    # Check for a dotted module name.
+    i = module.rfind('.')
+    if i >= 0:
+        package = module[:i]
+        submodule = module[i+1:]
+        parent = _readmodule(package, path, inpackage)
+        if inpackage is not None:
+            package = "%s.%s" % (inpackage, package)
+        if not '__path__' in parent:
+            raise ImportError('No package named {}'.format(package))
+        return _readmodule(submodule, parent['__path__'], package)
+
+    # Search the path for the module.
+    f = None
+    if inpackage is not None:
+        search_path = path
+    else:
+        search_path = path + sys.path
+    spec = importlib.util._find_spec_from_path(fullmodule, search_path)
+    _modules[fullmodule] = tree
+    # Is module a package?
+    if spec.submodule_search_locations is not None:
+        tree['__path__'] = spec.submodule_search_locations
+    try:
+        source = spec.loader.get_source(fullmodule)
+        if source is None:
+            return tree
+    except (AttributeError, ImportError):
+        # If module is not Python source, we cannot do anything.
+        return tree
+
+    fname = spec.loader.get_filename(fullmodule)
+    return _create_tree(fullmodule, path, fname, source, tree, inpackage)
+
+
+def _create_tree(fullmodule, path, fname, source, tree, inpackage):
+    """Return the tree for a particular module.
+
+    fullmodule (full module name), inpackage+module, becomes o.module.
+    path is passed to recursive calls of _readmodule.
+    fname becomes o.file.
+    source is tokenized.  Imports cause recursive calls to _readmodule.
+    tree is {} or {'__path__': <submodule search locations>}.
+    inpackage, None or string, is passed to recursive calls of _readmodule.
+
+    The effect of recursive calls is mutation of global _modules.
+    """
+    f = io.StringIO(source)
+
+    stack = [] # Initialize stack of (class, indent) pairs.
+
+    g = tokenize.generate_tokens(f.readline)
+    try:
+        for tokentype, token, start, _end, _line in g:
+            if tokentype == DEDENT:
+                lineno, thisindent = start
+                # Close previous nested classes and defs.
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+            elif token == 'def':
+                lineno, thisindent = start
+                # Close previous nested classes and defs.
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+                tokentype, func_name, start = next(g)[0:3]
+                if tokentype != NAME:
+                    continue  # Skip def with syntax error.
+                cur_func = None
+                if stack:
+                    cur_obj = stack[-1][0]
+                    cur_func = _nest_function(cur_obj, func_name, lineno)
+                else:
+                    # It is just a function.
+                    cur_func = Function(fullmodule, func_name, fname, lineno)
+                    tree[func_name] = cur_func
+                stack.append((cur_func, thisindent))
+            elif token == 'class':
+                lineno, thisindent = start
+                # Close previous nested classes and defs.
+                while stack and stack[-1][1] >= thisindent:
+                    del stack[-1]
+                tokentype, class_name, start = next(g)[0:3]
+                if tokentype != NAME:
+                    continue # Skip class with syntax error.
+                # Parse what follows the class name.
+                tokentype, token, start = next(g)[0:3]
+                inherit = None
+                if token == '(':
+                    names = [] # Initialize list of superclasses.
+                    level = 1
+                    super = [] # Tokens making up current superclass.
+                    while True:
+                        tokentype, token, start = next(g)[0:3]
+                        if token in (')', ',') and level == 1:
+                            n = "".join(super)
+                            if n in tree:
+                                # We know this super class.
+                                n = tree[n]
+                            else:
+                                c = n.split('.')
+                                if len(c) > 1:
+                                    # Super class form is module.class:
+                                    # look in module for class.
+                                    m = c[-2]
+                                    c = c[-1]
+                                    if m in _modules:
+                                        d = _modules[m]
+                                        if c in d:
+                                            n = d[c]
+                            names.append(n)
+                            super = []
+                        if token == '(':
+                            level += 1
+                        elif token == ')':
+                            level -= 1
+                            if level == 0:
+                                break
+                        elif token == ',' and level == 1:
+                            pass
+                        # Only use NAME and OP (== dot) tokens for type name.
+                        elif tokentype in (NAME, OP) and level == 1:
+                            super.append(token)
+                        # Expressions in the base list are not supported.
+                    inherit = names
+                if stack:
+                    cur_obj = stack[-1][0]
+                    cur_class = _nest_class(
+                            cur_obj, class_name, lineno, inherit)
+                else:
+                    cur_class = Class(fullmodule, class_name, inherit,
+                                      fname, lineno)
+                    tree[class_name] = cur_class
+                stack.append((cur_class, thisindent))
+            elif token == 'import' and start[1] == 0:
+                modules = _getnamelist(g)
+                for mod, _mod2 in modules:
+                    try:
+                        # Recursively read the imported module.
+                        if inpackage is None:
+                            _readmodule(mod, path)
+                        else:
+                            try:
+                                _readmodule(mod, path, inpackage)
+                            except ImportError:
+                                _readmodule(mod, [])
+                    except:
+                        # If we can't find or parse the imported module,
+                        # too bad -- don't die here.
+                        pass
+            elif token == 'from' and start[1] == 0:
+                mod, token = _getname(g)
+                if not mod or token != "import":
+                    continue
+                names = _getnamelist(g)
+                try:
+                    # Recursively read the imported module.
+                    d = _readmodule(mod, path, inpackage)
+                except:
+                    # If we can't find or parse the imported module,
+                    # too bad -- don't die here.
+                    continue
+                # Add any classes that were defined in the imported module
+                # to our name space if they were mentioned in the list.
+                for n, n2 in names:
+                    if n in d:
+                        tree[n2 or n] = d[n]
+                    elif n == '*':
+                        # Don't add names that start with _.
+                        for n in d:
+                            if n[0] != '_':
+                                tree[n] = d[n]
+    except StopIteration:
+        pass
+
+    f.close()
+    return tree
+
+
+def _getnamelist(g):
+    """Return list of (dotted-name, as-name or None) tuples for token source g.
+
+    An as-name is the name that follows 'as' in an as clause.
+    """
+    names = []
+    while True:
+        name, token = _getname(g)
+        if not name:
+            break
+        if token == 'as':
+            name2, token = _getname(g)
+        else:
+            name2 = None
+        names.append((name, name2))
+        while token != "," and "\n" not in token:
+            token = next(g)[1]
+        if token != ",":
+            break
+    return names
+
+
+def _getname(g):
+    "Return (dotted-name or None, next-token) tuple for token source g."
+    parts = []
+    tokentype, token = next(g)[0:2]
+    if tokentype != NAME and token != '*':
+        return (None, token)
+    parts.append(token)
+    while True:
+        tokentype, token = next(g)[0:2]
+        if token != '.':
+            break
+        tokentype, token = next(g)[0:2]
+        if tokentype != NAME:
+            break
+        parts.append(token)
+    return (".".join(parts), token)
+
+
+def _main():
+    "Print module output (default this file) for quick visual check."
+    import os
+    try:
+        mod = sys.argv[1]
+    except:
+        mod = __file__
+    if os.path.exists(mod):
+        path = [os.path.dirname(mod)]
+        mod = os.path.basename(mod)
+        if mod.lower().endswith(".py"):
+            mod = mod[:-3]
+    else:
+        path = []
+    tree = readmodule_ex(mod, path)
+    lineno_key = lambda a: getattr(a, 'lineno', 0)
+    objs = sorted(tree.values(), key=lineno_key, reverse=True)
+    indent_level = 2
+    while objs:
+        obj = objs.pop()
+        if isinstance(obj, list):
+            # Value is a __path__ key.
+            continue
+        if not hasattr(obj, 'indent'):
+            obj.indent = 0
+
+        if isinstance(obj, _Object):
+            new_objs = sorted(obj.children.values(),
+                              key=lineno_key, reverse=True)
+            for ob in new_objs:
+                ob.indent = obj.indent + indent_level
+            objs.extend(new_objs)
+        if isinstance(obj, Class):
+            print("{}class {} {} {}"
+                  .format(' ' * obj.indent, obj.name, obj.super, obj.lineno))
+        elif isinstance(obj, Function):
+            print("{}def {} {}".format(' ' * obj.indent, obj.name, obj.lineno))
+
+if __name__ == "__main__":
+    _main()
index 4cf4744fb0a8edbc53fa8034e9282277475cac28..571dd8fe0e20a32076a8c0a9e4566b3678e053b4 100644 (file)
@@ -1,17 +1,16 @@
-"""Class browser.
+"""Module browser.
 
 XXX TO DO:
 
 - reparse when source changed (maybe just a button would be OK?)
     (or recheck on window popup)
 - add popup menu with more options (e.g. doc strings, base classes, imports)
-- show function argument list? (have to do pattern matching on source)
-- should the classes and methods lists also be in the module's menu bar?
 - add base classes to class browser tree
+- finish removing limitation to x.py files (ModuleBrowserTreeItem)
 """
 
 import os
-import pyclbr
+from idlelib import _pyclbr as pyclbr
 import sys
 
 from idlelib.config import idleConf
@@ -19,23 +18,57 @@ from idlelib import pyshell
 from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
 from idlelib.windows import ListedToplevel
 
+
 file_open = None  # Method...Item and Class...Item use this.
 # Normally pyshell.flist.open, but there is no pyshell.flist for htest.
 
-class ClassBrowser:
+
+def transform_children(child_dict, modname=None):
+    """Transform a child dictionary to an ordered sequence of objects.
+
+    The dictionary maps names to pyclbr information objects.
+    Filter out imported objects.
+    Augment class names with bases.
+    Sort objects by line number.
+
+    The current tree only calls this once per child_dic as it saves
+    TreeItems once created.  A future tree and tests might violate this,
+    so a check prevents multiple in-place augmentations.
+    """
+    obs = []  # Use list since values should already be sorted.
+    for key, obj in child_dict.items():
+        if modname is None or obj.module == modname:
+            if hasattr(obj, 'super') and obj.super and obj.name == key:
+                # If obj.name != key, it has already been suffixed.
+                supers = []
+                for sup in obj.super:
+                    if type(sup) is type(''):
+                        sname = sup
+                    else:
+                        sname = sup.name
+                        if sup.module != obj.module:
+                            sname = f'{sup.module}.{sname}'
+                    supers.append(sname)
+                obj.name += '({})'.format(', '.join(supers))
+            obs.append(obj)
+    return sorted(obs, key=lambda o: o.lineno)
+
+
+class ModuleBrowser:
     """Browse module classes and functions in IDLE.
     """
+    # This class is also the base class for pathbrowser.PathBrowser.
+    # Init and close are inherited, other methods are overridden.
+    # PathBrowser.__init__ does not call __init__ below.
 
-    def __init__(self, flist, name, path, _htest=False):
-        # XXX This API should change, if the file doesn't end in ".py"
-        # XXX the code here is bogus!
+    def __init__(self, master, path, *, _htest=False, _utest=False):
         """Create a window for browsing a module's structure.
 
         Args:
-            flist: filelist.FileList instance used as the root for the window.
-            name: Python module to parse.
-            path: Module search path.
-            _htest - bool, change box when location running htest.
+            master: parent for widgets.
+            path: full path of file to browse.
+            _htest - bool; change box location when running htest.
+            -utest - bool; suppress contents when running unittest.
 
         Global variables:
             file_open: Function used for opening a file.
@@ -46,56 +79,63 @@ class ClassBrowser:
                 creating ModuleBrowserTreeItem as the rootnode for
                 the tree and subsequently in the children.
         """
-        global file_open
-        if not _htest:
-            file_open = pyshell.flist.open
-        self.name = name
-        self.file = os.path.join(path[0], self.name + ".py")
+        self.master = master
+        self.path = path
         self._htest = _htest
-        self.init(flist)
+        self._utest = _utest
+        self.init()
 
     def close(self, event=None):
         "Dismiss the window and the tree nodes."
         self.top.destroy()
         self.node.destroy()
 
-    def init(self, flist):
+    def init(self):
         "Create browser tkinter widgets, including the tree."
-        self.flist = flist
-        # reset pyclbr
+        global file_open
+        root = self.master
+        flist = (pyshell.flist if not (self._htest or self._utest)
+                 else pyshell.PyShellFileList(root))
+        file_open = flist.open
         pyclbr._modules.clear()
+
         # create top
-        self.top = top = ListedToplevel(flist.root)
+        self.top = top = ListedToplevel(root)
         top.protocol("WM_DELETE_WINDOW", self.close)
         top.bind("<Escape>", self.close)
         if self._htest: # place dialog below parent if running htest
             top.geometry("+%d+%d" %
-                (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200))
+                (root.winfo_rootx(), root.winfo_rooty() + 200))
         self.settitle()
         top.focus_set()
+
         # create scrolled canvas
         theme = idleConf.CurrentTheme()
         background = idleConf.GetHighlight(theme, 'normal')['background']
-        sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
+        sc = ScrolledCanvas(top, bg=background, highlightthickness=0,
+                            takefocus=1)
         sc.frame.pack(expand=1, fill="both")
         item = self.rootnode()
         self.node = node = TreeNode(sc.canvas, None, item)
-        node.update()
-        node.expand()
+        if not self._utest:
+            node.update()
+            node.expand()
 
     def settitle(self):
         "Set the window title."
-        self.top.wm_title("Class Browser - " + self.name)
-        self.top.wm_iconname("Class Browser")
+        self.top.wm_title("Module Browser - " + os.path.basename(self.path))
+        self.top.wm_iconname("Module Browser")
 
     def rootnode(self):
         "Return a ModuleBrowserTreeItem as the root of the tree."
-        return ModuleBrowserTreeItem(self.file)
+        return ModuleBrowserTreeItem(self.path)
+
 
 class ModuleBrowserTreeItem(TreeItem):
     """Browser tree for Python module.
 
     Uses TreeItem as the basis for the structure of the tree.
+    Used by both browsers.
     """
 
     def __init__(self, file):
@@ -115,16 +155,8 @@ class ModuleBrowserTreeItem(TreeItem):
         return "python"
 
     def GetSubList(self):
-        """Return the list of ClassBrowserTreeItem items.
-
-        Each item returned from listclasses is the first level of
-        classes/functions within the module.
-        """
-        sublist = []
-        for name in self.listclasses():
-            item = ClassBrowserTreeItem(name, self.classes, self.file)
-            sublist.append(item)
-        return sublist
+        "Return ChildBrowserTreeItems for children."
+        return [ChildBrowserTreeItem(obj) for obj in self.listchildren()]
 
     def OnDoubleClick(self):
         "Open a module in an editor window when double clicked."
@@ -132,89 +164,44 @@ class ModuleBrowserTreeItem(TreeItem):
             return
         if not os.path.exists(self.file):
             return
-        pyshell.flist.open(self.file)
+        file_open(self.file)
 
     def IsExpandable(self):
         "Return True if Python (.py) file."
         return os.path.normcase(self.file[-3:]) == ".py"
 
-    def listclasses(self):
-        """Return list of classes and functions in the module.
-
-        The dictionary output from pyclbr is re-written as a
-        list of tuples in the form (lineno, name) and
-        then sorted so that the classes and functions are
-        processed in line number order.  The returned list only
-        contains the name and not the line number.  An instance
-        variable self.classes contains the pyclbr dictionary values,
-        which are instances of Class and Function.
-        """
-        dir, file = os.path.split(self.file)
-        name, ext = os.path.splitext(file)
+    def listchildren(self):
+        "Return sequenced classes and functions in the module."
+        dir, base = os.path.split(self.file)
+        name, ext = os.path.splitext(base)
         if os.path.normcase(ext) != ".py":
             return []
         try:
-            dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
+            tree = pyclbr.readmodule_ex(name, [dir] + sys.path)
         except ImportError:
             return []
-        items = []
-        self.classes = {}
-        for key, cl in dict.items():
-            if cl.module == name:
-                s = key
-                if hasattr(cl, 'super') and cl.super:
-                    supers = []
-                    for sup in cl.super:
-                        if type(sup) is type(''):
-                            sname = sup
-                        else:
-                            sname = sup.name
-                            if sup.module != cl.module:
-                                sname = "%s.%s" % (sup.module, sname)
-                        supers.append(sname)
-                    s = s + "(%s)" % ", ".join(supers)
-                items.append((cl.lineno, s))
-                self.classes[s] = cl
-        items.sort()
-        list = []
-        for item, s in items:
-            list.append(s)
-        return list
-
-class ClassBrowserTreeItem(TreeItem):
-    """Browser tree for classes within a module.
+        return transform_children(tree, name)
+
+
+class ChildBrowserTreeItem(TreeItem):
+    """Browser tree for child nodes within the module.
 
     Uses TreeItem as the basis for the structure of the tree.
     """
 
-    def __init__(self, name, classes, file):
-        """Create a TreeItem for the class/function.
-
-        Args:
-            name: Name of the class/function.
-            classes: Dictonary of Class/Function instances from pyclbr.
-            file: Full path and module name.
-
-        Instance variables:
-            self.cl: Class/Function instance for the class/function name.
-            self.isfunction: True if self.cl is a Function.
-        """
-        self.name = name
-        # XXX - Does classes need to be an instance variable?
-        self.classes = classes
-        self.file = file
-        try:
-            self.cl = self.classes[self.name]
-        except (IndexError, KeyError):
-            self.cl = None
-        self.isfunction = isinstance(self.cl, pyclbr.Function)
+    def __init__(self, obj):
+        "Create a TreeItem for a pyclbr class/function object."
+        self.obj = obj
+        self.name = obj.name
+        self.isfunction = isinstance(obj, pyclbr.Function)
 
     def GetText(self):
         "Return the name of the function/class to display."
+        name = self.name
         if self.isfunction:
-            return "def " + self.name + "(...)"
+            return "def " + name + "(...)"
         else:
-            return "class " + self.name
+            return "class " + name
 
     def GetIconName(self):
         "Return the name of the icon to display."
@@ -224,102 +211,38 @@ class ClassBrowserTreeItem(TreeItem):
             return "folder"
 
     def IsExpandable(self):
-        "Return True if this class has methods."
-        if self.cl:
-            try:
-                return not not self.cl.methods
-            except AttributeError:
-                return False
-        return None
+        "Return True if self.obj has nested objects."
+        return self.obj.children != {}
 
     def GetSubList(self):
-        """Return Class methods as a list of MethodBrowserTreeItem items.
-
-        Each item is a method within the class.
-        """
-        if not self.cl:
-            return []
-        sublist = []
-        for name in self.listmethods():
-            item = MethodBrowserTreeItem(name, self.cl, self.file)
-            sublist.append(item)
-        return sublist
+        "Return ChildBrowserTreeItems for children."
+        return [ChildBrowserTreeItem(obj)
+                for obj in transform_children(self.obj.children)]
 
     def OnDoubleClick(self):
-        "Open module with file_open and position to lineno, if it exists."
-        if not os.path.exists(self.file):
-            return
-        edit = file_open(self.file)
-        if hasattr(self.cl, 'lineno'):
-            lineno = self.cl.lineno
-            edit.gotoline(lineno)
-
-    def listmethods(self):
-        "Return list of methods within a class sorted by lineno."
-        if not self.cl:
-            return []
-        items = []
-        for name, lineno in self.cl.methods.items():
-            items.append((lineno, name))
-        items.sort()
-        list = []
-        for item, name in items:
-            list.append(name)
-        return list
-
-class MethodBrowserTreeItem(TreeItem):
-    """Browser tree for methods within a class.
-
-    Uses TreeItem as the basis for the structure of the tree.
-    """
-
-    def __init__(self, name, cl, file):
-        """Create a TreeItem for the methods.
-
-        Args:
-            name: Name of the class/function.
-            cl: pyclbr.Class instance for name.
-            file: Full path and module name.
-        """
-        self.name = name
-        self.cl = cl
-        self.file = file
-
-    def GetText(self):
-        "Return the method name to display."
-        return "def " + self.name + "(...)"
-
-    def GetIconName(self):
-        "Return the name of the icon to display."
-        return "python"
-
-    def IsExpandable(self):
-        "Return False as there are no tree items after methods."
-        return False
+        "Open module with file_open and position to lineno."
+        try:
+            edit = file_open(self.obj.file)
+            edit.gotoline(self.obj.lineno)
+        except (OSError, AttributeError):
+            pass
 
-    def OnDoubleClick(self):
-        "Open module with file_open and position at the method start."
-        if not os.path.exists(self.file):
-            return
-        edit = file_open(self.file)
-        edit.gotoline(self.cl.methods[self.name])
 
-def _class_browser(parent): # htest #
-    try:
+def _module_browser(parent): # htest #
+    if len(sys.argv) > 1:  # If pass file on command line.
+        file = sys.argv[1]
+    else:
         file = __file__
-    except NameError:
-        file = sys.argv[0]
-        if sys.argv[1:]:
-            file = sys.argv[1]
-        else:
-            file = sys.argv[0]
-    dir, file = os.path.split(file)
-    name = os.path.splitext(file)[0]
-    flist = pyshell.PyShellFileList(parent)
-    global file_open
-    file_open = flist.open
-    ClassBrowser(flist, name, [dir], _htest=True)
+        # Add nested objects for htest.
+        class Nested_in_func(TreeNode):
+            def nested_in_class(): pass
+        def closure():
+            class Nested_in_closure: pass
+    ModuleBrowser(parent, file, _htest=True)
 
 if __name__ == "__main__":
+    if len(sys.argv) == 1:  # If pass file on command line, unittest fails.
+        from unittest import main
+        main('idlelib.idle_test.test_browser', verbosity=2, exit=False)
     from idlelib.idle_test.htest import run
-    run(_class_browser)
+    run(_module_browser)
index 5556b767964739edbf609a824604be0200610d92..3a865f869a06c4d9f6d78881f354bf402e97919e 100644 (file)
@@ -14,7 +14,7 @@ class GetKeysDialog(Toplevel):
     keyerror_title = 'Key Sequence Error'
 
     def __init__(self, parent, title, action, currentKeySequences,
-                 _htest=False, _utest=False):
+                 *, _htest=False, _utest=False):
         """
         action - string, the name of the virtual event these keys will be
                  mapped to
index 0f530c66a111d65ec63da8082fa8344a1213c78c..4e8394be928112bb3c9b6aa09c6af4a70c46ca89 100644 (file)
@@ -11,7 +11,7 @@ Refer to comments in EditorWindow autoindent code for details.
 """
 from tkinter import (Toplevel, Listbox, Text, Scale, Canvas,
                      StringVar, BooleanVar, IntVar, TRUE, FALSE,
-                     TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE, NORMAL, DISABLED,
+                     TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE,
                      NONE, BOTH, X, Y, W, E, EW, NS, NSEW, NW,
                      HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END)
 from tkinter.ttk import (Button, Checkbutton, Entry, Frame, Label, LabelFrame,
@@ -25,7 +25,6 @@ from idlelib.config_key import GetKeysDialog
 from idlelib.dynoption import DynOptionMenu
 from idlelib import macosx
 from idlelib.query import SectionName, HelpSource
-from idlelib.tabbedpages import TabbedPageSet
 from idlelib.textview import view_text
 from idlelib.autocomplete import AutoComplete
 from idlelib.codecontext import CodeContext
@@ -41,7 +40,7 @@ class ConfigDialog(Toplevel):
     """Config dialog for IDLE.
     """
 
-    def __init__(self, parent, title='', _htest=False, _utest=False):
+    def __init__(self, parent, title='', *, _htest=False, _utest=False):
         """Show the tabbed dialog for user configuration.
 
         Args:
@@ -105,7 +104,7 @@ class ConfigDialog(Toplevel):
             load_configs: Load pages except for extensions.
             activate_config_changes: Tell editors to reload.
         """
-        self.note = note = Notebook(self, width=450, height=450)
+        self.note = note = Notebook(self)
         self.highpage = HighPage(note)
         self.fontpage = FontPage(note, self.highpage)
         self.keyspage = KeysPage(note)
@@ -189,6 +188,11 @@ class ConfigDialog(Toplevel):
         """
         self.destroy()
 
+    def destroy(self):
+        global font_sample_text
+        font_sample_text = self.fontpage.font_sample.get('1.0', 'end')
+        super().destroy()
+
     def help(self):
         """Create textview for config dialog help.
 
@@ -429,6 +433,35 @@ class ConfigDialog(Toplevel):
 #     def other_methods():
 #         # Define tab-specific behavior.
 
+font_sample_text = (
+    '<ASCII/Latin1>\n'
+    'AaBbCcDdEeFfGgHhIiJj\n1234567890#:+=(){}[]\n'
+    '\u00a2\u00a3\u00a5\u00a7\u00a9\u00ab\u00ae\u00b6\u00bd\u011e'
+    '\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c7\u00d0\u00d8\u00df\n'
+    '\n<IPA,Greek,Cyrillic>\n'
+    '\u0250\u0255\u0258\u025e\u025f\u0264\u026b\u026e\u0270\u0277'
+    '\u027b\u0281\u0283\u0286\u028e\u029e\u02a2\u02ab\u02ad\u02af\n'
+    '\u0391\u03b1\u0392\u03b2\u0393\u03b3\u0394\u03b4\u0395\u03b5'
+    '\u0396\u03b6\u0397\u03b7\u0398\u03b8\u0399\u03b9\u039a\u03ba\n'
+    '\u0411\u0431\u0414\u0434\u0416\u0436\u041f\u043f\u0424\u0444'
+    '\u0427\u0447\u042a\u044a\u042d\u044d\u0460\u0464\u046c\u04dc\n'
+    '\n<Hebrew, Arabic>\n'
+    '\u05d0\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9'
+    '\u05da\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\n'
+    '\u0627\u0628\u062c\u062f\u0647\u0648\u0632\u062d\u0637\u064a'
+    '\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\n'
+    '\n<Devanagari, Tamil>\n'
+    '\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f'
+    '\u0905\u0906\u0907\u0908\u0909\u090a\u090f\u0910\u0913\u0914\n'
+    '\u0be6\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef'
+    '\u0b85\u0b87\u0b89\u0b8e\n'
+    '\n<East Asian>\n'
+    '\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\n'
+    '\u6c49\u5b57\u6f22\u5b57\u4eba\u6728\u706b\u571f\u91d1\u6c34\n'
+    '\uac00\ub0d0\ub354\ub824\ubaa8\ubd64\uc218\uc720\uc988\uce58\n'
+    '\u3042\u3044\u3046\u3048\u304a\u30a2\u30a4\u30a6\u30a8\u30aa\n'
+    )
+
 
 class FontPage(Frame):
 
@@ -479,8 +512,8 @@ class FontPage(Frame):
                     font_size_title: Label
                     (*)sizelist: DynOptionMenu - font_size
                     (*)bold_toggle: Checkbutton - font_bold
-                frame_font_sample: Frame
-                    (*)font_sample: Label
+            frame_sample: LabelFrame
+                (*)font_sample: Label
             frame_indent: LabelFrame
                     indent_title: Label
                     (*)indent_scale: Scale - space_num
@@ -490,10 +523,12 @@ class FontPage(Frame):
         self.font_bold = tracers.add(BooleanVar(self), self.var_changed_font)
         self.space_num = tracers.add(IntVar(self), ('main', 'Indent', 'num-spaces'))
 
-        # Create widgets:
-        # body and body section frames.
+        # Define frames and widgets.
         frame_font = LabelFrame(
-                self, borderwidth=2, relief=GROOVE, text=' Base Editor Font ')
+                self, borderwidth=2, relief=GROOVE, text=' Shell/Editor Font ')
+        frame_sample = LabelFrame(
+                self, borderwidth=2, relief=GROOVE,
+                text=' Font Sample (Editable) ')
         frame_indent = LabelFrame(
                 self, borderwidth=2, relief=GROOVE, text=' Indentation Width ')
         # frame_font.
@@ -501,7 +536,7 @@ class FontPage(Frame):
         frame_font_param = Frame(frame_font)
         font_name_title = Label(
                 frame_font_name, justify=LEFT, text='Font Face :')
-        self.fontlist = Listbox(frame_font_name, height=5,
+        self.fontlist = Listbox(frame_font_name, height=15,
                                 takefocus=True, exportselection=FALSE)
         self.fontlist.bind('<ButtonRelease-1>', self.on_fontlist_select)
         self.fontlist.bind('<KeyRelease-Up>', self.on_fontlist_select)
@@ -514,11 +549,9 @@ class FontPage(Frame):
         self.bold_toggle = Checkbutton(
                 frame_font_param, variable=self.font_bold,
                 onvalue=1, offvalue=0, text='Bold')
-        frame_font_sample = Frame(frame_font, relief=SOLID, borderwidth=1)
-        temp_font = tkFont.Font(self, ('courier', 10, 'normal'))
-        self.font_sample = Label(
-                frame_font_sample, justify=LEFT, font=temp_font,
-                text='AaBbCcDdEe\nFfGgHhIiJj\n1234567890\n#:+=(){}[]')
+        # frame_sample.
+        self.font_sample = Text(frame_sample, width=20, height=20)
+        self.font_sample.insert(END, font_sample_text)
         # frame_indent.
         indent_title = Label(
                 frame_indent, justify=LEFT,
@@ -527,10 +560,12 @@ class FontPage(Frame):
                 frame_indent, variable=self.space_num,
                 orient='horizontal', tickinterval=2, from_=2, to=16)
 
-        # Pack widgets:
-        # body.
-        frame_font.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
-        frame_indent.pack(side=LEFT, padx=5, pady=5, fill=Y)
+        # Grid and pack widgets:
+        self.columnconfigure(1, weight=1)
+        frame_font.grid(row=0, column=0, padx=5, pady=5)
+        frame_sample.grid(row=0, column=1, rowspan=2, padx=5, pady=5,
+                          sticky='nsew')
+        frame_indent.grid(row=1, column=0, padx=5, pady=5, sticky='ew')
         # frame_font.
         frame_font_name.pack(side=TOP, padx=5, pady=5, fill=X)
         frame_font_param.pack(side=TOP, padx=5, pady=5, fill=X)
@@ -540,10 +575,9 @@ class FontPage(Frame):
         font_size_title.pack(side=LEFT, anchor=W)
         self.sizelist.pack(side=LEFT, anchor=W)
         self.bold_toggle.pack(side=LEFT, anchor=W, padx=20)
-        frame_font_sample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
+        # frame_sample.
         self.font_sample.pack(expand=TRUE, fill=BOTH)
         # frame_indent.
-        frame_indent.pack(side=TOP, fill=X)
         indent_title.pack(side=TOP, anchor=W, padx=5)
         self.indent_scale.pack(side=TOP, padx=5, fill=X)
 
@@ -1408,7 +1442,7 @@ class KeysPage(Frame):
         self.bindingslist['xscrollcommand'] = scroll_target_x.set
         self.button_new_keys = Button(
                 frame_custom, text='Get New Keys for Selection',
-                command=self.get_new_keys, state=DISABLED)
+                command=self.get_new_keys, state='disabled')
         # frame_key_sets.
         frames = [Frame(frame_key_sets, padding=2, borderwidth=0)
                   for i in range(2)]
@@ -2108,10 +2142,26 @@ When you click either the Apply or Ok buttons, settings in this
 dialog that are different from IDLE's default are saved in
 a .idlerc directory in your home directory. Except as noted,
 these changes apply to all versions of IDLE installed on this
-machine. Some do not take affect until IDLE is restarted.
-[Cancel] only cancels changes made since the last save.
+machine. [Cancel] only cancels changes made since the last save.
 '''
 help_pages = {
+    'Fonts/Tabs':'''
+Font sample: This shows what a selection of Basic Multilingual Plane
+unicode characters look like for the current font selection.  If the
+selected font does not define a character, Tk attempts to find another
+font that does.  Substitute glyphs depend on what is available on a
+particular system and will not necessarily have the same size as the
+font selected.  Line contains 20 characters up to Devanagari, 14 for
+Tamil, and 10 for East Asia.
+
+Hebrew and Arabic letters should display right to left, starting with
+alef, \u05d0 and \u0627.  Arabic digits display left to right.  The
+Devanagari and Tamil lines start with digits.  The East Asian lines
+are Chinese digits, Chinese Hanzi, Korean Hangul, and Japanese
+Hiragana and Katakana.
+
+You can edit the font sample. Changes remain until IDLE is closed.
+''',
     'Highlights': '''
 Highlighting:
 The IDLE Dark color theme is new in October 2015.  It can only
index 855d375055653acd101970515c853243706c63af..b51c45c97e50f2a3d3102416589e61674bc9d156 100644 (file)
@@ -99,10 +99,6 @@ class EditorWindow(object):
         self.flist = flist
         root = root or flist.root
         self.root = root
-        try:
-            sys.ps1
-        except AttributeError:
-            sys.ps1 = '>>> '
         self.menubar = Menu(root)
         self.top = top = windows.ListedToplevel(root, menu=self.menubar)
         if flist:
@@ -116,6 +112,8 @@ class EditorWindow(object):
             self.top.instance_dict = {}
         self.recent_files_path = os.path.join(
                 idleConf.userdir, 'recent-files.lst')
+
+        self.prompt_last_line = ''  # Override in PyShell
         self.text_frame = text_frame = Frame(top)
         self.vbar = vbar = Scrollbar(text_frame, name='vbar')
         self.width = idleConf.GetOption('main', 'EditorWindow',
@@ -190,7 +188,7 @@ class EditorWindow(object):
                 flist.dict[key] = self
             text.bind("<<open-new-window>>", self.new_callback)
             text.bind("<<close-all-windows>>", self.flist.close_all_callback)
-            text.bind("<<open-class-browser>>", self.open_class_browser)
+            text.bind("<<open-class-browser>>", self.open_module_browser)
             text.bind("<<open-path-browser>>", self.open_path_browser)
             text.bind("<<open-turtle-demo>>", self.open_turtle_demo)
 
@@ -632,10 +630,10 @@ class EditorWindow(object):
     def open_module(self):
         """Get module name from user and open it.
 
-        Return module path or None for calls by open_class_browser
+        Return module path or None for calls by open_module_browser
         when latter is not invoked in named editor window.
         """
-        # XXX This, open_class_browser, and open_path_browser
+        # XXX This, open_module_browser, and open_path_browser
         # would fit better in iomenu.IOBinding.
         try:
             name = self.text.get("sel.first", "sel.last").strip()
@@ -657,22 +655,20 @@ class EditorWindow(object):
         self.open_module()
         return "break"
 
-    def open_class_browser(self, event=None):
+    def open_module_browser(self, event=None):
         filename = self.io.filename
         if not (self.__class__.__name__ == 'PyShellEditorWindow'
                 and filename):
             filename = self.open_module()
             if filename is None:
                 return "break"
-        head, tail = os.path.split(filename)
-        base, ext = os.path.splitext(tail)
         from idlelib import browser
-        browser.ClassBrowser(self.flist, base, [head])
+        browser.ModuleBrowser(self.root, filename)
         return "break"
 
     def open_path_browser(self, event=None):
         from idlelib import pathbrowser
-        pathbrowser.PathBrowser(self.flist)
+        pathbrowser.PathBrowser(self.root)
         return "break"
 
     def open_turtle_demo(self, event = None):
@@ -1215,13 +1211,9 @@ class EditorWindow(object):
         assert have > 0
         want = ((have - 1) // self.indentwidth) * self.indentwidth
         # Debug prompt is multilined....
-        if self.context_use_ps1:
-            last_line_of_prompt = sys.ps1.split('\n')[-1]
-        else:
-            last_line_of_prompt = ''
         ncharsdeleted = 0
         while 1:
-            if chars == last_line_of_prompt:
+            if chars == self.prompt_last_line:  # '' unless PyShell
                 break
             chars = chars[:-1]
             ncharsdeleted = ncharsdeleted + 1
@@ -1290,8 +1282,7 @@ class EditorWindow(object):
             indent = line[:i]
             # strip whitespace before insert point unless it's in the prompt
             i = 0
-            last_line_of_prompt = sys.ps1.split('\n')[-1]
-            while line and line[-1] in " \t" and line != last_line_of_prompt:
+            while line and line[-1] in " \t" and line != self.prompt_last_line:
                 line = line[:-1]
                 i = i+1
             if i:
index f46ad7cd7e9e0e7bd101c209561cc71bc7879b91..5e1a3dcd77dc67ba09097a5fe65c7f86680c8055 100644 (file)
@@ -113,8 +113,10 @@ class FileList:
 
 def _test():
     from idlelib.editor import fixwordbreaks
+    from idlelib.run import fix_scaling
     import sys
     root = Tk()
+    fix_scaling(root)
     fixwordbreaks(root)
     root.withdraw()
     flist = FileList(root)
index 679ac78d32db9584f5f3129102091387f66dbe7c..77b4b18962066ca25a77b7606159c98e16c8fa10 100644 (file)
@@ -23,7 +23,7 @@ class AboutDialog(Toplevel):
     """Modal about dialog for idle
 
     """
-    def __init__(self, parent, title=None, _htest=False, _utest=False):
+    def __init__(self, parent, title=None, *, _htest=False, _utest=False):
         """Create popup, do not return until tk widget destroyed.
 
         parent - parent of this dialog
index c580fb9e79352afbfc030c3f882515a21c05b2cc..5f3678fc7e1de31c13774389db8e24ab77f3e5c9 100644 (file)
@@ -144,9 +144,18 @@ green. Idle tests must not disturb the environment in a way that makes
 other tests fail (issue 18081).
 
 To run an individual Testcase or test method, extend the dotted name
-given to unittest on the command line.
+given to unittest on the command line or use the test -m option.  The
+latter allows use of other regrtest options.  When using the latter,
+all components of the pattern must be present, but any can be replaced
+by '*'.
 
 python -m unittest -v idlelib.idle_test.test_xyz.Test_case.test_meth
+python -m test -m idlelib.idle_test.text_xyz.Test_case.test_meth test_idle
+
+The test suite can be run in an IDLE user process from Shell.
+>>> import test.autotest  # Issue 25588, 2017/10/13, 3.6.4, 3.7.0a2.
+There are currently failures not usually present, and this does not
+work when run from the editor.
 
 
 4. Human-mediated Tests
index e483bbc93a2b054da8cceb2276c7881351dcf5bf..442f55e283a484e02e411937229d792c61945bb7 100644 (file)
@@ -86,7 +86,7 @@ _calltip_window_spec = {
            "Typing ') should hide the calltip.\n"
     }
 
-_class_browser_spec = {
+_module_browser_spec = {
     'file': 'browser',
     'kwds': {},
     'msg': "Inspect names of module, class(with superclass if "
diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py
new file mode 100644 (file)
index 0000000..05eb471
--- /dev/null
@@ -0,0 +1,253 @@
+""" Test idlelib.browser.
+
+Coverage: 88%
+(Higher, because should exclude 3 lines that .coveragerc won't exclude.)
+"""
+
+from collections import deque
+import os.path
+from idlelib import _pyclbr as pyclbr
+from tkinter import Tk
+
+from test.support import requires
+import unittest
+from unittest import mock
+from idlelib.idle_test.mock_idle import Func
+
+from idlelib import browser
+from idlelib import filelist
+from idlelib.tree import TreeNode
+
+
+class ModuleBrowserTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.mb = browser.ModuleBrowser(cls.root, __file__, _utest=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.mb.close()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root, cls.mb
+
+    def test_init(self):
+        mb = self.mb
+        eq = self.assertEqual
+        eq(mb.path, __file__)
+        eq(pyclbr._modules, {})
+        self.assertIsInstance(mb.node, TreeNode)
+        self.assertIsNotNone(browser.file_open)
+
+    def test_settitle(self):
+        mb = self.mb
+        self.assertIn(os.path.basename(__file__), mb.top.title())
+        self.assertEqual(mb.top.iconname(), 'Module Browser')
+
+    def test_rootnode(self):
+        mb = self.mb
+        rn = mb.rootnode()
+        self.assertIsInstance(rn, browser.ModuleBrowserTreeItem)
+
+    def test_close(self):
+        mb = self.mb
+        mb.top.destroy = Func()
+        mb.node.destroy = Func()
+        mb.close()
+        self.assertTrue(mb.top.destroy.called)
+        self.assertTrue(mb.node.destroy.called)
+        del mb.top.destroy, mb.node.destroy
+
+
+# Nested tree same as in test_pyclbr.py except for supers on C0. C1.
+mb = pyclbr
+module, fname = 'test', 'test.py'
+f0 = mb.Function(module, 'f0', fname, 1)
+f1 = mb._nest_function(f0, 'f1', 2)
+f2 = mb._nest_function(f1, 'f2', 3)
+c1 = mb._nest_class(f0, 'c1', 5)
+C0 = mb.Class(module, 'C0', ['base'], fname, 6)
+F1 = mb._nest_function(C0, 'F1', 8)
+C1 = mb._nest_class(C0, 'C1', 11, [''])
+C2 = mb._nest_class(C1, 'C2', 12)
+F3 = mb._nest_function(C2, 'F3', 14)
+mock_pyclbr_tree = {'f0': f0, 'C0': C0}
+
+# Adjust C0.name, C1.name so tests do not depend on order.
+browser.transform_children(mock_pyclbr_tree, 'test')  # C0(base)
+browser.transform_children(C0.children)  # C1()
+
+# The class below checks that the calls above are correct
+# and that duplicate calls have no effect.
+
+
+class TransformChildrenTest(unittest.TestCase):
+
+    def test_transform_module_children(self):
+        eq = self.assertEqual
+        transform = browser.transform_children
+        # Parameter matches tree module.
+        tcl = list(transform(mock_pyclbr_tree, 'test'))
+        eq(tcl, [f0, C0])
+        eq(tcl[0].name, 'f0')
+        eq(tcl[1].name, 'C0(base)')
+        # Check that second call does not change suffix.
+        tcl = list(transform(mock_pyclbr_tree, 'test'))
+        eq(tcl[1].name, 'C0(base)')
+        # Nothing to traverse if parameter name isn't same as tree module.
+        tcl = list(transform(mock_pyclbr_tree, 'different name'))
+        eq(tcl, [])
+
+    def test_transform_node_children(self):
+        eq = self.assertEqual
+        transform = browser.transform_children
+        # Class with two children, one name altered.
+        tcl = list(transform(C0.children))
+        eq(tcl, [F1, C1])
+        eq(tcl[0].name, 'F1')
+        eq(tcl[1].name, 'C1()')
+        tcl = list(transform(C0.children))
+        eq(tcl[1].name, 'C1()')
+        # Function with two children.
+        eq(list(transform(f0.children)), [f1, c1])
+
+
+class ModuleBrowserTreeItemTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.mbt = browser.ModuleBrowserTreeItem(fname)
+
+    def test_init(self):
+        self.assertEqual(self.mbt.file, fname)
+
+    def test_gettext(self):
+        self.assertEqual(self.mbt.GetText(), fname)
+
+    def test_geticonname(self):
+        self.assertEqual(self.mbt.GetIconName(), 'python')
+
+    def test_isexpandable(self):
+        self.assertTrue(self.mbt.IsExpandable())
+
+    def test_listchildren(self):
+        save_rex = browser.pyclbr.readmodule_ex
+        save_tc = browser.transform_children
+        browser.pyclbr.readmodule_ex = Func(result=mock_pyclbr_tree)
+        browser.transform_children = Func(result=[f0, C0])
+        try:
+            self.assertEqual(self.mbt.listchildren(), [f0, C0])
+        finally:
+            browser.pyclbr.readmodule_ex = save_rex
+            browser.transform_children = save_tc
+
+    def test_getsublist(self):
+        mbt = self.mbt
+        mbt.listchildren = Func(result=[f0, C0])
+        sub0, sub1 = mbt.GetSubList()
+        del mbt.listchildren
+        self.assertIsInstance(sub0, browser.ChildBrowserTreeItem)
+        self.assertIsInstance(sub1, browser.ChildBrowserTreeItem)
+        self.assertEqual(sub0.name, 'f0')
+        self.assertEqual(sub1.name, 'C0(base)')
+
+    @mock.patch('idlelib.browser.file_open')
+    def test_ondoubleclick(self, fopen):
+        mbt = self.mbt
+
+        with mock.patch('os.path.exists', return_value=False):
+            mbt.OnDoubleClick()
+            fopen.assert_not_called()
+
+        with mock.patch('os.path.exists', return_value=True):
+            mbt.OnDoubleClick()
+            fopen.assert_called()
+            fopen.called_with(fname)
+
+
+class ChildBrowserTreeItemTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        CBT = browser.ChildBrowserTreeItem
+        cls.cbt_f1 = CBT(f1)
+        cls.cbt_C1 = CBT(C1)
+        cls.cbt_F1 = CBT(F1)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.cbt_C1, cls.cbt_f1, cls.cbt_F1
+
+    def test_init(self):
+        eq = self.assertEqual
+        eq(self.cbt_C1.name, 'C1()')
+        self.assertFalse(self.cbt_C1.isfunction)
+        eq(self.cbt_f1.name, 'f1')
+        self.assertTrue(self.cbt_f1.isfunction)
+
+    def test_gettext(self):
+        self.assertEqual(self.cbt_C1.GetText(), 'class C1()')
+        self.assertEqual(self.cbt_f1.GetText(), 'def f1(...)')
+
+    def test_geticonname(self):
+        self.assertEqual(self.cbt_C1.GetIconName(), 'folder')
+        self.assertEqual(self.cbt_f1.GetIconName(), 'python')
+
+    def test_isexpandable(self):
+        self.assertTrue(self.cbt_C1.IsExpandable())
+        self.assertTrue(self.cbt_f1.IsExpandable())
+        self.assertFalse(self.cbt_F1.IsExpandable())
+
+    def test_getsublist(self):
+        eq = self.assertEqual
+        CBT = browser.ChildBrowserTreeItem
+
+        f1sublist = self.cbt_f1.GetSubList()
+        self.assertIsInstance(f1sublist[0], CBT)
+        eq(len(f1sublist), 1)
+        eq(f1sublist[0].name, 'f2')
+
+        eq(self.cbt_F1.GetSubList(), [])
+
+    @mock.patch('idlelib.browser.file_open')
+    def test_ondoubleclick(self, fopen):
+        goto = fopen.return_value.gotoline = mock.Mock()
+        self.cbt_F1.OnDoubleClick()
+        fopen.assert_called()
+        goto.assert_called()
+        goto.assert_called_with(self.cbt_F1.obj.lineno)
+        # Failure test would have to raise OSError or AttributeError.
+
+
+class NestedChildrenTest(unittest.TestCase):
+    "Test that all the nodes in a nested tree are added to the BrowserTree."
+
+    def test_nested(self):
+        queue = deque()
+        actual_names = []
+        # The tree items are processed in breadth first order.
+        # Verify that processing each sublist hits every node and
+        # in the right order.
+        expected_names = ['f0', 'C0(base)',
+                          'f1', 'c1', 'F1', 'C1()',
+                          'f2', 'C2',
+                          'F3']
+        CBT = browser.ChildBrowserTreeItem
+        queue.extend((CBT(f0), CBT(C0)))
+        while queue:
+            cb = queue.popleft()
+            sublist = cb.GetSubList()
+            queue.extend(sublist)
+            self.assertIn(cb.name, cb.GetText())
+            self.assertIn(cb.GetIconName(), ('python', 'folder'))
+            self.assertIs(cb.IsExpandable(), sublist != [])
+            actual_names.append(cb.name)
+        self.assertEqual(actual_names, expected_names)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
index dc7f69c2af86b26fbc4be90710bfb4325e39897b..982dc0b7eff7e13a4b18b805770dc8b03769dd7d 100644 (file)
@@ -44,10 +44,9 @@ def tearDownModule():
     tracers.detach()
     tracers.clear()
     changes.clear()
-    del dialog
     root.update_idletasks()
     root.destroy()
-    del root
+    root = dialog = None
 
 
 class FontPageTest(unittest.TestCase):
@@ -192,6 +191,7 @@ class FontPageTest(unittest.TestCase):
     def test_set_samples(self):
         d = self.page
         del d.set_samples  # Unmask method for test
+        orig_samples = d.font_sample, d.highlight_sample
         d.font_sample, d.highlight_sample = {}, {}
         d.font_name.set('test')
         d.font_size.set('5')
@@ -202,7 +202,7 @@ class FontPageTest(unittest.TestCase):
         d.set_samples()
         self.assertTrue(d.font_sample == d.highlight_sample == expected)
 
-        del d.font_sample, d.highlight_sample
+        d.font_sample, d.highlight_sample = orig_samples
         d.set_samples = Func()  # Re-mask for other tests.
 
 
index 813cbcc63167ccba261b13cf21e73c8352ab1a2d..74b716a3199327a10e6b2bcf06f1fc56f600b050 100644 (file)
@@ -1,11 +1,68 @@
+""" Test idlelib.pathbrowser.
+"""
+
+
+import os.path
+import pyclbr  # for _modules
+import sys  # for sys.path
+from tkinter import Tk
+
+from test.support import requires
 import unittest
-import os
-import sys
-import idlelib
+from idlelib.idle_test.mock_idle import Func
+
+import idlelib  # for __file__
+from idlelib import browser
 from idlelib import pathbrowser
+from idlelib.tree import TreeNode
+
 
 class PathBrowserTest(unittest.TestCase):
 
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.pb = pathbrowser.PathBrowser(cls.root, _utest=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.pb.close()
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root, cls.pb
+
+    def test_init(self):
+        pb = self.pb
+        eq = self.assertEqual
+        eq(pb.master, self.root)
+        eq(pyclbr._modules, {})
+        self.assertIsInstance(pb.node, TreeNode)
+        self.assertIsNotNone(browser.file_open)
+
+    def test_settitle(self):
+        pb = self.pb
+        self.assertEqual(pb.top.title(), 'Path Browser')
+        self.assertEqual(pb.top.iconname(), 'Path Browser')
+
+    def test_rootnode(self):
+        pb = self.pb
+        rn = pb.rootnode()
+        self.assertIsInstance(rn, pathbrowser.PathBrowserTreeItem)
+
+    def test_close(self):
+        pb = self.pb
+        pb.top.destroy = Func()
+        pb.node.destroy = Func()
+        pb.close()
+        self.assertTrue(pb.top.destroy.called)
+        self.assertTrue(pb.node.destroy.called)
+        del pb.top.destroy, pb.node.destroy
+
+
+class DirBrowserTreeItemTest(unittest.TestCase):
+
     def test_DirBrowserTreeItem(self):
         # Issue16226 - make sure that getting a sublist works
         d = pathbrowser.DirBrowserTreeItem('')
@@ -16,6 +73,9 @@ class PathBrowserTest(unittest.TestCase):
         self.assertEqual(d.ispackagedir(dir), True)
         self.assertEqual(d.ispackagedir(dir + '/Icons'), False)
 
+
+class PathBrowserTreeItemTest(unittest.TestCase):
+
     def test_PathBrowserTreeItem(self):
         p = pathbrowser.PathBrowserTreeItem()
         self.assertEqual(p.GetText(), 'sys.path')
@@ -23,5 +83,6 @@ class PathBrowserTest(unittest.TestCase):
         self.assertEqual(len(sub), len(sys.path))
         self.assertEqual(type(sub[0]), pathbrowser.DirBrowserTreeItem)
 
+
 if __name__ == '__main__':
     unittest.main(verbosity=2, exit=False)
index 2ecbd34168c54e8196dc7cedaba792c778c4dba0..df76dec3e6276d28aec99c99e3e00ab9e33c4f2e 100644 (file)
@@ -74,14 +74,14 @@ class ReplaceDialogTest(unittest.TestCase):
         replace()
         equal(text.get('1.8', '1.12'), 'asdf')
 
-        # dont "match word" case
+        # don't "match word" case
         text.mark_set('insert', '1.0')
         pv.set('is')
         rv.set('hello')
         replace()
         equal(text.get('1.2', '1.7'), 'hello')
 
-        # dont "match case" case
+        # don't "match case" case
         pv.set('string')
         rv.set('world')
         replace()
diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py
new file mode 100644 (file)
index 0000000..d7e627d
--- /dev/null
@@ -0,0 +1,35 @@
+import unittest
+from unittest import mock
+
+from test.support import captured_stderr
+import idlelib.run as idlerun
+
+
+class RunTest(unittest.TestCase):
+    def test_print_exception_unhashable(self):
+        class UnhashableException(Exception):
+            def __eq__(self, other):
+                return True
+
+        ex1 = UnhashableException('ex1')
+        ex2 = UnhashableException('ex2')
+        try:
+            raise ex2 from ex1
+        except UnhashableException:
+            try:
+                raise ex1
+            except UnhashableException:
+                with captured_stderr() as output:
+                    with mock.patch.object(idlerun,
+                                           'cleanup_traceback') as ct:
+                        ct.side_effect = lambda t, e: t
+                        idlerun.print_exception()
+
+        tb = output.getvalue().strip().splitlines()
+        self.assertEqual(11, len(tb))
+        self.assertIn('UnhashableException: ex2', tb[3])
+        self.assertIn('UnhashableException: ex1', tb[10])
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
index 3414c7b3aff4b39440a710b7841ccb89de043843..f9b6907b40cecc062de391e7ac3d9380b378dc96 100644 (file)
@@ -487,11 +487,11 @@ class IOBinding:
     opendialog = None
     savedialog = None
 
-    filetypes = [
+    filetypes = (
         ("Python files", "*.py *.pyw", "TEXT"),
         ("Text files", "*.txt", "TEXT"),
         ("All files", "*"),
-        ]
+        )
 
     defaultextension = '.py' if sys.platform == 'darwin' else ''
 
index d1dcb83d9324f46a4fd5b39ef382ff75a505d6ed..143570d6b11c416abbce33e202c4299525d53f30 100644 (file)
@@ -25,7 +25,7 @@ menudefs = [
    ('_New File', '<<open-new-window>>'),
    ('_Open...', '<<open-window-from-file>>'),
    ('Open _Module...', '<<open-module>>'),
-   ('Class _Browser', '<<open-class-browser>>'),
+   ('Module _Browser', '<<open-class-browser>>'),
    ('_Path Browser', '<<open-path-browser>>'),
    None,
    ('_Save', '<<save-window>>'),
index cf8dfdb641f69dcf374ee58b8c29e3fe9fa470df..1270115a44ce44be308dc82217845728a892eaf0 100644 (file)
@@ -158,7 +158,7 @@ def reformat_comment(data, limit, comment_header):
     newdata = reformat_paragraph(data, format_width)
     # re-split and re-insert the comment header.
     newdata = newdata.split("\n")
-    # If the block ends in a \n, we dont want the comment prefix
+    # If the block ends in a \n, we don't want the comment prefix
     # inserted after it. (Im not sure it makes sense to reformat a
     # comment block that is not made of complete lines, but whatever!)
     # Can't think of a clean solution, so we hack away
index 6c19508d314d8f654d5884bee3d3a7364745baef..6de242d0000beddfcd657d6717c3d5cd60faf1d5 100644 (file)
@@ -2,19 +2,20 @@ import importlib.machinery
 import os
 import sys
 
-from idlelib.browser import ClassBrowser, ModuleBrowserTreeItem
-from idlelib.pyshell import PyShellFileList
+from idlelib.browser import ModuleBrowser, ModuleBrowserTreeItem
 from idlelib.tree import TreeItem
 
 
-class PathBrowser(ClassBrowser):
+class PathBrowser(ModuleBrowser):
 
-    def __init__(self, flist, _htest=False):
+    def __init__(self, master, *, _htest=False, _utest=False):
         """
         _htest - bool, change box location when running htest
         """
+        self.master = master
         self._htest = _htest
-        self.init(flist)
+        self._utest = _utest
+        self.init()
 
     def settitle(self):
         "Set window titles."
@@ -99,8 +100,7 @@ class DirBrowserTreeItem(TreeItem):
 
 
 def _path_browser(parent):  # htest #
-    flist = PyShellFileList(parent)
-    PathBrowser(flist, _htest=True)
+    PathBrowser(parent, _htest=True)
     parent.mainloop()
 
 if __name__ == "__main__":
index 47df74433cf87ac9ab83d72f1f589b1201b0bc6b..8b07d52cc4872ad71aa87132de40316e64af5d17 100755 (executable)
@@ -12,6 +12,8 @@ import tkinter.messagebox as tkMessageBox
 if TkVersion < 8.5:
     root = Tk()  # otherwise create root in main
     root.withdraw()
+    from idlelib.run import fix_scaling
+    fix_scaling(root)
     tkMessageBox.showerror("Idle Cannot Start",
             "Idle requires tcl/tk 8.5+, not %s." % TkVersion,
             parent=root)
@@ -855,15 +857,17 @@ class PyShell(OutputWindow):
             fixwordbreaks(root)
             root.withdraw()
             flist = PyShellFileList(root)
-        #
+
         OutputWindow.__init__(self, flist, None, None)
-        #
-##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
+
         self.usetabs = True
         # indentwidth must be 8 when using tabs.  See note in EditorWindow:
         self.indentwidth = 8
-        self.context_use_ps1 = True
-        #
+
+        self.sys_ps1 = sys.ps1 if hasattr(sys, 'ps1') else '>>> '
+        self.prompt_last_line = self.sys_ps1.split('\n')[-1]
+        self.prompt = self.sys_ps1  # Changes when debug active
+
         text = self.text
         text.configure(wrap="char")
         text.bind("<<newline-and-indent>>", self.enter_callback)
@@ -876,7 +880,7 @@ class PyShell(OutputWindow):
         if use_subprocess:
             text.bind("<<view-restart>>", self.view_restart_mark)
             text.bind("<<restart-shell>>", self.restart_shell)
-        #
+
         self.save_stdout = sys.stdout
         self.save_stderr = sys.stderr
         self.save_stdin = sys.stdin
@@ -949,7 +953,7 @@ class PyShell(OutputWindow):
                 debugger_r.close_remote_debugger(self.interp.rpcclt)
             self.resetoutput()
             self.console.write("[DEBUG OFF]\n")
-            sys.ps1 = ">>> "
+            self.prompt = self.sys_ps1
             self.showprompt()
         self.set_debugger_indicator()
 
@@ -961,7 +965,7 @@ class PyShell(OutputWindow):
             dbg_gui = debugger.Debugger(self)
         self.interp.setdebugger(dbg_gui)
         dbg_gui.load_breakpoints()
-        sys.ps1 = "[DEBUG ON]\n>>> "
+        self.prompt = "[DEBUG ON]\n" + self.sys_ps1
         self.showprompt()
         self.set_debugger_indicator()
 
@@ -1246,11 +1250,7 @@ class PyShell(OutputWindow):
 
     def showprompt(self):
         self.resetoutput()
-        try:
-            s = str(sys.ps1)
-        except:
-            s = ""
-        self.console.write(s)
+        self.console.write(self.prompt)
         self.text.mark_set("insert", "end-1c")
         self.set_line_and_column()
         self.io.reset_undo()
@@ -1457,6 +1457,8 @@ def main():
         NoDefaultRoot()
     root = Tk(className="Idle")
     root.withdraw()
+    from idlelib.run import fix_scaling
+    fix_scaling(root)
 
     # set application icon
     icondir = os.path.join(os.path.dirname(__file__), 'Icons')
index 9f6604bb0acc58bdde771f65e635f6afabb69395..176fe3db743bd4513d5a9eacbc5194506197553b 100644 (file)
@@ -134,13 +134,17 @@ def main(del_exitfunc=False):
                     # exiting but got an extra KBI? Try again!
                     continue
             try:
-                seq, request = rpc.request_queue.get(block=True, timeout=0.05)
+                request = rpc.request_queue.get(block=True, timeout=0.05)
             except queue.Empty:
+                request = None
+                # Issue 32207: calling handle_tk_events here adds spurious
+                # queue.Empty traceback to event handling exceptions.
+            if request:
+                seq, (method, args, kwargs) = request
+                ret = method(*args, **kwargs)
+                rpc.response_queue.put((seq, ret))
+            else:
                 handle_tk_events()
-                continue
-            method, args, kwargs = request
-            ret = method(*args, **kwargs)
-            rpc.response_queue.put((seq, ret))
         except KeyboardInterrupt:
             if quitting:
                 exit_now = True
@@ -184,6 +188,7 @@ def show_socket_error(err, address):
     import tkinter
     from tkinter.messagebox import showerror
     root = tkinter.Tk()
+    fix_scaling(root)
     root.withdraw()
     msg = f"IDLE's subprocess can't connect to {address[0]}:{address[1]}.\n"\
           f"Fatal OSError #{err.errno}: {err.strerror}.\n"\
@@ -202,16 +207,16 @@ def print_exception():
     seen = set()
 
     def print_exc(typ, exc, tb):
-        seen.add(exc)
+        seen.add(id(exc))
         context = exc.__context__
         cause = exc.__cause__
-        if cause is not None and cause not in seen:
+        if cause is not None and id(cause) not in seen:
             print_exc(type(cause), cause, cause.__traceback__)
             print("\nThe above exception was the direct cause "
                   "of the following exception:\n", file=efile)
         elif (context is not None and
               not exc.__suppress_context__ and
-              context not in seen):
+              id(context) not in seen):
             print_exc(type(context), context, context.__traceback__)
             print("\nDuring handling of the above exception, "
                   "another exception occurred:\n", file=efile)
@@ -277,6 +282,18 @@ def exit():
     sys.exit(0)
 
 
+def fix_scaling(root):
+    """Scale fonts on HiDPI displays."""
+    import tkinter.font
+    scaling = float(root.tk.call('tk', 'scaling'))
+    if scaling > 1.4:
+        for name in tkinter.font.names(root):
+            font = tkinter.font.Font(root=root, name=name, exists=True)
+            size = int(font['size'])
+            if size < 0:
+                font['size'] = round(-0.75*size)
+
+
 class MyRPCServer(rpc.RPCServer):
 
     def handle_error(self, request, client_address):
diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py
deleted file mode 100644 (file)
index 4186fa2..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-"""An implementation of tabbed pages using only standard Tkinter.
-
-Originally developed for use in IDLE. Based on tabpage.py.
-
-Classes exported:
-TabbedPageSet -- A Tkinter implementation of a tabbed-page widget.
-TabSet -- A widget containing tabs (buttons) in one or more rows.
-
-"""
-from tkinter import *
-
-class InvalidNameError(Exception): pass
-class AlreadyExistsError(Exception): pass
-
-
-class TabSet(Frame):
-    """A widget containing tabs (buttons) in one or more rows.
-
-    Only one tab may be selected at a time.
-
-    """
-    def __init__(self, page_set, select_command,
-                 tabs=None, n_rows=1, max_tabs_per_row=5,
-                 expand_tabs=False, **kw):
-        """Constructor arguments:
-
-        select_command -- A callable which will be called when a tab is
-        selected. It is called with the name of the selected tab as an
-        argument.
-
-        tabs -- A list of strings, the names of the tabs. Should be specified in
-        the desired tab order. The first tab will be the default and first
-        active tab. If tabs is None or empty, the TabSet will be initialized
-        empty.
-
-        n_rows -- Number of rows of tabs to be shown. If n_rows <= 0 or is
-        None, then the number of rows will be decided by TabSet. See
-        _arrange_tabs() for details.
-
-        max_tabs_per_row -- Used for deciding how many rows of tabs are needed,
-        when the number of rows is not constant. See _arrange_tabs() for
-        details.
-
-        """
-        Frame.__init__(self, page_set, **kw)
-        self.select_command = select_command
-        self.n_rows = n_rows
-        self.max_tabs_per_row = max_tabs_per_row
-        self.expand_tabs = expand_tabs
-        self.page_set = page_set
-
-        self._tabs = {}
-        self._tab2row = {}
-        if tabs:
-            self._tab_names = list(tabs)
-        else:
-            self._tab_names = []
-        self._selected_tab = None
-        self._tab_rows = []
-
-        self.padding_frame = Frame(self, height=2,
-                                   borderwidth=0, relief=FLAT,
-                                   background=self.cget('background'))
-        self.padding_frame.pack(side=TOP, fill=X, expand=False)
-
-        self._arrange_tabs()
-
-    def add_tab(self, tab_name):
-        """Add a new tab with the name given in tab_name."""
-        if not tab_name:
-            raise InvalidNameError("Invalid Tab name: '%s'" % tab_name)
-        if tab_name in self._tab_names:
-            raise AlreadyExistsError("Tab named '%s' already exists" %tab_name)
-
-        self._tab_names.append(tab_name)
-        self._arrange_tabs()
-
-    def remove_tab(self, tab_name):
-        """Remove the tab named <tab_name>"""
-        if not tab_name in self._tab_names:
-            raise KeyError("No such Tab: '%s" % tab_name)
-
-        self._tab_names.remove(tab_name)
-        self._arrange_tabs()
-
-    def set_selected_tab(self, tab_name):
-        """Show the tab named <tab_name> as the selected one"""
-        if tab_name == self._selected_tab:
-            return
-        if tab_name is not None and tab_name not in self._tabs:
-            raise KeyError("No such Tab: '%s" % tab_name)
-
-        # deselect the current selected tab
-        if self._selected_tab is not None:
-            self._tabs[self._selected_tab].set_normal()
-        self._selected_tab = None
-
-        if tab_name is not None:
-            # activate the tab named tab_name
-            self._selected_tab = tab_name
-            tab = self._tabs[tab_name]
-            tab.set_selected()
-            # move the tab row with the selected tab to the bottom
-            tab_row = self._tab2row[tab]
-            tab_row.pack_forget()
-            tab_row.pack(side=TOP, fill=X, expand=0)
-
-    def _add_tab_row(self, tab_names, expand_tabs):
-        if not tab_names:
-            return
-
-        tab_row = Frame(self)
-        tab_row.pack(side=TOP, fill=X, expand=0)
-        self._tab_rows.append(tab_row)
-
-        for tab_name in tab_names:
-            tab = TabSet.TabButton(tab_name, self.select_command,
-                                   tab_row, self)
-            if expand_tabs:
-                tab.pack(side=LEFT, fill=X, expand=True)
-            else:
-                tab.pack(side=LEFT)
-            self._tabs[tab_name] = tab
-            self._tab2row[tab] = tab_row
-
-        # tab is the last one created in the above loop
-        tab.is_last_in_row = True
-
-    def _reset_tab_rows(self):
-        while self._tab_rows:
-            tab_row = self._tab_rows.pop()
-            tab_row.destroy()
-        self._tab2row = {}
-
-    def _arrange_tabs(self):
-        """
-        Arrange the tabs in rows, in the order in which they were added.
-
-        If n_rows >= 1, this will be the number of rows used. Otherwise the
-        number of rows will be calculated according to the number of tabs and
-        max_tabs_per_row. In this case, the number of rows may change when
-        adding/removing tabs.
-
-        """
-        # remove all tabs and rows
-        while self._tabs:
-            self._tabs.popitem()[1].destroy()
-        self._reset_tab_rows()
-
-        if not self._tab_names:
-            return
-
-        if self.n_rows is not None and self.n_rows > 0:
-            n_rows = self.n_rows
-        else:
-            # calculate the required number of rows
-            n_rows = (len(self._tab_names) - 1) // self.max_tabs_per_row + 1
-
-        # not expanding the tabs with more than one row is very ugly
-        expand_tabs = self.expand_tabs or n_rows > 1
-        i = 0 # index in self._tab_names
-        for row_index in range(n_rows):
-            # calculate required number of tabs in this row
-            n_tabs = (len(self._tab_names) - i - 1) // (n_rows - row_index) + 1
-            tab_names = self._tab_names[i:i + n_tabs]
-            i += n_tabs
-            self._add_tab_row(tab_names, expand_tabs)
-
-        # re-select selected tab so it is properly displayed
-        selected = self._selected_tab
-        self.set_selected_tab(None)
-        if selected in self._tab_names:
-            self.set_selected_tab(selected)
-
-    class TabButton(Frame):
-        """A simple tab-like widget."""
-
-        bw = 2 # borderwidth
-
-        def __init__(self, name, select_command, tab_row, tab_set):
-            """Constructor arguments:
-
-            name -- The tab's name, which will appear in its button.
-
-            select_command -- The command to be called upon selection of the
-            tab. It is called with the tab's name as an argument.
-
-            """
-            Frame.__init__(self, tab_row, borderwidth=self.bw, relief=RAISED)
-
-            self.name = name
-            self.select_command = select_command
-            self.tab_set = tab_set
-            self.is_last_in_row = False
-
-            self.button = Radiobutton(
-                self, text=name, command=self._select_event,
-                padx=5, pady=1, takefocus=FALSE, indicatoron=FALSE,
-                highlightthickness=0, selectcolor='', borderwidth=0)
-            self.button.pack(side=LEFT, fill=X, expand=True)
-
-            self._init_masks()
-            self.set_normal()
-
-        def _select_event(self, *args):
-            """Event handler for tab selection.
-
-            With TabbedPageSet, this calls TabbedPageSet.change_page, so that
-            selecting a tab changes the page.
-
-            Note that this does -not- call set_selected -- it will be called by
-            TabSet.set_selected_tab, which should be called when whatever the
-            tabs are related to changes.
-
-            """
-            self.select_command(self.name)
-            return
-
-        def set_selected(self):
-            """Assume selected look"""
-            self._place_masks(selected=True)
-
-        def set_normal(self):
-            """Assume normal look"""
-            self._place_masks(selected=False)
-
-        def _init_masks(self):
-            page_set = self.tab_set.page_set
-            background = page_set.pages_frame.cget('background')
-            # mask replaces the middle of the border with the background color
-            self.mask = Frame(page_set, borderwidth=0, relief=FLAT,
-                              background=background)
-            # mskl replaces the bottom-left corner of the border with a normal
-            # left border
-            self.mskl = Frame(page_set, borderwidth=0, relief=FLAT,
-                              background=background)
-            self.mskl.ml = Frame(self.mskl, borderwidth=self.bw,
-                                 relief=RAISED)
-            self.mskl.ml.place(x=0, y=-self.bw,
-                               width=2*self.bw, height=self.bw*4)
-            # mskr replaces the bottom-right corner of the border with a normal
-            # right border
-            self.mskr = Frame(page_set, borderwidth=0, relief=FLAT,
-                              background=background)
-            self.mskr.mr = Frame(self.mskr, borderwidth=self.bw,
-                                 relief=RAISED)
-
-        def _place_masks(self, selected=False):
-            height = self.bw
-            if selected:
-                height += self.bw
-
-            self.mask.place(in_=self,
-                            relx=0.0, x=0,
-                            rely=1.0, y=0,
-                            relwidth=1.0, width=0,
-                            relheight=0.0, height=height)
-
-            self.mskl.place(in_=self,
-                            relx=0.0, x=-self.bw,
-                            rely=1.0, y=0,
-                            relwidth=0.0, width=self.bw,
-                            relheight=0.0, height=height)
-
-            page_set = self.tab_set.page_set
-            if selected and ((not self.is_last_in_row) or
-                             (self.winfo_rootx() + self.winfo_width() <
-                              page_set.winfo_rootx() + page_set.winfo_width())
-                             ):
-                # for a selected tab, if its rightmost edge isn't on the
-                # rightmost edge of the page set, the right mask should be one
-                # borderwidth shorter (vertically)
-                height -= self.bw
-
-            self.mskr.place(in_=self,
-                            relx=1.0, x=0,
-                            rely=1.0, y=0,
-                            relwidth=0.0, width=self.bw,
-                            relheight=0.0, height=height)
-
-            self.mskr.mr.place(x=-self.bw, y=-self.bw,
-                               width=2*self.bw, height=height + self.bw*2)
-
-            # finally, lower the tab set so that all of the frames we just
-            # placed hide it
-            self.tab_set.lower()
-
-
-class TabbedPageSet(Frame):
-    """A Tkinter tabbed-pane widget.
-
-    Constains set of 'pages' (or 'panes') with tabs above for selecting which
-    page is displayed. Only one page will be displayed at a time.
-
-    Pages may be accessed through the 'pages' attribute, which is a dictionary
-    of pages, using the name given as the key. A page is an instance of a
-    subclass of Tk's Frame widget.
-
-    The page widgets will be created (and destroyed when required) by the
-    TabbedPageSet. Do not call the page's pack/place/grid/destroy methods.
-
-    Pages may be added or removed at any time using the add_page() and
-    remove_page() methods.
-
-    """
-
-    class Page(object):
-        """Abstract base class for TabbedPageSet's pages.
-
-        Subclasses must override the _show() and _hide() methods.
-
-        """
-        uses_grid = False
-
-        def __init__(self, page_set):
-            self.frame = Frame(page_set, borderwidth=2, relief=RAISED)
-
-        def _show(self):
-            raise NotImplementedError
-
-        def _hide(self):
-            raise NotImplementedError
-
-    class PageRemove(Page):
-        """Page class using the grid placement manager's "remove" mechanism."""
-        uses_grid = True
-
-        def _show(self):
-            self.frame.grid(row=0, column=0, sticky=NSEW)
-
-        def _hide(self):
-            self.frame.grid_remove()
-
-    class PageLift(Page):
-        """Page class using the grid placement manager's "lift" mechanism."""
-        uses_grid = True
-
-        def __init__(self, page_set):
-            super(TabbedPageSet.PageLift, self).__init__(page_set)
-            self.frame.grid(row=0, column=0, sticky=NSEW)
-            self.frame.lower()
-
-        def _show(self):
-            self.frame.lift()
-
-        def _hide(self):
-            self.frame.lower()
-
-    class PagePackForget(Page):
-        """Page class using the pack placement manager's "forget" mechanism."""
-        def _show(self):
-            self.frame.pack(fill=BOTH, expand=True)
-
-        def _hide(self):
-            self.frame.pack_forget()
-
-    def __init__(self, parent, page_names=None, page_class=PageLift,
-                 n_rows=1, max_tabs_per_row=5, expand_tabs=False,
-                 **kw):
-        """Constructor arguments:
-
-        page_names -- A list of strings, each will be the dictionary key to a
-        page's widget, and the name displayed on the page's tab. Should be
-        specified in the desired page order. The first page will be the default
-        and first active page. If page_names is None or empty, the
-        TabbedPageSet will be initialized empty.
-
-        n_rows, max_tabs_per_row -- Parameters for the TabSet which will
-        manage the tabs. See TabSet's docs for details.
-
-        page_class -- Pages can be shown/hidden using three mechanisms:
-
-        * PageLift - All pages will be rendered one on top of the other. When
-          a page is selected, it will be brought to the top, thus hiding all
-          other pages. Using this method, the TabbedPageSet will not be resized
-          when pages are switched. (It may still be resized when pages are
-          added/removed.)
-
-        * PageRemove - When a page is selected, the currently showing page is
-          hidden, and the new page shown in its place. Using this method, the
-          TabbedPageSet may resize when pages are changed.
-
-        * PagePackForget - This mechanism uses the pack placement manager.
-          When a page is shown it is packed, and when it is hidden it is
-          unpacked (i.e. pack_forget). This mechanism may also cause the
-          TabbedPageSet to resize when the page is changed.
-
-        """
-        Frame.__init__(self, parent, **kw)
-
-        self.page_class = page_class
-        self.pages = {}
-        self._pages_order = []
-        self._current_page = None
-        self._default_page = None
-
-        self.columnconfigure(0, weight=1)
-        self.rowconfigure(1, weight=1)
-
-        self.pages_frame = Frame(self)
-        self.pages_frame.grid(row=1, column=0, sticky=NSEW)
-        if self.page_class.uses_grid:
-            self.pages_frame.columnconfigure(0, weight=1)
-            self.pages_frame.rowconfigure(0, weight=1)
-
-        # the order of the following commands is important
-        self._tab_set = TabSet(self, self.change_page, n_rows=n_rows,
-                               max_tabs_per_row=max_tabs_per_row,
-                               expand_tabs=expand_tabs)
-        if page_names:
-            for name in page_names:
-                self.add_page(name)
-        self._tab_set.grid(row=0, column=0, sticky=NSEW)
-
-        self.change_page(self._default_page)
-
-    def add_page(self, page_name):
-        """Add a new page with the name given in page_name."""
-        if not page_name:
-            raise InvalidNameError("Invalid TabPage name: '%s'" % page_name)
-        if page_name in self.pages:
-            raise AlreadyExistsError(
-                "TabPage named '%s' already exists" % page_name)
-
-        self.pages[page_name] = self.page_class(self.pages_frame)
-        self._pages_order.append(page_name)
-        self._tab_set.add_tab(page_name)
-
-        if len(self.pages) == 1: # adding first page
-            self._default_page = page_name
-            self.change_page(page_name)
-
-    def remove_page(self, page_name):
-        """Destroy the page whose name is given in page_name."""
-        if not page_name in self.pages:
-            raise KeyError("No such TabPage: '%s" % page_name)
-
-        self._pages_order.remove(page_name)
-
-        # handle removing last remaining, default, or currently shown page
-        if len(self._pages_order) > 0:
-            if page_name == self._default_page:
-                # set a new default page
-                self._default_page = self._pages_order[0]
-        else:
-            self._default_page = None
-
-        if page_name == self._current_page:
-            self.change_page(self._default_page)
-
-        self._tab_set.remove_tab(page_name)
-        page = self.pages.pop(page_name)
-        page.frame.destroy()
-
-    def change_page(self, page_name):
-        """Show the page whose name is given in page_name."""
-        if self._current_page == page_name:
-            return
-        if page_name is not None and page_name not in self.pages:
-            raise KeyError("No such TabPage: '%s'" % page_name)
-
-        if self._current_page is not None:
-            self.pages[self._current_page]._hide()
-        self._current_page = None
-
-        if page_name is not None:
-            self._current_page = page_name
-            self.pages[page_name]._show()
-
-        self._tab_set.set_selected_tab(page_name)
-
-
-def _tabbed_pages(parent):  # htest #
-    top=Toplevel(parent)
-    x, y = map(int, parent.geometry().split('+')[1:])
-    top.geometry("+%d+%d" % (x, y + 175))
-    top.title("Test tabbed pages")
-    tabPage=TabbedPageSet(top, page_names=['Foobar','Baz'], n_rows=0,
-                          expand_tabs=False,
-                          )
-    tabPage.pack(side=TOP, expand=TRUE, fill=BOTH)
-    Label(tabPage.pages['Foobar'].frame, text='Foo', pady=20).pack()
-    Label(tabPage.pages['Foobar'].frame, text='Bar', pady=20).pack()
-    Label(tabPage.pages['Baz'].frame, text='Baz').pack()
-    entryPgName=Entry(top)
-    buttonAdd=Button(top, text='Add Page',
-            command=lambda:tabPage.add_page(entryPgName.get()))
-    buttonRemove=Button(top, text='Remove Page',
-            command=lambda:tabPage.remove_page(entryPgName.get()))
-    labelPgName=Label(top, text='name of page to add/remove:')
-    buttonAdd.pack(padx=5, pady=5)
-    buttonRemove.pack(padx=5, pady=5)
-    labelPgName.pack(padx=5)
-    entryPgName.pack(padx=5)
-
-if __name__ == '__main__':
-    from idlelib.idle_test.htest import run
-    run(_tabbed_pages)
index de4b190ff2e4de613d2da5fe4e3e14c948e317f3..e3b55065c6d9cceb246652f941cc01d3cb6994f2 100644 (file)
@@ -57,7 +57,7 @@ class ViewWindow(Toplevel):
     "A simple text viewer dialog for IDLE."
 
     def __init__(self, parent, title, text, modal=True,
-                 _htest=False, _utest=False):
+                 *, _htest=False, _utest=False):
         """Show the given text in a scrollable window with a 'close' button.
 
         If modal is left True, users cannot interact with other windows
index 4cf8aec1b2a4aa93f4f18a9c8bde24541ae0dc46..e2343dd430806dd73c70aa4a0b71893a6d7b950f 100644 (file)
@@ -994,7 +994,7 @@ def _gcd_import(name, package=None, level=0):
     return _find_and_load(name, _gcd_import)
 
 
-def _handle_fromlist(module, fromlist, import_):
+def _handle_fromlist(module, fromlist, import_, *, recursive=False):
     """Figure out what __import__ should return.
 
     The import_ parameter is a callable which takes the name of module to
@@ -1005,13 +1005,19 @@ def _handle_fromlist(module, fromlist, import_):
     # The hell that is fromlist ...
     # If a package was imported, try to import stuff from fromlist.
     if hasattr(module, '__path__'):
-        if '*' in fromlist:
-            fromlist = list(fromlist)
-            fromlist.remove('*')
-            if hasattr(module, '__all__'):
-                fromlist.extend(module.__all__)
         for x in fromlist:
-            if not hasattr(module, x):
+            if not isinstance(x, str):
+                if recursive:
+                    where = module.__name__ + '.__all__'
+                else:
+                    where = "``from list''"
+                raise TypeError(f"Item in {where} must be str, "
+                                f"not {type(x).__name__}")
+            elif x == '*':
+                if not recursive and hasattr(module, '__all__'):
+                    _handle_fromlist(module, module.__all__, import_,
+                                     recursive=True)
+            elif not hasattr(module, x):
                 from_name = '{}.{}'.format(module.__name__, x)
                 try:
                     _call_with_frames_removed(import_, from_name)
@@ -1019,7 +1025,8 @@ def _handle_fromlist(module, fromlist, import_):
                     # Backwards-compatibility dictates we ignore failed
                     # imports triggered by fromlist for modules that don't
                     # exist.
-                    if exc.name == from_name:
+                    if (exc.name == from_name and
+                        sys.modules.get(from_name, _NEEDS_LOADING) is not None):
                         continue
                     raise
     return module
index 3317f58f475dc80f0624ca75ff55cdcf9c036938..e9c2dbd5c88d9952d335c8ae13647bd84a1039e6 100644 (file)
@@ -505,13 +505,16 @@ def unwrap(func, *, stop=None):
         def _is_wrapper(f):
             return hasattr(f, '__wrapped__') and not stop(f)
     f = func  # remember the original func for error reporting
-    memo = {id(f)} # Memoise by id to tolerate non-hashable objects
+    # Memoise by id to tolerate non-hashable objects, but store objects to
+    # ensure they aren't destroyed, which would allow their IDs to be reused.
+    memo = {id(f): f}
+    recursion_limit = sys.getrecursionlimit()
     while _is_wrapper(func):
         func = func.__wrapped__
         id_func = id(func)
-        if id_func in memo:
+        if (id_func in memo) or (len(memo) >= recursion_limit):
             raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
-        memo.add(id_func)
+        memo[id_func] = func
     return func
 
 # -------------------------------------------------- source code extraction
index 0965536797d7c6207106ad1b0b4b18cccf374e9e..3617dbb6d996a85dbfd96205e19390f8c70ed07f 100644 (file)
@@ -1669,7 +1669,7 @@ class LoggerAdapter(object):
         """
         if self.isEnabledFor(level):
             msg, kwargs = self.process(msg, kwargs)
-            self.logger._log(level, msg, args, **kwargs)
+            self.logger.log(level, msg, *args, **kwargs)
 
     def isEnabledFor(self, level):
         """
@@ -1715,9 +1715,13 @@ class LoggerAdapter(object):
         return self.logger.manager
 
     @manager.setter
-    def set_manager(self, value):
+    def manager(self, value):
         self.logger.manager = value
 
+    @property
+    def name(self):
+        return self.logger.name
+
     def __repr__(self):
         logger = self.logger
         level = getLevelName(logger.getEffectiveLevel())
index 2f934b330715633d8daf875fddf954754464fef1..11ebcf124c3f93575021babba45148920a38988e 100644 (file)
@@ -356,10 +356,10 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
                 suffix = fileName[plen:]
                 if self.extMatch.match(suffix):
                     result.append(os.path.join(dirName, fileName))
-        result.sort()
         if len(result) < self.backupCount:
             result = []
         else:
+            result.sort()
             result = result[:len(result) - self.backupCount]
         return result
 
@@ -1183,7 +1183,9 @@ class HTTPHandler(logging.Handler):
             i = host.find(":")
             if i >= 0:
                 host = host[:i]
-            h.putheader("Host", host)
+            # See issue #30904: putrequest call above already adds this header
+            # on Python 3.x.
+            # h.putheader("Host", host)
             if self.method == "POST":
                 h.putheader("Content-type",
                             "application/x-www-form-urlencoded")
index d5ce6257456766123080f16379eb21e249a82ff6..fd198959c8a1ae2a1cf3f3c56770f70e0c903ede 100644 (file)
@@ -33,6 +33,7 @@ class ForkServer(object):
     def __init__(self):
         self._forkserver_address = None
         self._forkserver_alive_fd = None
+        self._forkserver_pid = None
         self._inherited_fds = None
         self._lock = threading.Lock()
         self._preload_modules = ['__main__']
@@ -89,8 +90,17 @@ class ForkServer(object):
         '''
         with self._lock:
             semaphore_tracker.ensure_running()
-            if self._forkserver_alive_fd is not None:
-                return
+            if self._forkserver_pid is not None:
+                # forkserver was launched before, is it still running?
+                pid, status = os.waitpid(self._forkserver_pid, os.WNOHANG)
+                if not pid:
+                    # still alive
+                    return
+                # dead, launch it again
+                os.close(self._forkserver_alive_fd)
+                self._forkserver_address = None
+                self._forkserver_alive_fd = None
+                self._forkserver_pid = None
 
             cmd = ('from multiprocessing.forkserver import main; ' +
                    'main(%d, %d, %r, **%r)')
@@ -127,6 +137,7 @@ class ForkServer(object):
                     os.close(alive_r)
                 self._forkserver_address = address
                 self._forkserver_alive_fd = alive_w
+                self._forkserver_pid = pid
 
 #
 #
@@ -149,11 +160,11 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
 
     util._close_stdin()
 
-    # ignoring SIGCHLD means no need to reap zombie processes;
-    # letting SIGINT through avoids KeyboardInterrupt tracebacks
     handlers = {
+        # no need to reap zombie processes;
         signal.SIGCHLD: signal.SIG_IGN,
-        signal.SIGINT: signal.SIG_DFL,
+        # protect the process from ^C
+        signal.SIGINT: signal.SIG_IGN,
         }
     old_handlers = {sig: signal.signal(sig, val)
                     for (sig, val) in handlers.items()}
index d2ebd7cfbe1e03de90be6075bbdf3d87066b3bf1..5d0fa569f12eaaa3e9789539fdea820229f90f8e 100644 (file)
@@ -14,8 +14,14 @@ class Popen(object):
     method = 'fork'
 
     def __init__(self, process_obj):
-        sys.stdout.flush()
-        sys.stderr.flush()
+        try:
+            sys.stdout.flush()
+        except (AttributeError, ValueError):
+            pass
+        try:
+            sys.stderr.flush()
+        except (AttributeError, ValueError):
+            pass
         self.returncode = None
         self._launch(process_obj)
 
index de7738eeee8ab264ab059c99d749ee62372c3c39..3b50a46ddc5fbf21b3ad9b58a5b30bc1bba98e9e 100644 (file)
@@ -29,6 +29,7 @@ class SemaphoreTracker(object):
     def __init__(self):
         self._lock = threading.Lock()
         self._fd = None
+        self._pid = None
 
     def getfd(self):
         self.ensure_running()
@@ -40,8 +41,20 @@ class SemaphoreTracker(object):
         This can be run from any process.  Usually a child process will use
         the semaphore created by its parent.'''
         with self._lock:
-            if self._fd is not None:
-                return
+            if self._pid is not None:
+                # semaphore tracker was launched before, is it still running?
+                pid, status = os.waitpid(self._pid, os.WNOHANG)
+                if not pid:
+                    # => still alive
+                    return
+                # => dead, launch it again
+                os.close(self._fd)
+                self._fd = None
+                self._pid = None
+
+                warnings.warn('semaphore_tracker: process died unexpectedly, '
+                              'relaunching.  Some semaphores might leak.')
+
             fds_to_pass = []
             try:
                 fds_to_pass.append(sys.stderr.fileno())
@@ -55,12 +68,13 @@ class SemaphoreTracker(object):
                 exe = spawn.get_executable()
                 args = [exe] + util._args_from_interpreter_flags()
                 args += ['-c', cmd % r]
-                util.spawnv_passfds(exe, args, fds_to_pass)
+                pid = util.spawnv_passfds(exe, args, fds_to_pass)
             except:
                 os.close(w)
                 raise
             else:
                 self._fd = w
+                self._pid = pid
             finally:
                 os.close(r)
 
index bbb3d23b5433433ec89c07dfb6a7ddbd5027e9ec..1d90f5d900899c7449e9c20fac4e28dddeaaf8e3 100644 (file)
@@ -127,15 +127,15 @@ class netrc:
         rep = ""
         for host in self.hosts.keys():
             attrs = self.hosts[host]
-            rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"
+            rep += f"machine {host}\n\tlogin {attrs[0]}\n"
             if attrs[1]:
-                rep = rep + "account " + repr(attrs[1])
-            rep = rep + "\tpassword " + repr(attrs[2]) + "\n"
+                rep += f"\taccount {attrs[1]}\n"
+            rep += f"\tpassword {attrs[2]}\n"
         for macro in self.macros.keys():
-            rep = rep + "macdef " + macro + "\n"
+            rep += f"macdef {macro}\n"
             for line in self.macros[macro]:
-                rep = rep + line
-            rep = rep + "\n"
+                rep += line
+            rep += "\n"
         return rep
 
 if __name__ == '__main__':
index 09be5fd369ccf0dbb446451e98ff15c395f385e7..a91864372554bfa13aef355c6d031a0d141c2170 100644 (file)
@@ -590,6 +590,8 @@ class InvalidFileException (ValueError):
 
 _BINARY_FORMAT = {1: 'B', 2: 'H', 4: 'L', 8: 'Q'}
 
+_undefined = object()
+
 class _BinaryPlistParser:
     """
     Read or write a binary plist file, following the description of the binary
@@ -620,9 +622,11 @@ class _BinaryPlistParser:
             ) = struct.unpack('>6xBBQQQ', trailer)
             self._fp.seek(offset_table_offset)
             self._object_offsets = self._read_ints(num_objects, offset_size)
-            return self._read_object(self._object_offsets[top_object])
+            self._objects = [_undefined] * num_objects
+            return self._read_object(top_object)
 
-        except (OSError, IndexError, struct.error):
+        except (OSError, IndexError, struct.error, OverflowError,
+                UnicodeDecodeError):
             raise InvalidFileException()
 
     def _get_size(self, tokenL):
@@ -640,68 +644,76 @@ class _BinaryPlistParser:
         if size in _BINARY_FORMAT:
             return struct.unpack('>' + _BINARY_FORMAT[size] * n, data)
         else:
+            if not size or len(data) != size * n:
+                raise InvalidFileException()
             return tuple(int.from_bytes(data[i: i + size], 'big')
                          for i in range(0, size * n, size))
 
     def _read_refs(self, n):
         return self._read_ints(n, self._ref_size)
 
-    def _read_object(self, offset):
+    def _read_object(self, ref):
         """
-        read the object at offset.
+        read the object by reference.
 
         May recursively read sub-objects (content of an array/dict/set)
         """
+        result = self._objects[ref]
+        if result is not _undefined:
+            return result
+
+        offset = self._object_offsets[ref]
         self._fp.seek(offset)
         token = self._fp.read(1)[0]
         tokenH, tokenL = token & 0xF0, token & 0x0F
 
         if token == 0x00:
-            return None
+            result = None
 
         elif token == 0x08:
-            return False
+            result = False
 
         elif token == 0x09:
-            return True
+            result = True
 
         # The referenced source code also mentions URL (0x0c, 0x0d) and
         # UUID (0x0e), but neither can be generated using the Cocoa libraries.
 
         elif token == 0x0f:
-            return b''
+            result = b''
 
         elif tokenH == 0x10:  # int
-            return int.from_bytes(self._fp.read(1 << tokenL),
-                                  'big', signed=tokenL >= 3)
+            result = int.from_bytes(self._fp.read(1 << tokenL),
+                                    'big', signed=tokenL >= 3)
 
         elif token == 0x22: # real
-            return struct.unpack('>f', self._fp.read(4))[0]
+            result = struct.unpack('>f', self._fp.read(4))[0]
 
         elif token == 0x23: # real
-            return struct.unpack('>d', self._fp.read(8))[0]
+            result = struct.unpack('>d', self._fp.read(8))[0]
 
         elif token == 0x33:  # date
             f = struct.unpack('>d', self._fp.read(8))[0]
             # timestamp 0 of binary plists corresponds to 1/1/2001
             # (year of Mac OS X 10.0), instead of 1/1/1970.
-            return datetime.datetime(2001, 1, 1) + datetime.timedelta(seconds=f)
+            result = (datetime.datetime(2001, 1, 1) +
+                      datetime.timedelta(seconds=f))
 
         elif tokenH == 0x40:  # data
             s = self._get_size(tokenL)
             if self._use_builtin_types:
-                return self._fp.read(s)
+                result = self._fp.read(s)
             else:
-                return Data(self._fp.read(s))
+                result = Data(self._fp.read(s))
 
         elif tokenH == 0x50:  # ascii string
             s = self._get_size(tokenL)
             result =  self._fp.read(s).decode('ascii')
-            return result
+            result = result
 
         elif tokenH == 0x60:  # unicode string
             s = self._get_size(tokenL)
-            return self._fp.read(s * 2).decode('utf-16be')
+            result = self._fp.read(s * 2).decode('utf-16be')
 
         # tokenH == 0x80 is documented as 'UID' and appears to be used for
         # keyed-archiving, not in plists.
@@ -709,8 +721,9 @@ class _BinaryPlistParser:
         elif tokenH == 0xA0:  # array
             s = self._get_size(tokenL)
             obj_refs = self._read_refs(s)
-            return [self._read_object(self._object_offsets[x])
-                for x in obj_refs]
+            result = []
+            self._objects[ref] = result
+            result.extend(self._read_object(x) for x in obj_refs)
 
         # tokenH == 0xB0 is documented as 'ordset', but is not actually
         # implemented in the Apple reference code.
@@ -723,12 +736,15 @@ class _BinaryPlistParser:
             key_refs = self._read_refs(s)
             obj_refs = self._read_refs(s)
             result = self._dict_type()
+            self._objects[ref] = result
             for k, o in zip(key_refs, obj_refs):
-                result[self._read_object(self._object_offsets[k])
-                    ] = self._read_object(self._object_offsets[o])
-            return result
+                result[self._read_object(k)] = self._read_object(o)
+
+        else:
+            raise InvalidFileException()
 
-        raise InvalidFileException()
+        self._objects[ref] = result
+        return result
 
 def _count_to_size(count):
     if count < 1 << 8:
@@ -743,6 +759,8 @@ def _count_to_size(count):
     else:
         return 8
 
+_scalars = (str, int, float, datetime.datetime, bytes)
+
 class _BinaryPlistWriter (object):
     def __init__(self, fp, sort_keys, skipkeys):
         self._fp = fp
@@ -798,8 +816,7 @@ class _BinaryPlistWriter (object):
         # First check if the object is in the object table, not used for
         # containers to ensure that two subcontainers with the same contents
         # will be serialized as distinct values.
-        if isinstance(value, (
-                str, int, float, datetime.datetime, bytes, bytearray)):
+        if isinstance(value, _scalars):
             if (type(value), value) in self._objtable:
                 return
 
@@ -807,15 +824,17 @@ class _BinaryPlistWriter (object):
             if (type(value.data), value.data) in self._objtable:
                 return
 
+        elif id(value) in self._objidtable:
+            return
+
         # Add to objectreference map
         refnum = len(self._objlist)
         self._objlist.append(value)
-        try:
-            if isinstance(value, Data):
-                self._objtable[(type(value.data), value.data)] = refnum
-            else:
-                self._objtable[(type(value), value)] = refnum
-        except TypeError:
+        if isinstance(value, _scalars):
+            self._objtable[(type(value), value)] = refnum
+        elif isinstance(value, Data):
+            self._objtable[(type(value.data), value.data)] = refnum
+        else:
             self._objidtable[id(value)] = refnum
 
         # And finally recurse into containers
@@ -842,12 +861,11 @@ class _BinaryPlistWriter (object):
                 self._flatten(o)
 
     def _getrefnum(self, value):
-        try:
-            if isinstance(value, Data):
-                return self._objtable[(type(value.data), value.data)]
-            else:
-                return self._objtable[(type(value), value)]
-        except TypeError:
+        if isinstance(value, _scalars):
+            return self._objtable[(type(value), value)]
+        elif isinstance(value, Data):
+            return self._objtable[(type(value.data), value.data)]
+        else:
             return self._objidtable[id(value)]
 
     def _write_size(self, token, size):
index deb540d526ef7d166aac32ee4b233455d153d6d7..8dc41a2c17a694f5c87102e6b3f0509ab64199bd 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Mon Sep 18 23:00:11 2017
+# Autogenerated by Sphinx on Tue Dec  5 03:11:02 2017
 topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
@@ -2674,7 +2674,6 @@ topics = {'assert': 'The "assert" statement\n'
              '   mgr = (EXPR)\n'
              '   aexit = type(mgr).__aexit__\n'
              '   aenter = type(mgr).__aenter__(mgr)\n'
-             '   exc = True\n'
              '\n'
              '   VAR = await aenter\n'
              '   try:\n'
@@ -4503,12 +4502,6 @@ topics = {'assert': 'The "assert" statement\n'
              '   3.14    10.    .001    1e100    3.14e-10    0e0    '
              '3.14_15_93\n'
              '\n'
-             'Note that numeric literals do not include a sign; a phrase like '
-             '"-1"\n'
-             'is actually an expression composed of the unary operator "-" and '
-             'the\n'
-             'literal "1".\n'
-             '\n'
              'Changed in version 3.6: Underscores are now allowed for '
              'grouping\n'
              'purposes in literals.\n',
@@ -5497,7 +5490,7 @@ topics = {'assert': 'The "assert" statement\n'
            '\n'
            '**CPython implementation detail:** The current implementation does '
            'not\n'
-           'enforce some of these restriction, but programs should not abuse '
+           'enforce some of these restrictions, but programs should not abuse '
            'this\n'
            'freedom, as future implementations may enforce them or silently '
            'change\n'
@@ -6744,7 +6737,9 @@ topics = {'assert': 'The "assert" statement\n'
                      'Addition and subtraction              |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
                      '| "*", "@", "/", "//", "%"                        | '
-                     'Multiplication, matrix multiplication |\n'
+                     'Multiplication, matrix                |\n'
+                     '|                                                 | '
+                     'multiplication, division, floor       |\n'
                      '|                                                 | '
                      'division, remainder [5]               |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
@@ -10102,11 +10097,6 @@ topics = {'assert': 'The "assert" statement\n'
             'or\n'
             'greater must be expressed with escapes.\n'
             '\n'
-            'As of Python 3.3 it is possible again to prefix string literals '
-            'with a\n'
-            '"u" prefix to simplify maintenance of dual 2.x and 3.x '
-            'codebases.\n'
-            '\n'
             'Both string and bytes literals may optionally be prefixed with a\n'
             'letter "\'r\'" or "\'R\'"; such strings are called *raw strings* '
             'and treat\n'
index ad1c9167b02a65c6783260848e2713c8fc0b9f62..0152e5ea12bf7924e4a64184ba1b59df376b3890 100644 (file)
@@ -109,9 +109,10 @@ class Random(_random.Random):
         """
 
         if version == 1 and isinstance(a, (str, bytes)):
+            a = a.decode('latin-1') if isinstance(a, bytes) else a
             x = ord(a[0]) << 7 if a else 0
-            for c in a:
-                x = ((1000003 * x) ^ ord(c)) & 0xFFFFFFFFFFFFFFFF
+            for c in map(ord, a):
+                x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
             x ^= len(a)
             a = -2 if x == -1 else x
 
index 7dd0050528f8fa19541e6a7ba10c30bc40c771b9..34cd233535dc16488fcf509a16333436dc12a6de 100644 (file)
@@ -24,6 +24,8 @@
 import datetime
 import unittest
 import sqlite3 as sqlite
+import weakref
+from test import support
 
 class RegressionTests(unittest.TestCase):
     def setUp(self):
@@ -188,6 +190,9 @@ class RegressionTests(unittest.TestCase):
         cur = Cursor(con)
         with self.assertRaises(sqlite.ProgrammingError):
             cur.execute("select 4+5").fetchall()
+        with self.assertRaisesRegex(sqlite.ProgrammingError,
+                                    r'^Base Cursor\.__init__ not called\.$'):
+            cur.close()
 
     def CheckStrSubclass(self):
         """
@@ -376,6 +381,22 @@ class RegressionTests(unittest.TestCase):
                 counter += 1
         self.assertEqual(counter, 3, "should have returned exactly three rows")
 
+    def CheckBpo31770(self):
+        """
+        The interpreter shouldn't crash in case Cursor.__init__() is called
+        more than once.
+        """
+        def callback(*args):
+            pass
+        con = sqlite.connect(":memory:")
+        cur = sqlite.Cursor(con)
+        ref = weakref.ref(cur, callback)
+        cur.__init__(con)
+        del cur
+        # The interpreter shouldn't crash when ref is collected.
+        del ref
+        support.gc_collect()
+
 
 def suite():
     regression_suite = unittest.makeSuite(RegressionTests, "Check")
index c9020076437e999c23829caec193b4b9aa7bfb88..670c1951a8a82070425a5754c4666ed4d9baa921 100644 (file)
@@ -78,7 +78,11 @@ class Template(metaclass=_TemplateMetaclass):
     """A string class for supporting $-substitutions."""
 
     delimiter = '$'
-    idpattern = r'[_a-z][_a-z0-9]*'
+    # r'[a-z]' matches to non-ASCII letters when used with IGNORECASE,
+    # but without ASCII flag.  We can't add re.ASCII to flags because of
+    # backward compatibility.  So we use local -i flag and [a-zA-Z] pattern.
+    # See https://bugs.python.org/issue31672
+    idpattern = r'(?-i:[_a-zA-Z][_a-zA-Z0-9]*)'
     flags = _re.IGNORECASE
 
     def __init__(self, template):
index db30e6b9d22a0c04acbb0532b39418db5292411d..f01c0041d652dbf6c1477dc25d044202b4b8e412 100644 (file)
@@ -4,6 +4,7 @@
 
 import unittest
 import queue as pyqueue
+import contextlib
 import time
 import io
 import itertools
@@ -425,6 +426,75 @@ class _TestProcess(BaseTestCase):
         self.assertEqual(q.get(), 5)
         close_queue(q)
 
+    @classmethod
+    def _test_error_on_stdio_flush(self, evt):
+        evt.set()
+
+    def test_error_on_stdio_flush(self):
+        streams = [io.StringIO(), None]
+        streams[0].close()
+        for stream_name in ('stdout', 'stderr'):
+            for stream in streams:
+                old_stream = getattr(sys, stream_name)
+                setattr(sys, stream_name, stream)
+                try:
+                    evt = self.Event()
+                    proc = self.Process(target=self._test_error_on_stdio_flush,
+                                        args=(evt,))
+                    proc.start()
+                    proc.join()
+                    self.assertTrue(evt.is_set())
+                finally:
+                    setattr(sys, stream_name, old_stream)
+
+    @classmethod
+    def _sleep_and_set_event(self, evt, delay=0.0):
+        time.sleep(delay)
+        evt.set()
+
+    def check_forkserver_death(self, signum):
+        # bpo-31308: if the forkserver process has died, we should still
+        # be able to create and run new Process instances (the forkserver
+        # is implicitly restarted).
+        if self.TYPE == 'threads':
+            self.skipTest('test not appropriate for {}'.format(self.TYPE))
+        sm = multiprocessing.get_start_method()
+        if sm != 'forkserver':
+            # The fork method by design inherits all fds from the parent,
+            # trying to go against it is a lost battle
+            self.skipTest('test not appropriate for {}'.format(sm))
+
+        from multiprocessing.forkserver import _forkserver
+        _forkserver.ensure_running()
+
+        evt = self.Event()
+        proc = self.Process(target=self._sleep_and_set_event, args=(evt, 1.0))
+        proc.start()
+
+        pid = _forkserver._forkserver_pid
+        os.kill(pid, signum)
+        time.sleep(1.0)  # give it time to die
+
+        evt2 = self.Event()
+        proc2 = self.Process(target=self._sleep_and_set_event, args=(evt2,))
+        proc2.start()
+        proc2.join()
+        self.assertTrue(evt2.is_set())
+        self.assertEqual(proc2.exitcode, 0)
+
+        proc.join()
+        self.assertTrue(evt.is_set())
+        self.assertIn(proc.exitcode, (0, 255))
+
+    def test_forkserver_sigint(self):
+        # Catchable signal
+        self.check_forkserver_death(signal.SIGINT)
+
+    def test_forkserver_sigkill(self):
+        # Uncatchable signal
+        if os.name != 'nt':
+            self.check_forkserver_death(signal.SIGKILL)
+
 
 #
 #
@@ -4056,14 +4126,14 @@ class TestStartMethod(unittest.TestCase):
             self.fail("failed spawning forkserver or grandchild")
 
 
-#
-# Check that killing process does not leak named semaphores
-#
-
 @unittest.skipIf(sys.platform == "win32",
                  "test semantics don't make sense on Windows")
 class TestSemaphoreTracker(unittest.TestCase):
+
     def test_semaphore_tracker(self):
+        #
+        # Check that killing process does not leak named semaphores
+        #
         import subprocess
         cmd = '''if 1:
             import multiprocessing as mp, time, os
@@ -4097,6 +4167,40 @@ class TestSemaphoreTracker(unittest.TestCase):
         self.assertRegex(err, expected)
         self.assertRegex(err, r'semaphore_tracker: %r: \[Errno' % name1)
 
+    def check_semaphore_tracker_death(self, signum, should_die):
+        # bpo-31310: if the semaphore tracker process has died, it should
+        # be restarted implicitly.
+        from multiprocessing.semaphore_tracker import _semaphore_tracker
+        _semaphore_tracker.ensure_running()
+        pid = _semaphore_tracker._pid
+        os.kill(pid, signum)
+        time.sleep(1.0)  # give it time to die
+
+        ctx = multiprocessing.get_context("spawn")
+        with contextlib.ExitStack() as stack:
+            if should_die:
+                stack.enter_context(self.assertWarnsRegex(
+                    UserWarning,
+                    "semaphore_tracker: process died"))
+            sem = ctx.Semaphore()
+            sem.acquire()
+            sem.release()
+            wr = weakref.ref(sem)
+            # ensure `sem` gets collected, which triggers communication with
+            # the semaphore tracker
+            del sem
+            gc.collect()
+            self.assertIsNone(wr())
+
+    def test_semaphore_tracker_sigint(self):
+        # Catchable signal (ignored by semaphore tracker)
+        self.check_semaphore_tracker_death(signal.SIGINT, False)
+
+    def test_semaphore_tracker_sigkill(self):
+        # Uncatchable signal.
+        self.check_semaphore_tracker_death(signal.SIGKILL, True)
+
+
 class TestSimpleQueue(unittest.TestCase):
 
     @classmethod
index b25e6c17136790f7484c27dd8cae2a3aad4e943b..f23a5305e45123291b708652a603eb9485aa246e 100644 (file)
@@ -846,6 +846,46 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
 
         self.assertRaises(TypeError, divmod, t, 10)
 
+    def test_issue31293(self):
+        # The interpreter shouldn't crash in case a timedelta is divided or
+        # multiplied by a float with a bad as_integer_ratio() method.
+        def get_bad_float(bad_ratio):
+            class BadFloat(float):
+                def as_integer_ratio(self):
+                    return bad_ratio
+            return BadFloat()
+
+        with self.assertRaises(TypeError):
+            timedelta() / get_bad_float(1 << 1000)
+        with self.assertRaises(TypeError):
+            timedelta() * get_bad_float(1 << 1000)
+
+        for bad_ratio in [(), (42, ), (1, 2, 3)]:
+            with self.assertRaises(ValueError):
+                timedelta() / get_bad_float(bad_ratio)
+            with self.assertRaises(ValueError):
+                timedelta() * get_bad_float(bad_ratio)
+
+    def test_issue31752(self):
+        # The interpreter shouldn't crash because divmod() returns negative
+        # remainder.
+        class BadInt(int):
+            def __mul__(self, other):
+                return Prod()
+
+        class Prod:
+            def __radd__(self, other):
+                return Sum()
+
+        class Sum(int):
+            def __divmod__(self, other):
+                # negative remainder
+                return (0, -1)
+
+        timedelta(microseconds=BadInt(1))
+        timedelta(hours=BadInt(1))
+        timedelta(weeks=BadInt(1))
+
 
 #############################################################################
 # date tests
@@ -1460,6 +1500,13 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         base = cls(2000, 2, 29)
         self.assertRaises(ValueError, base.replace, year=2001)
 
+    def test_subclass_replace(self):
+        class DateSubclass(self.theclass):
+            pass
+
+        dt = DateSubclass(2012, 1, 1)
+        self.assertIs(type(dt.replace(year=2013)), DateSubclass)
+
     def test_subclass_date(self):
 
         class C(self.theclass):
@@ -2559,6 +2606,13 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
         self.assertRaises(ValueError, base.replace, second=100)
         self.assertRaises(ValueError, base.replace, microsecond=1000000)
 
+    def test_subclass_replace(self):
+        class TimeSubclass(self.theclass):
+            pass
+
+        ctime = TimeSubclass(12, 30)
+        self.assertIs(type(ctime.replace(hour=10)), TimeSubclass)
+
     def test_subclass_time(self):
 
         class C(self.theclass):
index 1dbe88efe70ffdfffac745b37c4bbd3d3b9e5fa3..bc308fe107b31172159012278ed1e03878789ebf 100644 (file)
@@ -20,7 +20,6 @@ import time
 import unittest
 
 from test import support
-android_not_root = support.android_not_root
 
 @contextlib.contextmanager
 def kill_on_error(proc):
@@ -312,14 +311,16 @@ class SocketEINTRTest(EINTRBaseTest):
     # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203162
     @support.requires_freebsd_version(10, 3)
     @unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()')
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def _test_open(self, do_open_close_reader, do_open_close_writer):
         filename = support.TESTFN
 
         # Use a fifo: until the child opens it for reading, the parent will
         # block when trying to open it for writing.
         support.unlink(filename)
-        os.mkfifo(filename)
+        try:
+            os.mkfifo(filename)
+        except PermissionError as e:
+            self.skipTest('os.mkfifo(): %s' % e)
         self.addCleanup(support.unlink, filename)
 
         code = '\n'.join((
index d44f69dda2f70ed3c6b1f5c38a435d7fcb2dbdbb..15e51525c36209e5e99fcaa9f1a50a304bea7d71 100644 (file)
@@ -256,12 +256,12 @@ class Regrtest:
             if isinstance(test, unittest.TestSuite):
                 self._list_cases(test)
             elif isinstance(test, unittest.TestCase):
-                if support._match_test(test):
+                if support.match_test(test):
                     print(test.id())
 
     def list_cases(self):
         support.verbose = False
-        support.match_tests = self.ns.match_tests
+        support.set_match_tests(self.ns.match_tests)
 
         for test in self.selected:
             abstest = get_abs_module(self.ns, test)
index d716b83e23547260f56b72a4aefe19df2af11aee..aefec1254b2e32bb91b02b66af6ed530afdb25a7 100644 (file)
@@ -102,7 +102,7 @@ def runtest(ns, test):
     if use_timeout:
         faulthandler.dump_traceback_later(ns.timeout, exit=True)
     try:
-        support.match_tests = ns.match_tests
+        support.set_match_tests(ns.match_tests)
         if ns.failfast:
             support.failfast = True
         if output_on_failure:
index 1d24531fc26ec544e5f15e3e5cb89e94544b1009..bf899a9e4d4ac1a042f64968f9e34a1e0bcfc457 100644 (file)
@@ -14,17 +14,26 @@ from test.libregrtest.refleak import warm_caches
 
 
 def setup_tests(ns):
-    # Display the Python traceback on fatal errors (e.g. segfault)
-    faulthandler.enable(all_threads=True)
-
-    # Display the Python traceback on SIGALRM or SIGUSR1 signal
-    signals = []
-    if hasattr(signal, 'SIGALRM'):
-        signals.append(signal.SIGALRM)
-    if hasattr(signal, 'SIGUSR1'):
-        signals.append(signal.SIGUSR1)
-    for signum in signals:
-        faulthandler.register(signum, chain=True)
+    try:
+        stderr_fd = sys.__stderr__.fileno()
+    except (ValueError, AttributeError):
+        # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
+        # and ValueError on a closed stream.
+        #
+        # Catch AttributeError for stderr being None.
+        stderr_fd = None
+    else:
+        # Display the Python traceback on fatal errors (e.g. segfault)
+        faulthandler.enable(all_threads=True, file=stderr_fd)
+
+        # Display the Python traceback on SIGALRM or SIGUSR1 signal
+        signals = []
+        if hasattr(signal, 'SIGALRM'):
+            signals.append(signal.SIGALRM)
+        if hasattr(signal, 'SIGUSR1'):
+            signals.append(signal.SIGUSR1)
+        for signum in signals:
+            faulthandler.register(signum, chain=True, file=stderr_fd)
 
     replace_stdout()
     support.record_original_stdout(sys.stdout)
@@ -109,7 +118,17 @@ def replace_stdout():
     """Set stdout encoder error handler to backslashreplace (as stderr error
     handler) to avoid UnicodeEncodeError when printing a traceback"""
     stdout = sys.stdout
-    sys.stdout = open(stdout.fileno(), 'w',
+    try:
+        fd = stdout.fileno()
+    except ValueError:
+        # On IDLE, sys.stdout has no file descriptor and is not a TextIOWrapper
+        # object. Leaving sys.stdout unchanged.
+        #
+        # Catch ValueError to catch io.UnsupportedOperation on TextIOBase
+        # and ValueError on a closed stream.
+        return
+
+    sys.stdout = open(fd, 'w',
         encoding=stdout.encoding,
         errors="backslashreplace",
         closefd=False,
index 5c83361027bdb2548c561951ffc5033f36b4df9c..a1c0bd726fe2bb32d6dc10f9c90c80b1bdd5c999 100644 (file)
@@ -2534,7 +2534,7 @@ class AbstractPickleModuleTests(unittest.TestCase):
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, pickle.dump, 123, f)
+            self.assertRaises(ValueError, self.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
@@ -2543,16 +2543,16 @@ class AbstractPickleModuleTests(unittest.TestCase):
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, pickle.dump, 123, f)
+            self.assertRaises(ValueError, self.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
     def test_load_from_and_dump_to_file(self):
         stream = io.BytesIO()
         data = [123, {}, 124]
-        pickle.dump(data, stream)
+        self.dump(data, stream)
         stream.seek(0)
-        unpickled = pickle.load(stream)
+        unpickled = self.load(stream)
         self.assertEqual(unpickled, data)
 
     def test_highest_protocol(self):
@@ -2562,20 +2562,20 @@ class AbstractPickleModuleTests(unittest.TestCase):
     def test_callapi(self):
         f = io.BytesIO()
         # With and without keyword arguments
-        pickle.dump(123, f, -1)
-        pickle.dump(123, file=f, protocol=-1)
-        pickle.dumps(123, -1)
-        pickle.dumps(123, protocol=-1)
-        pickle.Pickler(f, -1)
-        pickle.Pickler(f, protocol=-1)
+        self.dump(123, f, -1)
+        self.dump(123, file=f, protocol=-1)
+        self.dumps(123, -1)
+        self.dumps(123, protocol=-1)
+        self.Pickler(f, -1)
+        self.Pickler(f, protocol=-1)
 
     def test_bad_init(self):
         # Test issue3664 (pickle can segfault from a badly initialized Pickler).
         # Override initialization without calling __init__() of the superclass.
-        class BadPickler(pickle.Pickler):
+        class BadPickler(self.Pickler):
             def __init__(self): pass
 
-        class BadUnpickler(pickle.Unpickler):
+        class BadUnpickler(self.Unpickler):
             def __init__(self): pass
 
         self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
index 15cce34e822cfae8ffe04d9c7247227d503b38e3..c238ef7b75c5bd6db4de21e5299590b7cb871504 100644 (file)
@@ -2,6 +2,7 @@
 Collect various informations about Python to help debugging test failures.
 """
 from __future__ import print_function
+import errno
 import re
 import sys
 import traceback
@@ -114,6 +115,14 @@ def collect_sys(info_add):
             encoding = '%s/%s' % (encoding, errors)
         info_add('sys.%s.encoding' % name, encoding)
 
+    # Were we compiled --with-pydebug or with #define Py_DEBUG?
+    Py_DEBUG = hasattr(sys, 'gettotalrefcount')
+    if Py_DEBUG:
+        text = 'Yes (sys.gettotalrefcount() present)'
+    else:
+        text = 'No (sys.gettotalrefcount() missing)'
+    info_add('Py_DEBUG', text)
+
 
 def collect_platform(info_add):
     import platform
@@ -223,11 +232,17 @@ def collect_os(info_add):
     if hasattr(os, 'getrandom'):
         # PEP 524: Check if system urandom is initialized
         try:
-            os.getrandom(1, os.GRND_NONBLOCK)
-            state = 'ready (initialized)'
-        except BlockingIOError as exc:
-            state = 'not seeded yet (%s)' % exc
-        info_add('os.getrandom', state)
+            try:
+                os.getrandom(1, os.GRND_NONBLOCK)
+                state = 'ready (initialized)'
+            except BlockingIOError as exc:
+                state = 'not seeded yet (%s)' % exc
+            info_add('os.getrandom', state)
+        except OSError as exc:
+            # Python was compiled on a more recent Linux version
+            # than the current Linux kernel: ignore OSError(ENOSYS)
+            if exc.errno != errno.ENOSYS:
+                raise
 
 
 def collect_readline(info_add):
index a5b8c46f9495b06eb23c0cad5bad9742b207b7bc..2930ab24e4d047862896ab028be7a15acd71fdb8 100644 (file)
@@ -93,7 +93,7 @@ __all__ = [
     "check__all__", "requires_android_level", "requires_multiprocessing_queue",
     # sys
     "is_jython", "is_android", "check_impl_detail", "unix_shell",
-    "setswitchinterval", "android_not_root",
+    "setswitchinterval",
     # network
     "HOST", "IPV6_ENABLED", "find_unused_port", "bind_port", "open_urlresource",
     "bind_unix_socket",
@@ -281,7 +281,6 @@ max_memuse = 0           # Disable bigmem tests (they will still be run with
                          # small sizes, to make sure they work.)
 real_max_memuse = 0
 failfast = False
-match_tests = None
 
 # _original_stdout is meant to hold stdout at the time regrtest began.
 # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
@@ -779,7 +778,6 @@ is_jython = sys.platform.startswith('java')
 
 _ANDROID_API_LEVEL = sysconfig.get_config_var('ANDROID_API_LEVEL')
 is_android = (_ANDROID_API_LEVEL is not None and _ANDROID_API_LEVEL > 0)
-android_not_root = (is_android and os.geteuid() != 0)
 
 if sys.platform != 'win32':
     unix_shell = '/system/bin/sh' if is_android else '/bin/sh'
@@ -1898,21 +1896,67 @@ def _run_suite(suite):
         raise TestFailed(err)
 
 
-def _match_test(test):
-    global match_tests
+# By default, don't filter tests
+_match_test_func = None
+_match_test_patterns = None
 
-    if match_tests is None:
+
+def match_test(test):
+    # Function used by support.run_unittest() and regrtest --list-cases
+    if _match_test_func is None:
         return True
-    test_id = test.id()
+    else:
+        return _match_test_func(test.id())
 
-    for match_test in match_tests:
-        if fnmatch.fnmatchcase(test_id, match_test):
-            return True
 
-        for name in test_id.split("."):
-            if fnmatch.fnmatchcase(name, match_test):
+def _is_full_match_test(pattern):
+    # If a pattern contains at least one dot, it's considered
+    # as a full test identifier.
+    # Example: 'test.test_os.FileTests.test_access'.
+    #
+    # Reject patterns which contain fnmatch patterns: '*', '?', '[...]'
+    # or '[!...]'. For example, reject 'test_access*'.
+    return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern))
+
+
+def set_match_tests(patterns):
+    global _match_test_func, _match_test_patterns
+
+    if patterns == _match_test_patterns:
+        # No change: no need to recompile patterns.
+        return
+
+    if not patterns:
+        func = None
+        # set_match_tests(None) behaves as set_match_tests(())
+        patterns = ()
+    elif all(map(_is_full_match_test, patterns)):
+        # Simple case: all patterns are full test identifier.
+        # The test.bisect utility only uses such full test identifiers.
+        func = set(patterns).__contains__
+    else:
+        regex = '|'.join(map(fnmatch.translate, patterns))
+        # The search *is* case sensitive on purpose:
+        # don't use flags=re.IGNORECASE
+        regex_match = re.compile(regex).match
+
+        def match_test_regex(test_id):
+            if regex_match(test_id):
+                # The regex matchs the whole identifier like
+                # 'test.test_os.FileTests.test_access'
                 return True
-    return False
+            else:
+                # Try to match parts of the test identifier.
+                # For example, split 'test.test_os.FileTests.test_access'
+                # into: 'test', 'test_os', 'FileTests' and 'test_access'.
+                return any(map(regex_match, test_id.split(".")))
+
+        func = match_test_regex
+
+    # Create a copy since patterns can be mutable and so modified later
+    _match_test_patterns = tuple(patterns)
+    _match_test_func = func
+
 
 
 def run_unittest(*classes):
@@ -1929,7 +1973,7 @@ def run_unittest(*classes):
             suite.addTest(cls)
         else:
             suite.addTest(unittest.makeSuite(cls))
-    _filter_suite(suite, _match_test)
+    _filter_suite(suite, match_test)
     _run_suite(suite)
 
 #=======================================================================
@@ -2621,3 +2665,42 @@ def disable_faulthandler():
     finally:
         if is_enabled:
             faulthandler.enable(file=fd, all_threads=True)
+
+
+class SaveSignals:
+    """
+    Save an restore signal handlers.
+
+    This class is only able to save/restore signal handlers registered
+    by the Python signal module: see bpo-13285 for "external" signal
+    handlers.
+    """
+
+    def __init__(self):
+        import signal
+        self.signal = signal
+        self.signals = list(range(1, signal.NSIG))
+        # SIGKILL and SIGSTOP signals cannot be ignored nor catched
+        for signame in ('SIGKILL', 'SIGSTOP'):
+            try:
+                signum = getattr(signal, signame)
+            except AttributeError:
+                continue
+            self.signals.remove(signum)
+        self.handlers = {}
+
+    def save(self):
+        for signum in self.signals:
+            handler = self.signal.getsignal(signum)
+            if handler is None:
+                # getsignal() returns None if a signal handler was not
+                # registered by the Python signal module,
+                # and the handler is not SIG_DFL nor SIG_IGN.
+                #
+                # Ignore the signal: we cannot restore the handler.
+                continue
+            self.handlers[signum] = handler
+
+    def restore(self):
+        for signum, handler in self.handlers.items():
+            self.signal.signal(signum, handler)
index 8c62408bd8a392d722d3b8278a42712c584e7c5c..e68d0de2f8be1b9c65fcf8281e01beb85995af5d 100644 (file)
@@ -421,6 +421,16 @@ class AST_Tests(unittest.TestCase):
             compile(empty_yield_from, "<test>", "exec")
         self.assertIn("field value is required", str(cm.exception))
 
+    @support.cpython_only
+    def test_issue31592(self):
+        # There shouldn't be an assertion failure in case of a bad
+        # unicodedata.normalize().
+        import unicodedata
+        def bad_normalize(*args):
+            return None
+        with support.swap_attr(unicodedata, 'normalize', bad_normalize):
+            self.assertRaises(TypeError, ast.parse, '\u03D5')
+
 
 class ASTHelpers_Test(unittest.TestCase):
 
index fe5a6dbfe34ecc019ee6d23389569682e546645d..2137cde6f480b7b78af702208d212463d3acf089 100644 (file)
@@ -295,6 +295,23 @@ class QueueGetTests(_QueueTestBase):
                            loop=self.loop),
             )
 
+    def test_cancelled_getters_not_being_held_in_self_getters(self):
+        def a_generator():
+            yield 0.1
+            yield 0.2
+
+        self.loop = self.new_test_loop(a_generator)
+        @asyncio.coroutine
+        def consumer(queue):
+            try:
+                item = yield from asyncio.wait_for(queue.get(), 0.1, loop=self.loop)
+            except asyncio.TimeoutError:
+                pass
+
+        queue = asyncio.Queue(loop=self.loop, maxsize=5)
+        self.loop.run_until_complete(self.loop.create_task(consumer(queue)))
+        self.assertEqual(len(queue._getters), 0)
+
 
 class QueuePutTests(_QueueTestBase):
 
index c50b3e49565c92df33c64e5bc0438a273b498e7f..3477573ec3e7df535d6d324c66978fb0c1db23e8 100644 (file)
@@ -182,7 +182,28 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
 
         f = self.loop.sock_recv(sock, 1024)
         self.assertIsInstance(f, asyncio.Future)
-        self.loop._sock_recv.assert_called_with(f, False, sock, 1024)
+        self.loop._sock_recv.assert_called_with(f, None, sock, 1024)
+
+    def test_sock_recv_reconnection(self):
+        sock = mock.Mock()
+        sock.fileno.return_value = 10
+        sock.recv.side_effect = BlockingIOError
+        sock.gettimeout.return_value = 0.0
+
+        self.loop.add_reader = mock.Mock()
+        self.loop.remove_reader = mock.Mock()
+        fut = self.loop.sock_recv(sock, 1024)
+        callback = self.loop.add_reader.call_args[0][1]
+        params = self.loop.add_reader.call_args[0][2:]
+
+        # emulate the old socket has closed, but the new one has
+        # the same fileno, so callback is called with old (closed) socket
+        sock.fileno.return_value = -1
+        sock.recv.side_effect = OSError(9)
+        callback(*params)
+
+        self.assertIsInstance(fut.exception(), OSError)
+        self.assertEqual((10,), self.loop.remove_reader.call_args[0])
 
     def test__sock_recv_canceled_fut(self):
         sock = mock.Mock()
@@ -190,7 +211,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         f = asyncio.Future(loop=self.loop)
         f.cancel()
 
-        self.loop._sock_recv(f, False, sock, 1024)
+        self.loop._sock_recv(f, None, sock, 1024)
         self.assertFalse(sock.recv.called)
 
     def test__sock_recv_unregister(self):
@@ -201,7 +222,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         f.cancel()
 
         self.loop.remove_reader = mock.Mock()
-        self.loop._sock_recv(f, True, sock, 1024)
+        self.loop._sock_recv(f, 10, sock, 1024)
         self.assertEqual((10,), self.loop.remove_reader.call_args[0])
 
     def test__sock_recv_tryagain(self):
@@ -211,8 +232,8 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.recv.side_effect = BlockingIOError
 
         self.loop.add_reader = mock.Mock()
-        self.loop._sock_recv(f, False, sock, 1024)
-        self.assertEqual((10, self.loop._sock_recv, f, True, sock, 1024),
+        self.loop._sock_recv(f, None, sock, 1024)
+        self.assertEqual((10, self.loop._sock_recv, f, 10, sock, 1024),
                          self.loop.add_reader.call_args[0])
 
     def test__sock_recv_exception(self):
@@ -221,7 +242,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.fileno.return_value = 10
         err = sock.recv.side_effect = OSError()
 
-        self.loop._sock_recv(f, False, sock, 1024)
+        self.loop._sock_recv(f, None, sock, 1024)
         self.assertIs(err, f.exception())
 
     def test_sock_sendall(self):
@@ -231,7 +252,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         f = self.loop.sock_sendall(sock, b'data')
         self.assertIsInstance(f, asyncio.Future)
         self.assertEqual(
-            (f, False, sock, b'data'),
+            (f, None, sock, b'data'),
             self.loop._sock_sendall.call_args[0])
 
     def test_sock_sendall_nodata(self):
@@ -244,13 +265,34 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         self.assertIsNone(f.result())
         self.assertFalse(self.loop._sock_sendall.called)
 
+    def test_sock_sendall_reconnection(self):
+        sock = mock.Mock()
+        sock.fileno.return_value = 10
+        sock.send.side_effect = BlockingIOError
+        sock.gettimeout.return_value = 0.0
+
+        self.loop.add_writer = mock.Mock()
+        self.loop.remove_writer = mock.Mock()
+        fut = self.loop.sock_sendall(sock, b'data')
+        callback = self.loop.add_writer.call_args[0][1]
+        params = self.loop.add_writer.call_args[0][2:]
+
+        # emulate the old socket has closed, but the new one has
+        # the same fileno, so callback is called with old (closed) socket
+        sock.fileno.return_value = -1
+        sock.send.side_effect = OSError(9)
+        callback(*params)
+
+        self.assertIsInstance(fut.exception(), OSError)
+        self.assertEqual((10,), self.loop.remove_writer.call_args[0])
+
     def test__sock_sendall_canceled_fut(self):
         sock = mock.Mock()
 
         f = asyncio.Future(loop=self.loop)
         f.cancel()
 
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertFalse(sock.send.called)
 
     def test__sock_sendall_unregister(self):
@@ -261,7 +303,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         f.cancel()
 
         self.loop.remove_writer = mock.Mock()
-        self.loop._sock_sendall(f, True, sock, b'data')
+        self.loop._sock_sendall(f, 10, sock, b'data')
         self.assertEqual((10,), self.loop.remove_writer.call_args[0])
 
     def test__sock_sendall_tryagain(self):
@@ -271,9 +313,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.send.side_effect = BlockingIOError
 
         self.loop.add_writer = mock.Mock()
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertEqual(
-            (10, self.loop._sock_sendall, f, True, sock, b'data'),
+            (10, self.loop._sock_sendall, f, 10, sock, b'data'),
             self.loop.add_writer.call_args[0])
 
     def test__sock_sendall_interrupted(self):
@@ -283,9 +325,9 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.send.side_effect = InterruptedError
 
         self.loop.add_writer = mock.Mock()
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertEqual(
-            (10, self.loop._sock_sendall, f, True, sock, b'data'),
+            (10, self.loop._sock_sendall, f, 10, sock, b'data'),
             self.loop.add_writer.call_args[0])
 
     def test__sock_sendall_exception(self):
@@ -294,7 +336,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.fileno.return_value = 10
         err = sock.send.side_effect = OSError()
 
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertIs(f.exception(), err)
 
     def test__sock_sendall(self):
@@ -304,7 +346,7 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.fileno.return_value = 10
         sock.send.return_value = 4
 
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertTrue(f.done())
         self.assertIsNone(f.result())
 
@@ -316,10 +358,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.send.return_value = 2
 
         self.loop.add_writer = mock.Mock()
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertFalse(f.done())
         self.assertEqual(
-            (10, self.loop._sock_sendall, f, True, sock, b'ta'),
+            (10, self.loop._sock_sendall, f, 10, sock, b'ta'),
             self.loop.add_writer.call_args[0])
 
     def test__sock_sendall_none(self):
@@ -330,10 +372,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase):
         sock.send.return_value = 0
 
         self.loop.add_writer = mock.Mock()
-        self.loop._sock_sendall(f, False, sock, b'data')
+        self.loop._sock_sendall(f, None, sock, b'data')
         self.assertFalse(f.done())
         self.assertEqual(
-            (10, self.loop._sock_sendall, f, True, sock, b'data'),
+            (10, self.loop._sock_sendall, f, 10, sock, b'data'),
             self.loop.add_writer.call_args[0])
 
     def test_sock_connect_timeout(self):
index bcd236ea2632ed728a91a4b485b68ed7c5535f14..f573ae8fe779e7f11af44eec1e2b44b022d0baa8 100644 (file)
@@ -121,6 +121,14 @@ class SslProtoHandshakeTests(test_utils.TestCase):
         ssl_proto.connection_lost(None)
         self.assertIsNone(ssl_proto._get_extra_info('socket'))
 
+    def test_set_new_app_protocol(self):
+        waiter = asyncio.Future(loop=self.loop)
+        ssl_proto = self.ssl_protocol(waiter)
+        new_app_proto = asyncio.Protocol()
+        ssl_proto._app_transport.set_protocol(new_app_proto)
+        self.assertIs(ssl_proto._app_transport.get_protocol(), new_app_proto)
+        self.assertIs(ssl_proto._app_protocol, new_app_proto)
+
 
 if __name__ == '__main__':
     unittest.main()
index b47433a4cfdbd41d11cf1bf59963a6f7f14fde65..6d16d2007967d319e1210be5ef47ff0dcb80ef65 100644 (file)
@@ -3,6 +3,7 @@
 import gc
 import os
 import queue
+import pickle
 import socket
 import sys
 import threading
@@ -845,6 +846,23 @@ os.close(fd)
         stream._transport.__repr__.return_value = "<Transport>"
         self.assertEqual("<StreamReader t=<Transport>>", repr(stream))
 
+    def test_IncompleteReadError_pickleable(self):
+        e = asyncio.IncompleteReadError(b'abc', 10)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            with self.subTest(pickle_protocol=proto):
+                e2 = pickle.loads(pickle.dumps(e, protocol=proto))
+                self.assertEqual(str(e), str(e2))
+                self.assertEqual(e.partial, e2.partial)
+                self.assertEqual(e.expected, e2.expected)
+
+    def test_LimitOverrunError_pickleable(self):
+        e = asyncio.LimitOverrunError('message', 10)
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            with self.subTest(pickle_protocol=proto):
+                e2 = pickle.loads(pickle.dumps(e, protocol=proto))
+                self.assertEqual(str(e), str(e2))
+                self.assertEqual(e.consumed, e2.consumed)
+
 
 if __name__ == '__main__':
     unittest.main()
index 243faf6b04995875f2a76ca8040635c06a086b44..42da1fa19548f1c54458dfec824526ebf0b7b7e6 100644 (file)
@@ -1918,7 +1918,7 @@ class BaseTaskTests:
 
         regex = (r'^<CoroWrapper %s\(?\)? .* at %s:%s, .*> '
                     r'was never yielded from\n'
-                 r'Coroutine object created at \(most recent call last\):\n'
+                 r'Coroutine object created at \(most recent call last, truncated to \d+ last lines\):\n'
                  r'.*\n'
                  r'  File "%s", line %s, in test_coroutine_never_yielded\n'
                  r'    coro_noop\(\)$'
index b83f2f107c1c7cb46331b8bbee73514abafb4460..f302da415d33f314fb1c5a057013c52502797df3 100644 (file)
@@ -17,7 +17,7 @@ from test import support
 from itertools import permutations, product
 from random import randrange, sample, choice
 import warnings
-import sys, array, io
+import sys, array, io, os
 from decimal import Decimal
 from fractions import Fraction
 
@@ -37,7 +37,8 @@ except ImportError:
     ctypes = None
 
 try:
-    with warnings.catch_warnings():
+    with support.EnvironmentVarGuard() as os.environ, \
+         warnings.catch_warnings():
         from numpy import ndarray as numpy_array
 except ImportError:
     numpy_array = None
index cd82fa64570cb5ed4a73fd61415734d61aff1295..6fcc26a0a1bf7900ed42509cb349563c089749b1 100644 (file)
@@ -540,8 +540,16 @@ class BaseBytesTest:
         self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
         self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
 
+    def test_replace_int_error(self):
+        self.assertRaises(TypeError, self.type2test(b'a b').replace, 32, b'')
+
     def test_split_string_error(self):
         self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
+        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
+
+    def test_split_int_error(self):
+        self.assertRaises(TypeError, self.type2test(b'a b').split, 32)
+        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, 32)
 
     def test_split_unicodewhitespace(self):
         for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
@@ -550,9 +558,6 @@ class BaseBytesTest:
         b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
         self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
 
-    def test_rsplit_string_error(self):
-        self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
-
     def test_rsplit_unicodewhitespace(self):
         b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
         self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
@@ -568,6 +573,14 @@ class BaseBytesTest:
         self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
         self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
 
+    def test_partition_string_error(self):
+        self.assertRaises(TypeError, self.type2test(b'a b').partition, ' ')
+        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, ' ')
+
+    def test_partition_int_error(self):
+        self.assertRaises(TypeError, self.type2test(b'a b').partition, 32)
+        self.assertRaises(TypeError, self.type2test(b'a b').rpartition, 32)
+
     def test_pickling(self):
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
@@ -600,9 +613,14 @@ class BaseBytesTest:
         self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
 
     def test_strip_string_error(self):
-        self.assertRaises(TypeError, self.type2test(b'abc').strip, 'b')
-        self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'b')
-        self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'b')
+        self.assertRaises(TypeError, self.type2test(b'abc').strip, 'ac')
+        self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'ac')
+        self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'ac')
+
+    def test_strip_int_error(self):
+        self.assertRaises(TypeError, self.type2test(b' abc ').strip, 32)
+        self.assertRaises(TypeError, self.type2test(b' abc ').lstrip, 32)
+        self.assertRaises(TypeError, self.type2test(b' abc ').rstrip, 32)
 
     def test_center(self):
         # Fill character can be either bytes or bytearray (issue 12380)
@@ -625,6 +643,11 @@ class BaseBytesTest:
             self.assertEqual(b.rjust(7, fill_type(b'-')),
                              self.type2test(b'----abc'))
 
+    def test_xjust_int_error(self):
+        self.assertRaises(TypeError, self.type2test(b'abc').center, 7, 32)
+        self.assertRaises(TypeError, self.type2test(b'abc').ljust, 7, 32)
+        self.assertRaises(TypeError, self.type2test(b'abc').rjust, 7, 32)
+
     def test_ord(self):
         b = self.type2test(b'\0A\x7f\x80\xff')
         self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
index 216851c2d36c8b429626f2d5976f0973338f4e06..6e4286ed881aa296126ee3939b05827328271e86 100644 (file)
@@ -13,7 +13,7 @@ import time
 import unittest
 from test import support
 from test.support import MISSING_C_DOCSTRINGS
-from test.support.script_helper import assert_python_failure
+from test.support.script_helper import assert_python_failure, assert_python_ok
 try:
     import _posixsubprocess
 except ImportError:
@@ -241,6 +241,38 @@ class CAPITest(unittest.TestCase):
     def test_buildvalue_N(self):
         _testcapi.test_buildvalue_N()
 
+    def test_set_nomemory(self):
+        code = """if 1:
+            import _testcapi
+
+            class C(): pass
+
+            # The first loop tests both functions and that remove_mem_hooks()
+            # can be called twice in a row. The second loop checks a call to
+            # set_nomemory() after a call to remove_mem_hooks(). The third
+            # loop checks the start and stop arguments of set_nomemory().
+            for outer_cnt in range(1, 4):
+                start = 10 * outer_cnt
+                for j in range(100):
+                    if j == 0:
+                        if outer_cnt != 3:
+                            _testcapi.set_nomemory(start)
+                        else:
+                            _testcapi.set_nomemory(start, start + 1)
+                    try:
+                        C()
+                    except MemoryError as e:
+                        if outer_cnt != 3:
+                            _testcapi.remove_mem_hooks()
+                        print('MemoryError', outer_cnt, j)
+                        _testcapi.remove_mem_hooks()
+                        break
+        """
+        rc, out, err = assert_python_ok('-c', code)
+        self.assertIn(b'MemoryError 1 10', out)
+        self.assertIn(b'MemoryError 2 20', out)
+        self.assertIn(b'MemoryError 3 30', out)
+
 
 @unittest.skipUnless(threading, 'Threading required for this test.')
 class TestPendingCalls(unittest.TestCase):
@@ -369,23 +401,30 @@ class EmbeddingTests(unittest.TestCase):
     def tearDown(self):
         os.chdir(self.oldcwd)
 
-    def run_embedded_interpreter(self, *args):
+    def run_embedded_interpreter(self, *args, env=None):
         """Runs a test in the embedded interpreter"""
         cmd = [self.test_exe]
         cmd.extend(args)
+        if env is not None and sys.platform == 'win32':
+            # Windows requires at least the SYSTEMROOT environment variable to
+            # start Python.
+            env = env.copy()
+            env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
+
         p = subprocess.Popen(cmd,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE,
-                             universal_newlines=True)
+                             universal_newlines=True,
+                             env=env)
         (out, err) = p.communicate()
         self.assertEqual(p.returncode, 0,
                          "bad returncode %d, stderr is %r" %
                          (p.returncode, err))
         return out, err
 
-    def test_subinterps(self):
+    def test_repeated_init_and_subinterpreters(self):
         # This is just a "don't crash" test
-        out, err = self.run_embedded_interpreter()
+        out, err = self.run_embedded_interpreter('repeated_init_and_subinterpreters')
         if support.verbose:
             print()
             print(out)
@@ -403,13 +442,14 @@ class EmbeddingTests(unittest.TestCase):
 
     def test_forced_io_encoding(self):
         # Checks forced configuration of embedded interpreter IO streams
-        out, err = self.run_embedded_interpreter("forced_io_encoding")
+        env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape")
+        out, err = self.run_embedded_interpreter("forced_io_encoding", env=env)
         if support.verbose:
             print()
             print(out)
             print(err)
-        expected_errors = sys.__stdout__.errors
-        expected_stdin_encoding = sys.__stdin__.encoding
+        expected_stream_encoding = "utf-8"
+        expected_errors = "surrogateescape"
         expected_pipe_encoding = self._get_default_pipe_encoding()
         expected_output = '\n'.join([
         "--- Use defaults ---",
@@ -437,13 +477,33 @@ class EmbeddingTests(unittest.TestCase):
         "stdout: latin-1:replace",
         "stderr: latin-1:backslashreplace"])
         expected_output = expected_output.format(
-                                in_encoding=expected_stdin_encoding,
-                                out_encoding=expected_pipe_encoding,
+                                in_encoding=expected_stream_encoding,
+                                out_encoding=expected_stream_encoding,
                                 errors=expected_errors)
         # This is useful if we ever trip over odd platform behaviour
         self.maxDiff = None
         self.assertEqual(out.strip(), expected_output)
 
+    def test_pre_initialization_api(self):
+        """
+        Checks the few parts of the C-API that work before the runtine
+        is initialized (via Py_Initialize()).
+        """
+        env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
+        out, err = self.run_embedded_interpreter("pre_initialization_api", env=env)
+        self.assertEqual(out, '')
+        self.assertEqual(err, '')
+
+    def test_bpo20891(self):
+        """
+        bpo-20891: Calling PyGILState_Ensure in a non-Python thread before
+        calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must
+        call PyEval_InitThreads() for us in this case.
+        """
+        out, err = self.run_embedded_interpreter("bpo20891")
+        self.assertEqual(out, '')
+        self.assertEqual(err, '')
+
 
 class SkipitemTest(unittest.TestCase):
 
index 68537482ac91f3415fa339e1577d51a8e80dc7c4..55faf4c4279fb6ce4be91e3db798fadc0c31e1b7 100644 (file)
@@ -102,6 +102,7 @@ consts: ('None',)
 
 """
 
+import inspect
 import sys
 import threading
 import unittest
@@ -130,6 +131,10 @@ def dump(co):
         print("%s: %s" % (attr, getattr(co, "co_" + attr)))
     print("consts:", tuple(consts(co.co_consts)))
 
+# Needed for test_closure_injection below
+# Defined at global scope to avoid implicitly closing over __class__
+def external_getitem(self, i):
+    return f"Foreign getitem: {super().__getitem__(i)}"
 
 class CodeTest(unittest.TestCase):
 
@@ -141,6 +146,46 @@ class CodeTest(unittest.TestCase):
         self.assertEqual(co.co_name, "funcname")
         self.assertEqual(co.co_firstlineno, 15)
 
+    @cpython_only
+    def test_closure_injection(self):
+        # From https://bugs.python.org/issue32176
+        from types import FunctionType, CodeType
+
+        def create_closure(__class__):
+            return (lambda: __class__).__closure__
+
+        def new_code(c):
+            '''A new code object with a __class__ cell added to freevars'''
+            return CodeType(
+                c.co_argcount, c.co_kwonlyargcount, c.co_nlocals,
+                c.co_stacksize, c.co_flags, c.co_code, c.co_consts, c.co_names,
+                c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno,
+                c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars)
+
+        def add_foreign_method(cls, name, f):
+            code = new_code(f.__code__)
+            assert not f.__closure__
+            closure = create_closure(cls)
+            defaults = f.__defaults__
+            setattr(cls, name, FunctionType(code, globals(), name, defaults, closure))
+
+        class List(list):
+            pass
+
+        add_foreign_method(List, "__getitem__", external_getitem)
+
+        # Ensure the closure injection actually worked
+        function = List.__getitem__
+        class_ref = function.__closure__[0].cell_contents
+        self.assertIs(class_ref, List)
+
+        # Ensure the code correctly indicates it accesses a free variable
+        self.assertFalse(function.__code__.co_flags & inspect.CO_NOFREE,
+                         hex(function.__code__.co_flags))
+
+        # Ensure the zero-arg super() call in the injected method works
+        obj = List([1, 2, 3])
+        self.assertEqual(obj[0], "Foreign getitem: 1")
 
 def isinterned(s):
     return s is sys.intern(('_' + s + '_')[1:-1])
@@ -231,7 +276,7 @@ if check_impl_detail(cpython=True) and ctypes is not None:
     SetExtra.restype = ctypes.c_int
 
     GetExtra = py._PyCode_GetExtra
-    GetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, 
+    GetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t,
                          ctypes.POINTER(ctypes.c_voidp))
     GetExtra.restype = ctypes.c_int
 
index 1a8f6990dfb7ec707ad6875840ac2c02cfa48d11..24db0ace80122e707b77aad253c5045994008fa9 100644 (file)
@@ -28,16 +28,24 @@ class TestInteractiveConsole(unittest.TestCase):
         self.sysmod = stack.enter_context(prepatch)
         if sys.excepthook is sys.__excepthook__:
             self.sysmod.excepthook = self.sysmod.__excepthook__
+        del self.sysmod.ps1
+        del self.sysmod.ps2
 
     def test_ps1(self):
         self.infunc.side_effect = EOFError('Finished')
         self.console.interact()
         self.assertEqual(self.sysmod.ps1, '>>> ')
+        self.sysmod.ps1 = 'custom1> '
+        self.console.interact()
+        self.assertEqual(self.sysmod.ps1, 'custom1> ')
 
     def test_ps2(self):
         self.infunc.side_effect = EOFError('Finished')
         self.console.interact()
         self.assertEqual(self.sysmod.ps2, '... ')
+        self.sysmod.ps1 = 'custom2> '
+        self.console.interact()
+        self.assertEqual(self.sysmod.ps1, 'custom2> ')
 
     def test_console_stderr(self):
         self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')]
index 1e63ed8d79381b1f8d3f6ac097640e8845461c34..eb21a3915b938a96664ea68fb56f0e5545bcd673 100644 (file)
@@ -196,19 +196,33 @@ class ReadTest(MixInCheckStateHandling):
         self.assertEqual(f.read(), ''.join(lines[1:]))
         self.assertEqual(f.read(), '')
 
+        # Issue #32110: Test readline() followed by read(n)
+        f = getreader()
+        self.assertEqual(f.readline(), lines[0])
+        self.assertEqual(f.read(1), lines[1][0])
+        self.assertEqual(f.read(0), '')
+        self.assertEqual(f.read(100), data[len(lines[0]) + 1:][:100])
+
         # Issue #16636: Test readline() followed by readlines()
         f = getreader()
         self.assertEqual(f.readline(), lines[0])
         self.assertEqual(f.readlines(), lines[1:])
         self.assertEqual(f.read(), '')
 
-        # Test read() followed by read()
+        # Test read(n) followed by read()
         f = getreader()
         self.assertEqual(f.read(size=40, chars=5), data[:5])
         self.assertEqual(f.read(), data[5:])
         self.assertEqual(f.read(), '')
 
-        # Issue #12446: Test read() followed by readlines()
+        # Issue #32110: Test read(n) followed by read(n)
+        f = getreader()
+        self.assertEqual(f.read(size=40, chars=5), data[:5])
+        self.assertEqual(f.read(1), data[5])
+        self.assertEqual(f.read(0), '')
+        self.assertEqual(f.read(100), data[6:106])
+
+        # Issue #12446: Test read(n) followed by readlines()
         f = getreader()
         self.assertEqual(f.read(size=40, chars=5), data[:5])
         self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:])
@@ -1203,6 +1217,8 @@ class EscapeDecodeTest(unittest.TestCase):
             check(br"\8", b"\\8")
         with self.assertWarns(DeprecationWarning):
             check(br"\9", b"\\9")
+        with self.assertWarns(DeprecationWarning):
+            check(b"\\\xfa", b"\\\xfa")
 
     def test_errors(self):
         decode = codecs.escape_decode
@@ -2474,6 +2490,8 @@ class UnicodeEscapeTest(unittest.TestCase):
             check(br"\8", "\\8")
         with self.assertWarns(DeprecationWarning):
             check(br"\9", "\\9")
+        with self.assertWarns(DeprecationWarning):
+            check(b"\\\xfa", "\\\xfa")
 
     def test_decode_errors(self):
         decode = codecs.unicode_escape_decode
index e4f58979c13567276a4f7da23237ab1b8e5e42ce..44a3ad44892b9986197670b066c849bbb73a85bf 100644 (file)
@@ -1,33 +1,45 @@
+import sys
 from test import support
 import unittest
 
 crypt = support.import_module('crypt')
 
+if sys.platform.startswith('openbsd'):
+    raise unittest.SkipTest('The only supported method on OpenBSD is Blowfish')
+
 class CryptTestCase(unittest.TestCase):
 
     def test_crypt(self):
-        c = crypt.crypt('mypassword', 'ab')
-        if support.verbose:
-            print('Test encryption: ', c)
+        cr = crypt.crypt('mypassword')
+        cr2 = crypt.crypt('mypassword', cr)
+        self.assertEqual(cr2, cr)
+        cr = crypt.crypt('mypassword', 'ab')
+        if cr is not None:
+            cr2 = crypt.crypt('mypassword', cr)
+            self.assertEqual(cr2, cr)
 
     def test_salt(self):
         self.assertEqual(len(crypt._saltchars), 64)
         for method in crypt.methods:
             salt = crypt.mksalt(method)
-            self.assertEqual(len(salt),
-                    method.salt_chars + (3 if method.ident else 0))
+            self.assertIn(len(salt) - method.salt_chars, {0, 1, 3, 4, 6, 7})
+            if method.ident:
+                self.assertIn(method.ident, salt[:len(salt)-method.salt_chars])
 
     def test_saltedcrypt(self):
         for method in crypt.methods:
-            pw = crypt.crypt('assword', method)
-            self.assertEqual(len(pw), method.total_size)
-            pw = crypt.crypt('assword', crypt.mksalt(method))
-            self.assertEqual(len(pw), method.total_size)
+            cr = crypt.crypt('assword', method)
+            self.assertEqual(len(cr), method.total_size)
+            cr2 = crypt.crypt('assword', cr)
+            self.assertEqual(cr2, cr)
+            cr = crypt.crypt('assword', crypt.mksalt(method))
+            self.assertEqual(len(cr), method.total_size)
 
     def test_methods(self):
         # Guarantee that METHOD_CRYPT is the last method in crypt.methods.
         self.assertTrue(len(crypt.methods) >= 1)
         self.assertEqual(crypt.METHOD_CRYPT, crypt.methods[-1])
 
+
 if __name__ == "__main__":
     unittest.main()
index 0d0b160d7645a55a1b1f3f90e4c23c4255b2cc30..3b442fe6a4b7aa8876255c1ca203049cb3bd4b9c 100644 (file)
@@ -15,7 +15,7 @@ import sys
 import tempfile
 import unittest
 
-from test.support import requires, import_module, verbose
+from test.support import requires, import_module, verbose, SaveSignals
 
 # Optionally test curses module.  This currently requires that the
 # 'curses' resource be given on the regrtest command line using the -u
@@ -25,9 +25,12 @@ requires('curses')
 
 # If either of these don't exist, skip the tests.
 curses = import_module('curses')
-import_module('curses.panel')
 import_module('curses.ascii')
 import_module('curses.textpad')
+try:
+    import curses.panel
+except ImportError:
+    pass
 
 def requires_curses_func(name):
     return unittest.skipUnless(hasattr(curses, name),
@@ -63,6 +66,8 @@ class TestCurses(unittest.TestCase):
             del cls.tmp
 
     def setUp(self):
+        self.save_signals = SaveSignals()
+        self.save_signals.save()
         if verbose:
             # just to make the test output a little more readable
             print()
@@ -72,6 +77,7 @@ class TestCurses(unittest.TestCase):
     def tearDown(self):
         curses.resetty()
         curses.endwin()
+        self.save_signals.restore()
 
     def test_window_funcs(self):
         "Test the methods of windows"
@@ -86,7 +92,7 @@ class TestCurses(unittest.TestCase):
                 with self.subTest(meth=meth.__qualname__, args=args):
                     meth(*args)
 
-        for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
+        for meth in [stdscr.clear, stdscr.clrtobot,
                      stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
                      stdscr.deleteln, stdscr.erase, stdscr.getbegyx,
                      stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx,
@@ -120,6 +126,13 @@ class TestCurses(unittest.TestCase):
             win.border(65, 66, 67, 68,
                        69, [], 71, 72)
 
+        win.box(65, 67)
+        win.box('!', '_')
+        win.box(b':', b'~')
+        self.assertRaises(TypeError, win.box, 65, 66, 67)
+        self.assertRaises(TypeError, win.box, 65)
+        win.box()
+
         stdscr.clearok(1)
 
         win4 = stdscr.derwin(2,2)
@@ -135,7 +148,9 @@ class TestCurses(unittest.TestCase):
 
         stdscr.idcok(1)
         stdscr.idlok(1)
-        stdscr.immedok(1)
+        if hasattr(stdscr, 'immedok'):
+            stdscr.immedok(1)
+            stdscr.immedok(0)
         stdscr.insch('c')
         stdscr.insdelln(1)
         stdscr.insnstr('abc', 3)
@@ -169,25 +184,27 @@ class TestCurses(unittest.TestCase):
         stdscr.setscrreg(10,15)
         win3 = stdscr.subwin(10,10)
         win3 = stdscr.subwin(10,10, 5,5)
-        stdscr.syncok(1)
+        if hasattr(stdscr, 'syncok') and not sys.platform.startswith("sunos"):
+            stdscr.syncok(1)
         stdscr.timeout(5)
         stdscr.touchline(5,5)
         stdscr.touchline(5,5,0)
         stdscr.vline('a', 3)
         stdscr.vline('a', 3, curses.A_STANDOUT)
-        stdscr.chgat(5, 2, 3, curses.A_BLINK)
-        stdscr.chgat(3, curses.A_BOLD)
-        stdscr.chgat(5, 8, curses.A_UNDERLINE)
-        stdscr.chgat(curses.A_BLINK)
+        if hasattr(stdscr, 'chgat'):
+            stdscr.chgat(5, 2, 3, curses.A_BLINK)
+            stdscr.chgat(3, curses.A_BOLD)
+            stdscr.chgat(5, 8, curses.A_UNDERLINE)
+            stdscr.chgat(curses.A_BLINK)
         stdscr.refresh()
 
         stdscr.vline(1,1, 'a', 3)
         stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT)
 
-        if hasattr(curses, 'resize'):
-            stdscr.resize()
-        if hasattr(curses, 'enclose'):
-            stdscr.enclose()
+        if hasattr(stdscr, 'resize'):
+            stdscr.resize(25, 80)
+        if hasattr(stdscr, 'enclose'):
+            stdscr.enclose(10, 10)
 
         self.assertRaises(ValueError, stdscr.getstr, -400)
         self.assertRaises(ValueError, stdscr.getstr, 2, 3, -400)
@@ -208,15 +225,19 @@ class TestCurses(unittest.TestCase):
         "Test module-level functions"
         for func in [curses.baudrate, curses.beep, curses.can_change_color,
                      curses.cbreak, curses.def_prog_mode, curses.doupdate,
-                     curses.filter, curses.flash, curses.flushinp,
+                     curses.flash, curses.flushinp,
                      curses.has_colors, curses.has_ic, curses.has_il,
                      curses.isendwin, curses.killchar, curses.longname,
                      curses.nocbreak, curses.noecho, curses.nonl,
                      curses.noqiflush, curses.noraw,
                      curses.reset_prog_mode, curses.termattrs,
-                     curses.termname, curses.erasechar, curses.getsyx]:
+                     curses.termname, curses.erasechar]:
             with self.subTest(func=func.__qualname__):
                 func()
+        if hasattr(curses, 'filter'):
+            curses.filter()
+        if hasattr(curses, 'getsyx'):
+            curses.getsyx()
 
         # Functions that actually need arguments
         if curses.tigetstr("cnorm"):
@@ -240,15 +261,18 @@ class TestCurses(unittest.TestCase):
         curses.putp(b'abc')
         curses.qiflush()
         curses.raw() ; curses.raw(1)
-        curses.setsyx(5,5)
+        if hasattr(curses, 'setsyx'):
+            curses.setsyx(5,5)
         curses.tigetflag('hc')
         curses.tigetnum('co')
         curses.tigetstr('cr')
         curses.tparm(b'cr')
-        curses.typeahead(sys.__stdin__.fileno())
+        if hasattr(curses, 'typeahead'):
+            curses.typeahead(sys.__stdin__.fileno())
         curses.unctrl('a')
         curses.ungetch('a')
-        curses.use_env(1)
+        if hasattr(curses, 'use_env'):
+            curses.use_env(1)
 
     # Functions only available on a few platforms
     def test_colors_funcs(self):
@@ -282,6 +306,7 @@ class TestCurses(unittest.TestCase):
         curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED)
         m = curses.getmouse()
 
+    @requires_curses_func('panel')
     def test_userptr_without_set(self):
         w = curses.newwin(10, 10)
         p = curses.panel.new_panel(w)
@@ -290,6 +315,7 @@ class TestCurses(unittest.TestCase):
                                msg='userptr should fail since not set'):
             p.userptr()
 
+    @requires_curses_func('panel')
     def test_userptr_memory_leak(self):
         w = curses.newwin(10, 10)
         p = curses.panel.new_panel(w)
@@ -302,16 +328,20 @@ class TestCurses(unittest.TestCase):
         self.assertEqual(sys.getrefcount(obj), nrefs,
                          "set_userptr leaked references")
 
+    @requires_curses_func('panel')
     def test_userptr_segfault(self):
-        panel = curses.panel.new_panel(self.stdscr)
+        w = curses.newwin(10, 10)
+        panel = curses.panel.new_panel(w)
         class A:
             def __del__(self):
                 panel.set_userptr(None)
         panel.set_userptr(A())
         panel.set_userptr(None)
 
+    @requires_curses_func('panel')
     def test_new_curses_panel(self):
-        panel = curses.panel.new_panel(self.stdscr)
+        w = curses.newwin(10, 10)
+        panel = curses.panel.new_panel(w)
         self.assertRaises(TypeError, type(panel))
 
     @requires_curses_func('is_term_resized')
@@ -338,6 +368,9 @@ class TestCurses(unittest.TestCase):
         self.stdscr.getkey()
 
     @requires_curses_func('unget_wch')
+    # XXX Remove the decorator when ncurses on OpenBSD be updated
+    @unittest.skipIf(sys.platform.startswith("openbsd"),
+                     "OpenBSD's curses (v.5.7) has bugs")
     def test_unget_wch(self):
         stdscr = self.stdscr
         encoding = stdscr.encoding
@@ -404,6 +437,8 @@ class TestCurses(unittest.TestCase):
 
     def test_issue13051(self):
         stdscr = self.stdscr
+        if not hasattr(stdscr, 'resize'):
+            raise unittest.SkipTest('requires curses.window.resize')
         box = curses.textpad.Textbox(stdscr, insert_mode=True)
         lines, cols = stdscr.getmaxyx()
         stdscr.resize(lines-2, cols-2)
index e0ec87d2080185d5a9eac459470c07694d2ad5ab..1667617b9e465f1819a9985397e5e2f969b18f9b 100644 (file)
@@ -14,18 +14,7 @@ class TestTokens(TestEmailBase):
         self.assertEqual(x, ' \t')
         self.assertEqual(str(x), '')
         self.assertEqual(x.value, '')
-        self.assertEqual(x.encoded, ' \t')
-
-    # UnstructuredTokenList
-
-    def test_undecodable_bytes_error_preserved(self):
-        badstr = b"le pouf c\xaflebre".decode('ascii', 'surrogateescape')
-        unst = parser.get_unstructured(badstr)
-        self.assertDefectsEqual(unst.all_defects, [errors.UndecodableBytesDefect])
-        parts = list(unst.parts)
-        self.assertDefectsEqual(parts[0].all_defects, [])
-        self.assertDefectsEqual(parts[1].all_defects, [])
-        self.assertDefectsEqual(parts[2].all_defects, [errors.UndecodableBytesDefect])
+        self.assertEqual(x.token_type, 'fws')
 
 
 class TestParserMixin:
@@ -139,7 +128,6 @@ class TestParser(TestParserMixin, TestEmailBase):
                          'first second',
                          [],
                          '')
-        self.assertEqual(ew.encoded, '=?us-ascii*jive?q?first_second?=')
         self.assertEqual(ew.charset, 'us-ascii')
         self.assertEqual(ew.lang, 'jive')
 
@@ -150,7 +138,6 @@ class TestParser(TestParserMixin, TestEmailBase):
                          'first second',
                          [],
                          '')
-        self.assertEqual(ew.encoded, '=?us-ascii?q?first_second?=')
         self.assertEqual(ew.charset, 'us-ascii')
         self.assertEqual(ew.lang, '')
 
@@ -2700,28 +2687,37 @@ class TestFolding(TestEmailBase):
     # and with unicode tokens in the comments.  Spaces inside the quotes
     # currently don't do the right thing.
 
-    def test_initial_whitespace_splitting(self):
+    def test_split_at_whitespace_after_header_before_long_token(self):
         body = parser.get_unstructured('   ' + 'x'*77)
         header = parser.Header([
             parser.HeaderLabel([parser.ValueTerminal('test:', 'atext')]),
             parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')]), body])
         self._test(header, 'test:   \n ' + 'x'*77 + '\n')
 
-    def test_whitespace_splitting(self):
+    def test_split_at_whitespace_before_long_token(self):
         self._test(parser.get_unstructured('xxx   ' + 'y'*77),
                    'xxx  \n ' + 'y'*77 + '\n')
 
+    def test_overlong_encodeable_is_wrapped(self):
+        first_token_with_whitespace = 'xxx   '
+        chrome_leader = '=?utf-8?q?'
+        len_chrome = len(chrome_leader) + 2
+        len_non_y = len_chrome + len(first_token_with_whitespace)
+        self._test(parser.get_unstructured(first_token_with_whitespace +
+                                           'y'*80),
+                   first_token_with_whitespace + chrome_leader +
+                       'y'*(78-len_non_y) + '?=\n' +
+                       ' ' + chrome_leader + 'y'*(80-(78-len_non_y)) + '?=\n')
+
     def test_long_filename_attachment(self):
-        folded = self.policy.fold('Content-Disposition', 'attachment; filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TES.txt"')
-        self.assertEqual(
-            'Content-Disposition: attachment;\n filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TES.txt"\n',
-            folded
-        )
-        folded = self.policy.fold('Content-Disposition', 'attachment; filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_T.txt"')
-        self.assertEqual(
-            'Content-Disposition: attachment;\n filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_T.txt"\n',
-            folded
-        )
+        self._test(parser.parse_content_disposition_header(
+            'attachment; filename="TEST_TEST_TEST_TEST'
+                '_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TES.txt"'),
+            "attachment;\n"
+            " filename*0*=us-ascii''TEST_TEST_TEST_TEST_TEST_TEST"
+                "_TEST_TEST_TEST_TEST_TEST;\n"
+            " filename*1*=_TEST_TES.txt\n",
+            )
 
 if __name__ == '__main__':
     unittest.main()
index c4f182903afefea848983045a42ef6dec3baecc4..c1aeaefab775ffa81195d8ea2eaa208741de86fc 100644 (file)
@@ -27,7 +27,6 @@ class TestGeneratorBase:
 
             None
             """),
-        # From is wrapped because wrapped it fits in 40.
         40: textwrap.dedent("""\
             To: whom_it_may_concern@example.com
             From:
@@ -40,11 +39,11 @@ class TestGeneratorBase:
 
             None
             """),
-        # Neither to nor from fit even if put on a new line,
-        # so we leave them sticking out on the first line.
         20: textwrap.dedent("""\
-            To: whom_it_may_concern@example.com
-            From: nobody_you_want_to_know@example.com
+            To:
+             whom_it_may_concern@example.com
+            From:
+             nobody_you_want_to_know@example.com
             Subject: We the
              willing led by the
              unknowing are doing
@@ -169,6 +168,53 @@ class TestGeneratorBase:
         g.flatten(msg)
         self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[0]))
 
+    def test_rfc2231_wrapping(self):
+        # This is pretty much just to make sure we don't have an infinite
+        # loop; I don't expect anyone to hit this in the field.
+        msg = self.msgmaker(self.typ(textwrap.dedent("""\
+            To: nobody
+            Content-Disposition: attachment;
+             filename="afilenamelongenoghtowraphere"
+
+            None
+            """)))
+        expected = textwrap.dedent("""\
+            To: nobody
+            Content-Disposition: attachment;
+             filename*0*=us-ascii''afilename;
+             filename*1*=longenoghtowraphere
+
+            None
+            """)
+        s = self.ioclass()
+        g = self.genclass(s, policy=self.policy.clone(max_line_length=33))
+        g.flatten(msg)
+        self.assertEqual(s.getvalue(), self.typ(expected))
+
+    def test_rfc2231_wrapping_switches_to_default_len_if_too_narrow(self):
+        # This is just to make sure we don't have an infinite loop; I don't
+        # expect anyone to hit this in the field, so I'm not bothering to make
+        # the result optimal (the encoding isn't needed).
+        msg = self.msgmaker(self.typ(textwrap.dedent("""\
+            To: nobody
+            Content-Disposition: attachment;
+             filename="afilenamelongenoghtowraphere"
+
+            None
+            """)))
+        expected = textwrap.dedent("""\
+            To: nobody
+            Content-Disposition:
+             attachment;
+             filename*0*=us-ascii''afilenamelongenoghtowraphere
+
+            None
+            """)
+        s = self.ioclass()
+        g = self.genclass(s, policy=self.policy.clone(max_line_length=20))
+        g.flatten(msg)
+        self.assertEqual(s.getvalue(), self.typ(expected))
+
 
 class TestGenerator(TestGeneratorBase, TestEmailBase):
 
index af836dc972662230ce05559bbf380d264d3715f3..30ce0ba54e47285099b86a963a5ad41f07614e51 100644 (file)
@@ -229,14 +229,14 @@ class TestContentTypeHeader(TestHeaderBase):
         defects =  args[1] if l>1 else []
         decoded =  args[2] if l>2 and args[2] is not DITTO else source
         header = 'Content-Type:' + ' ' if source else ''
-        folded = args[3] if l>3 else header + source + '\n'
+        folded = args[3] if l>3 else header + decoded + '\n'
         h = self.make_header('Content-Type', source)
         self.assertEqual(h.content_type, content_type)
         self.assertEqual(h.maintype, maintype)
         self.assertEqual(h.subtype, subtype)
         self.assertEqual(h.params, parmdict)
         with self.assertRaises(TypeError):
-            h.params['abc'] = 'xyz'   # params is read-only.
+            h.params['abc'] = 'xyz'   # make sure params is read-only.
         self.assertDefectsEqual(h.defects, defects)
         self.assertEqual(h, decoded)
         self.assertEqual(h.fold(policy=policy.default), folded)
@@ -373,9 +373,10 @@ class TestContentTypeHeader(TestHeaderBase):
             'text/plain; Charset="utf-8"'),
 
         # Since this is pretty much the ur-mimeheader, we'll put all the tests
-        # that exercise the parameter parsing and formatting here.
-        #
-        # XXX: question: is minimal quoting preferred?
+        # that exercise the parameter parsing and formatting here.  Note that
+        # when we refold we may canonicalize, so things like whitespace,
+        # quoting, and rfc2231 encoding may change from what was in the input
+        # header.
 
         'unquoted_param_value': (
             'text/plain; title=foo',
@@ -384,7 +385,8 @@ class TestContentTypeHeader(TestHeaderBase):
             'plain',
             {'title': 'foo'},
             [],
-            'text/plain; title="foo"'),
+            'text/plain; title="foo"',
+            ),
 
         'param_value_with_tspecials': (
             'text/plain; title="(bar)foo blue"',
@@ -415,7 +417,8 @@ class TestContentTypeHeader(TestHeaderBase):
             'mixed',
             {'boundary': 'CPIMSSMTPC06p5f3tG'},
             [],
-            'Multipart/mixed; boundary="CPIMSSMTPC06p5f3tG"'),
+            'Multipart/mixed; boundary="CPIMSSMTPC06p5f3tG"',
+            ),
 
         'spaces_around_semis': (
             ('image/jpeg; name="wibble.JPG" ; x-mac-type="4A504547" ; '
@@ -429,14 +432,31 @@ class TestContentTypeHeader(TestHeaderBase):
             [],
             ('image/jpeg; name="wibble.JPG"; x-mac-type="4A504547"; '
                 'x-mac-creator="474B4F4E"'),
-            # XXX: it could be that we will eventually prefer to fold starting
-            # from the decoded value, in which case these spaces and similar
-            # spaces in other tests will be wrong.
-            ('Content-Type: image/jpeg; name="wibble.JPG" ; '
-                'x-mac-type="4A504547" ;\n'
+            ('Content-Type: image/jpeg; name="wibble.JPG";'
+                ' x-mac-type="4A504547";\n'
              ' x-mac-creator="474B4F4E"\n'),
             ),
 
+        'lots_of_mime_params': (
+            ('image/jpeg; name="wibble.JPG"; x-mac-type="4A504547"; '
+                'x-mac-creator="474B4F4E"; x-extrastuff="make it longer"'),
+            'image/jpeg',
+            'image',
+            'jpeg',
+            {'name': 'wibble.JPG',
+             'x-mac-type': '4A504547',
+             'x-mac-creator': '474B4F4E',
+             'x-extrastuff': 'make it longer'},
+            [],
+            ('image/jpeg; name="wibble.JPG"; x-mac-type="4A504547"; '
+                'x-mac-creator="474B4F4E"; x-extrastuff="make it longer"'),
+            # In this case the whole of the MimeParameters does *not* fit
+            # one one line, so we break at a lower syntactic level.
+            ('Content-Type: image/jpeg; name="wibble.JPG";'
+                ' x-mac-type="4A504547";\n'
+             ' x-mac-creator="474B4F4E"; x-extrastuff="make it longer"\n'),
+            ),
+
         'semis_inside_quotes': (
             'image/jpeg; name="Jim&amp;&amp;Jill"',
             'image/jpeg',
@@ -460,19 +480,25 @@ class TestContentTypeHeader(TestHeaderBase):
             [],
             r'image/jpeg; name="Jim \"Bob\" Jill"'),
 
-        # XXX: This test works except for the refolding of the header.  I'll
-        # deal with that bug when I deal with the other folding bugs.
-        #'non_ascii_in_params': (
-        #    ('foo\xa7/bar; b\xa7r=two; '
-        #        'baz=thr\xa7e'.encode('latin-1').decode('us-ascii',
-        #                                                'surrogateescape')),
-        #    'foo\uFFFD/bar',
-        #    'foo\uFFFD',
-        #    'bar',
-        #    {'b\uFFFDr': 'two', 'baz': 'thr\uFFFDe'},
-        #    [errors.UndecodableBytesDefect]*3,
-        #    'foo�/bar; b�r="two"; baz="thr�e"',
-        #    ),
+        'non_ascii_in_params': (
+            ('foo\xa7/bar; b\xa7r=two; '
+                'baz=thr\xa7e'.encode('latin-1').decode('us-ascii',
+                                                        'surrogateescape')),
+            'foo\uFFFD/bar',
+            'foo\uFFFD',
+            'bar',
+            {'b\uFFFDr': 'two', 'baz': 'thr\uFFFDe'},
+            [errors.UndecodableBytesDefect]*3,
+            'foo�/bar; b�r="two"; baz="thr�e"',
+            # XXX Two bugs here: the mime type is not allowed to be an encoded
+            # word, and we shouldn't be emitting surrogates in the parameter
+            # names.  But I don't know what the behavior should be here, so I'm
+            # punting for now.  In practice this is unlikely to be encountered
+            # since headers with binary in them only come from a binary source
+            # and are almost certain to be re-emitted without refolding.
+            'Content-Type: =?unknown-8bit?q?foo=A7?=/bar; b\udca7r="two";\n'
+            " baz*=unknown-8bit''thr%A7e\n",
+            ),
 
         # RFC 2231 parameter tests.
 
@@ -494,19 +520,20 @@ class TestContentTypeHeader(TestHeaderBase):
             [],
             r'image/jpeg; bar="baz\"foobar\"baz"'),
 
-        # XXX: This test works except for the refolding of the header.  I'll
-        # deal with that bug when I deal with the other folding bugs.
-        #'non_ascii_rfc2231_value': (
-        #    ('text/plain; charset=us-ascii; '
-        #     "title*=us-ascii'en'This%20is%20"
-        #     'not%20f\xa7n').encode('latin-1').decode('us-ascii',
-        #                                             'surrogateescape'),
-        #    'text/plain',
-        #    'text',
-        #    'plain',
-        #    {'charset': 'us-ascii', 'title': 'This is not f\uFFFDn'},
-        #     [errors.UndecodableBytesDefect],
-        #     'text/plain; charset="us-ascii"; title="This is not f�n"'),
+        'non_ascii_rfc2231_value': (
+            ('text/plain; charset=us-ascii; '
+             "title*=us-ascii'en'This%20is%20"
+             'not%20f\xa7n').encode('latin-1').decode('us-ascii',
+                                                     'surrogateescape'),
+            'text/plain',
+            'text',
+            'plain',
+            {'charset': 'us-ascii', 'title': 'This is not f\uFFFDn'},
+             [errors.UndecodableBytesDefect],
+             'text/plain; charset="us-ascii"; title="This is not f�n"',
+            'Content-Type: text/plain; charset="us-ascii";\n'
+            " title*=unknown-8bit''This%20is%20not%20f%A7n\n",
+            ),
 
         'rfc2231_encoded_charset': (
             'text/plain; charset*=ansi-x3.4-1968\'\'us-ascii',
@@ -529,8 +556,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'This is ***fun*** is it not.pdf'},
             [],
             'text/plain; name="This is ***fun*** is it not.pdf"',
-            ('Content-Type: text/plain;\tname*0*=\'\'This%20is%20;\n'
-             '\tname*1*=%2A%2A%2Afun%2A%2A%2A%20;\tname*2="is it not.pdf"\n'),
             ),
 
         # Make sure we also handle it if there are spurious double quotes.
@@ -545,9 +570,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'This is even more ***fun*** is it not.pdf'},
             [errors.InvalidHeaderDefect]*2,
             'text/plain; name="This is even more ***fun*** is it not.pdf"',
-            ('Content-Type: text/plain;\t'
-                'name*0*="us-ascii\'\'This%20is%20even%20more%20";\n'
-             '\tname*1*="%2A%2A%2Afun%2A%2A%2A%20";\tname*2="is it not.pdf"\n'),
             ),
 
         'rfc2231_single_quote_inside_double_quotes': (
@@ -562,9 +584,8 @@ class TestContentTypeHeader(TestHeaderBase):
             [errors.InvalidHeaderDefect]*2,
             ('text/plain; charset="us-ascii"; '
                'title="This is really ***fun*** isn\'t it!"'),
-            ('Content-Type: text/plain; charset=us-ascii;\n'
-             '\ttitle*0*="us-ascii\'en\'This%20is%20really%20";\n'
-             '\ttitle*1*="%2A%2A%2Afun%2A%2A%2A%20";\ttitle*2="isn\'t it!"\n'),
+            ('Content-Type: text/plain; charset="us-ascii";\n'
+                ' title="This is really ***fun*** isn\'t it!"\n'),
             ),
 
         'rfc2231_single_quote_in_value_with_charset_and_lang': (
@@ -576,9 +597,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': "Frank's Document"},
             [errors.InvalidHeaderDefect]*2,
             'application/x-foo; name="Frank\'s Document"',
-            ('Content-Type: application/x-foo;\t'
-                'name*0*="us-ascii\'en-us\'Frank\'s";\n'
-             ' name*1*=" Document"\n'),
             ),
 
         'rfc2231_single_quote_in_non_encoded_value': (
@@ -590,9 +608,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': "us-ascii'en-us'Frank's Document"},
             [],
             'application/x-foo; name="us-ascii\'en-us\'Frank\'s Document"',
-            ('Content-Type: application/x-foo;\t'
-                'name*0="us-ascii\'en-us\'Frank\'s";\n'
-             ' name*1=" Document"\n'),
              ),
 
         'rfc2231_no_language_or_charset': (
@@ -615,12 +630,8 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'This is even more ***fun*** is it.pdf'},
             [errors.InvalidHeaderDefect]*2,
             'text/plain; name="This is even more ***fun*** is it.pdf"',
-            ('Content-Type: text/plain;\t'
-                'name*0*="\'\'This%20is%20even%20more%20";\n'
-             '\tname*1*="%2A%2A%2Afun%2A%2A%2A%20";\tname*2="is it.pdf"\n'),
             ),
 
-        # XXX: see below...the first name line here should be *0 not *0*.
         'rfc2231_partly_encoded': (
             ("text/plain;"
                 '\tname*0*="\'\'This%20is%20even%20more%20";'
@@ -632,9 +643,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'This is even more ***fun*** is it.pdf'},
             [errors.InvalidHeaderDefect]*2,
             'text/plain; name="This is even more ***fun*** is it.pdf"',
-            ('Content-Type: text/plain;\t'
-                'name*0*="\'\'This%20is%20even%20more%20";\n'
-             '\tname*1*="%2A%2A%2Afun%2A%2A%2A%20";\tname*2="is it.pdf"\n'),
             ),
 
         'rfc2231_partly_encoded_2': (
@@ -647,10 +655,11 @@ class TestContentTypeHeader(TestHeaderBase):
             'plain',
             {'name': 'This is even more %2A%2A%2Afun%2A%2A%2A%20is it.pdf'},
             [errors.InvalidHeaderDefect],
-            'text/plain; name="This is even more %2A%2A%2Afun%2A%2A%2A%20is it.pdf"',
-            ('Content-Type: text/plain;\t'
-                'name*0*="\'\'This%20is%20even%20more%20";\n'
-             '\tname*1="%2A%2A%2Afun%2A%2A%2A%20";\tname*2="is it.pdf"\n'),
+            ('text/plain;'
+             ' name="This is even more %2A%2A%2Afun%2A%2A%2A%20is it.pdf"'),
+            ('Content-Type: text/plain;\n'
+             ' name="This is even more %2A%2A%2Afun%2A%2A%2A%20is'
+                ' it.pdf"\n'),
             ),
 
         'rfc2231_unknown_charset_treated_as_ascii': (
@@ -669,9 +678,12 @@ class TestContentTypeHeader(TestHeaderBase):
             'plain',
             {'charset': 'utf-8\uFFFD\uFFFD\uFFFD'},
             [errors.UndecodableBytesDefect],
-            'text/plain; charset="utf-8\uFFFD\uFFFD\uFFFD"'),
+            'text/plain; charset="utf-8\uFFFD\uFFFD\uFFFD"',
+            "Content-Type: text/plain;"
+            " charset*=unknown-8bit''utf-8%F1%F2%F3\n",
+            ),
 
-        'rfc2231_utf_8_in_supposedly_ascii_charset_parameter_value': (
+        'rfc2231_utf8_in_supposedly_ascii_charset_parameter_value': (
             "text/plain; charset*=ascii''utf-8%E2%80%9D",
             'text/plain',
             'text',
@@ -679,9 +691,11 @@ class TestContentTypeHeader(TestHeaderBase):
             {'charset': 'utf-8”'},
             [errors.UndecodableBytesDefect],
             'text/plain; charset="utf-8”"',
+            # XXX Should folding change the charset to utf8?  Currently it just
+            # reproduces the original, which is arguably fine.
+            "Content-Type: text/plain;"
+            " charset*=unknown-8bit''utf-8%E2%80%9D\n",
             ),
-            # XXX: if the above were *re*folded, it would get tagged as utf-8
-            # instead of ascii in the param, since it now contains non-ASCII.
 
         'rfc2231_encoded_then_unencoded_segments': (
             ('application/x-foo;'
@@ -694,9 +708,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'My Document For You'},
             [errors.InvalidHeaderDefect],
             'application/x-foo; name="My Document For You"',
-            ('Content-Type: application/x-foo;\t'
-                'name*0*="us-ascii\'en-us\'My";\n'
-             '\tname*1=" Document";\tname*2=" For You"\n'),
             ),
 
         # My reading of the RFC is that this is an invalid header.  The RFC
@@ -713,11 +724,6 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': 'My Document For You'},
             [errors.InvalidHeaderDefect]*3,
             'application/x-foo; name="My Document For You"',
-            ("Content-Type: application/x-foo;\tname*0=us-ascii'en-us'My;\t"
-                # XXX: the newline is in the wrong place, come back and fix
-                # this when the rest of tests pass.
-                'name*1*=" Document"\n;'
-             '\tname*2*=" For You"\n'),
             ),
 
         # XXX: I would say this one should default to ascii/en for the
@@ -730,8 +736,7 @@ class TestContentTypeHeader(TestHeaderBase):
         # charset'lang'value pattern exactly *and* there is at least one
         # encoded segment.  Implementing that algorithm will require some
         # refactoring, so I haven't done it (yet).
-
-        'rfc2231_qouted_unencoded_then_encoded_segments': (
+        'rfc2231_quoted_unencoded_then_encoded_segments': (
             ('application/x-foo;'
                 '\tname*0="us-ascii\'en-us\'My";'
                 '\tname*1*=" Document";'
@@ -742,9 +747,25 @@ class TestContentTypeHeader(TestHeaderBase):
             {'name': "us-ascii'en-us'My Document For You"},
             [errors.InvalidHeaderDefect]*2,
             'application/x-foo; name="us-ascii\'en-us\'My Document For You"',
-            ('Content-Type: application/x-foo;\t'
-                'name*0="us-ascii\'en-us\'My";\n'
-             '\tname*1*=" Document";\tname*2*=" For You"\n'),
+            ),
+
+        # Make sure our folding algorithm produces multiple sections correctly.
+        # We could mix encoded and non-encoded segments, but we don't, we just
+        # make them all encoded.  It might be worth fixing that, since the
+        # sections can get used for wrapping ascii text.
+        'rfc2231_folded_segments_correctly_formatted': (
+            ('application/x-foo;'
+                '\tname="' + "with spaces"*8 + '"'),
+            'application/x-foo',
+            'application',
+            'x-foo',
+            {'name': "with spaces"*8},
+            [],
+            'application/x-foo; name="' + "with spaces"*8 + '"',
+            "Content-Type: application/x-foo;\n"
+            " name*0*=us-ascii''with%20spaceswith%20spaceswith%20spaceswith"
+                "%20spaceswith;\n"
+            " name*1*=%20spaceswith%20spaceswith%20spaceswith%20spaces\n"
             ),
 
     }
@@ -827,8 +848,8 @@ class TestContentDisposition(TestHeaderBase):
             [],
             ('attachment; filename="genome.jpeg"; '
                  'modification-date="Wed, 12 Feb 1997 16:29:51 -0500"'),
-            ('Content-Disposition: attachment; filename=genome.jpeg;\n'
-             '  modification-date="Wed, 12 Feb 1997 16:29:51 -0500";\n'),
+            ('Content-Disposition: attachment; filename="genome.jpeg";\n'
+             ' modification-date="Wed, 12 Feb 1997 16:29:51 -0500"\n'),
             ),
 
         'no_value': (
@@ -873,7 +894,7 @@ class TestMIMEVersionHeader(TestHeaderBase):
         if source:
             source = ' ' + source
         self.assertEqual(h.fold(policy=policy.default),
-                        'MIME-Version:' + source + '\n')
+                         'MIME-Version:' + source + '\n')
 
     version_string_params = {
 
@@ -1546,15 +1567,39 @@ class TestFolding(TestHeaderBase):
             'singlewordthatwontfit')
         self.assertEqual(
             h.fold(policy=policy.default.clone(max_line_length=20)),
-            'Subject: thisisaverylonglineconsistingofasinglewordthatwontfit\n')
+            'Subject: \n'
+            ' =?utf-8?q?thisisa?=\n'
+            ' =?utf-8?q?verylon?=\n'
+            ' =?utf-8?q?glineco?=\n'
+            ' =?utf-8?q?nsistin?=\n'
+            ' =?utf-8?q?gofasin?=\n'
+            ' =?utf-8?q?gleword?=\n'
+            ' =?utf-8?q?thatwon?=\n'
+            ' =?utf-8?q?tfit?=\n'
+            )
 
     def test_fold_unstructured_with_two_overlong_words(self):
         h = self.make_header('Subject', 'thisisaverylonglineconsistingofa'
             'singlewordthatwontfit plusanotherverylongwordthatwontfit')
         self.assertEqual(
             h.fold(policy=policy.default.clone(max_line_length=20)),
-            'Subject: thisisaverylonglineconsistingofasinglewordthatwontfit\n'
-                ' plusanotherverylongwordthatwontfit\n')
+            'Subject: \n'
+            ' =?utf-8?q?thisisa?=\n'
+            ' =?utf-8?q?verylon?=\n'
+            ' =?utf-8?q?glineco?=\n'
+            ' =?utf-8?q?nsistin?=\n'
+            ' =?utf-8?q?gofasin?=\n'
+            ' =?utf-8?q?gleword?=\n'
+            ' =?utf-8?q?thatwon?=\n'
+            ' =?utf-8?q?tfit_pl?=\n'
+            ' =?utf-8?q?usanoth?=\n'
+            ' =?utf-8?q?erveryl?=\n'
+            ' =?utf-8?q?ongword?=\n'
+            ' =?utf-8?q?thatwon?=\n'
+            ' =?utf-8?q?tfit?=\n'
+            )
+
+    # XXX Need test for when max_line_length is less than the chrome size.
 
     def test_fold_unstructured_with_slightly_long_word(self):
         h = self.make_header('Subject', 'thislongwordislessthanmaxlinelen')
@@ -1590,6 +1635,18 @@ class TestFolding(TestHeaderBase):
         self.assertEqual(h.fold(policy=policy.default),
                         'Date: Sat, 02 Feb 2002 17:00:06 -0800\n')
 
+    def test_fold_overlong_words_using_RFC2047(self):
+        h = self.make_header(
+            'X-Report-Abuse',
+            '<https://www.mailitapp.com/report_abuse.php?'
+              'mid=xxx-xxx-xxxxxxxxxxxxxxxxxxxxxxxx==-xxx-xx-xx>')
+        self.assertEqual(
+            h.fold(policy=policy.default),
+            'X-Report-Abuse: =?utf-8?q?=3Chttps=3A//www=2Emailitapp=2E'
+                'com/report=5F?=\n'
+            ' =?utf-8?q?abuse=2Ephp=3Fmid=3Dxxx-xxx-xxxx'
+                'xxxxxxxxxxxxxxxxxxxx=3D=3D-xxx-?=\n'
+            ' =?utf-8?q?xx-xx=3E?=\n')
 
 
 if __name__ == '__main__':
index 9b04c18b0e296882487642744f54784946eb9607..89966893092851cc5296a741177dc5538d1ea8a2 100644 (file)
@@ -20,6 +20,7 @@ class EnsurepipMixin:
     def setUp(self):
         run_pip_patch = unittest.mock.patch("ensurepip._run_pip")
         self.run_pip = run_pip_patch.start()
+        self.run_pip.return_value = 0
         self.addCleanup(run_pip_patch.stop)
 
         # Avoid side effects on the actual os module
@@ -255,7 +256,7 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
         self.assertFalse(self.run_pip.called)
 
     def test_basic_bootstrapping(self):
-        ensurepip._main([])
+        exit_code = ensurepip._main([])
 
         self.run_pip.assert_called_once_with(
             [
@@ -267,6 +268,13 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
 
         additional_paths = self.run_pip.call_args[0][1]
         self.assertEqual(len(additional_paths), 2)
+        self.assertEqual(exit_code, 0)
+
+    def test_bootstrapping_error_code(self):
+        self.run_pip.return_value = 2
+        exit_code = ensurepip._main([])
+        self.assertEqual(exit_code, 2)
+
 
 class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
 
@@ -280,7 +288,7 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
 
     def test_basic_uninstall(self):
         with fake_pip():
-            ensurepip._uninstall._main([])
+            exit_code = ensurepip._uninstall._main([])
 
         self.run_pip.assert_called_once_with(
             [
@@ -289,6 +297,13 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
             ]
         )
 
+        self.assertEqual(exit_code, 0)
+
+    def test_uninstall_error_code(self):
+        with fake_pip():
+            self.run_pip.return_value = 2
+            exit_code = ensurepip._uninstall._main([])
+        self.assertEqual(exit_code, 2)
 
 
 if __name__ == "__main__":
index 53851cb6cfda660c0eedb55e0264d5b792abf87d..f3bf223a8a4bd9b23f840b1145cb31b2d72a9bd2 100644 (file)
@@ -10,8 +10,8 @@ import errno
 
 from test.support import (TESTFN, captured_stderr, check_impl_detail,
                           check_warnings, cpython_only, gc_collect, run_unittest,
-                          no_tracing, unlink, import_module)
-
+                          no_tracing, unlink, import_module, script_helper,
+                          SuppressCrashReport)
 class NaiveException(Exception):
     def __init__(self, x):
         self.x = x
@@ -936,6 +936,105 @@ class ExceptionTests(unittest.TestCase):
         self.assertTrue(isinstance(v, RecursionError), type(v))
         self.assertIn("maximum recursion depth exceeded", str(v))
 
+    @cpython_only
+    def test_recursion_normalizing_exception(self):
+        # Issue #22898.
+        # Test that a RecursionError is raised when tstate->recursion_depth is
+        # equal to recursion_limit in PyErr_NormalizeException() and check
+        # that a ResourceWarning is printed.
+        # Prior to #22898, the recursivity of PyErr_NormalizeException() was
+        # controled by tstate->recursion_depth and a PyExc_RecursionErrorInst
+        # singleton was being used in that case, that held traceback data and
+        # locals indefinitely and would cause a segfault in _PyExc_Fini() upon
+        # finalization of these locals.
+        code = """if 1:
+            import sys
+            from _testcapi import get_recursion_depth
+
+            class MyException(Exception): pass
+
+            def setrecursionlimit(depth):
+                while 1:
+                    try:
+                        sys.setrecursionlimit(depth)
+                        return depth
+                    except RecursionError:
+                        # sys.setrecursionlimit() raises a RecursionError if
+                        # the new recursion limit is too low (issue #25274).
+                        depth += 1
+
+            def recurse(cnt):
+                cnt -= 1
+                if cnt:
+                    recurse(cnt)
+                else:
+                    generator.throw(MyException)
+
+            def gen():
+                f = open(%a, mode='rb', buffering=0)
+                yield
+
+            generator = gen()
+            next(generator)
+            recursionlimit = sys.getrecursionlimit()
+            depth = get_recursion_depth()
+            try:
+                # Upon the last recursive invocation of recurse(),
+                # tstate->recursion_depth is equal to (recursion_limit - 1)
+                # and is equal to recursion_limit when _gen_throw() calls
+                # PyErr_NormalizeException().
+                recurse(setrecursionlimit(depth + 2) - depth - 1)
+            finally:
+                sys.setrecursionlimit(recursionlimit)
+                print('Done.')
+        """ % __file__
+        rc, out, err = script_helper.assert_python_failure("-Wd", "-c", code)
+        # Check that the program does not fail with SIGABRT.
+        self.assertEqual(rc, 1)
+        self.assertIn(b'RecursionError', err)
+        self.assertIn(b'ResourceWarning', err)
+        self.assertIn(b'Done.', out)
+
+    @cpython_only
+    def test_recursion_normalizing_infinite_exception(self):
+        # Issue #30697. Test that a RecursionError is raised when
+        # PyErr_NormalizeException() maximum recursion depth has been
+        # exceeded.
+        code = """if 1:
+            import _testcapi
+            try:
+                raise _testcapi.RecursingInfinitelyError
+            finally:
+                print('Done.')
+        """
+        rc, out, err = script_helper.assert_python_failure("-c", code)
+        self.assertEqual(rc, 1)
+        self.assertIn(b'RecursionError: maximum recursion depth exceeded '
+                      b'while normalizing an exception', err)
+        self.assertIn(b'Done.', out)
+
+    @cpython_only
+    def test_recursion_normalizing_with_no_memory(self):
+        # Issue #30697. Test that in the abort that occurs when there is no
+        # memory left and the size of the Python frames stack is greater than
+        # the size of the list of preallocated MemoryError instances, the
+        # Fatal Python error message mentions MemoryError.
+        code = """if 1:
+            import _testcapi
+            class C(): pass
+            def recurse(cnt):
+                cnt -= 1
+                if cnt:
+                    recurse(cnt)
+                else:
+                    _testcapi.set_nomemory(0)
+                    C()
+            recurse(16)
+        """
+        with SuppressCrashReport():
+            rc, out, err = script_helper.assert_python_failure("-c", code)
+            self.assertIn(b'Fatal Python error: Cannot recover from '
+                          b'MemoryErrors while normalizing exceptions.', err)
 
     @cpython_only
     def test_MemoryError(self):
@@ -1104,6 +1203,23 @@ class ExceptionTests(unittest.TestCase):
                     self.assertIn("test message", report)
                 self.assertTrue(report.endswith("\n"))
 
+    @cpython_only
+    def test_memory_error_in_PyErr_PrintEx(self):
+        code = """if 1:
+            import _testcapi
+            class C(): pass
+            _testcapi.set_nomemory(0, %d)
+            C()
+        """
+
+        # Issue #30817: Abort in PyErr_PrintEx() when no memory.
+        # Span a large range of tests as the CPython code always evolves with
+        # changes that add or remove memory allocations.
+        for i in range(1, 20):
+            rc, out, err = script_helper.assert_python_failure("-c", code % i)
+            self.assertIn(rc, (1, 120))
+            self.assertIn(b'MemoryError', err)
+
 
 class ImportErrorTests(unittest.TestCase):
 
index 20fe1e2655946f5bc7a18f2940a50057bb6014d6..b8d8ea3cd47115026b34de187f071b7a6de7b59b 100644 (file)
@@ -755,6 +755,22 @@ class FaultHandlerTests(unittest.TestCase):
                 3,
                 name)
 
+    @unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
+    def test_ignore_exception(self):
+        for exc_code in (
+            0xE06D7363,   # MSC exception ("Emsc")
+            0xE0434352,   # COM Callable Runtime exception ("ECCR")
+        ):
+            code = f"""
+                    import faulthandler
+                    faulthandler.enable()
+                    faulthandler._raise_exception({exc_code})
+                    """
+            code = dedent(code)
+            output, exitcode = self.get_output(code)
+            self.assertEqual(output, [])
+            self.assertEqual(exitcode, exc_code)
+
     @unittest.skipUnless(MS_WINDOWS, 'specific to Windows')
     def test_raise_nonfatal_exception(self):
         # These exceptions are not strictly errors. Letting
index f698e13f68a7bf336e64e2b8db6744027f932774..01e11da09805e70dff41a1f285debce98cf73646 100644 (file)
@@ -8,7 +8,6 @@ import sys
 import unittest
 import warnings
 from test import support
-android_not_root = support.android_not_root
 
 
 def create_file(filename, data=b'foo'):
@@ -213,9 +212,11 @@ class GenericTest:
     def test_samefile_on_symlink(self):
         self._test_samefile_on_link_func(os.symlink)
 
-    @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
     def test_samefile_on_link(self):
-        self._test_samefile_on_link_func(os.link)
+        try:
+            self._test_samefile_on_link_func(os.link)
+        except PermissionError as e:
+            self.skipTest('os.link(): %s' % e)
 
     def test_samestat(self):
         test_fn1 = support.TESTFN
@@ -253,9 +254,11 @@ class GenericTest:
     def test_samestat_on_symlink(self):
         self._test_samestat_on_link_func(os.symlink)
 
-    @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
     def test_samestat_on_link(self):
-        self._test_samestat_on_link_func(os.link)
+        try:
+            self._test_samestat_on_link_func(os.link)
+        except PermissionError as e:
+            self.skipTest('os.link(): %s' % e)
 
     def test_sameopenfile(self):
         filename = support.TESTFN
index b457bd3f44df6511c0fdb7dd956413da16851841..295d4d4a8fdf3fc0b2b502a90cb45ab2c9a71637 100644 (file)
@@ -431,6 +431,30 @@ class TestGzip(BaseTest):
             with gzip.GzipFile(fileobj=f, mode="w") as g:
                 pass
 
+    def test_fileobj_mode(self):
+        gzip.GzipFile(self.filename, "wb").close()
+        with open(self.filename, "r+b") as f:
+            with gzip.GzipFile(fileobj=f, mode='r') as g:
+                self.assertEqual(g.mode, gzip.READ)
+            with gzip.GzipFile(fileobj=f, mode='w') as g:
+                self.assertEqual(g.mode, gzip.WRITE)
+            with gzip.GzipFile(fileobj=f, mode='a') as g:
+                self.assertEqual(g.mode, gzip.WRITE)
+            with gzip.GzipFile(fileobj=f, mode='x') as g:
+                self.assertEqual(g.mode, gzip.WRITE)
+            with self.assertRaises(ValueError):
+                gzip.GzipFile(fileobj=f, mode='z')
+        for mode in "rb", "r+b":
+            with open(self.filename, mode) as f:
+                with gzip.GzipFile(fileobj=f) as g:
+                    self.assertEqual(g.mode, gzip.READ)
+        for mode in "wb", "ab", "xb":
+            if "x" in mode:
+                support.unlink(self.filename)
+            with open(self.filename, mode) as f:
+                with gzip.GzipFile(fileobj=f) as g:
+                    self.assertEqual(g.mode, gzip.WRITE)
+
     def test_bytes_filename(self):
         str_filename = self.filename
         try:
index 647719ea62ce1a136743dea1f39a88b0032d1afc..981748892efb3d144087e974d83f756b350207fc 100644 (file)
@@ -618,6 +618,24 @@ class HashLibTestCase(unittest.TestCase):
           "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"+
           "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")
 
+    @requires_blake2
+    def test_case_blake2b_all_parameters(self):
+        # This checks that all the parameters work in general, and also that
+        # parameter byte order doesn't get confused on big endian platforms.
+        self.check('blake2b', b"foo",
+          "920568b0c5873b2f0ab67bedb6cf1b2b",
+          digest_size=16,
+          key=b"bar",
+          salt=b"baz",
+          person=b"bing",
+          fanout=2,
+          depth=3,
+          leaf_size=4,
+          node_offset=5,
+          node_depth=6,
+          inner_size=7,
+          last_node=True)
+
     @requires_blake2
     def test_blake2b_vectors(self):
         for msg, key, md in read_vectors('blake2b'):
@@ -643,6 +661,24 @@ class HashLibTestCase(unittest.TestCase):
         self.check('blake2s', b"abc",
           "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982")
 
+    @requires_blake2
+    def test_case_blake2s_all_parameters(self):
+        # This checks that all the parameters work in general, and also that
+        # parameter byte order doesn't get confused on big endian platforms.
+        self.check('blake2s', b"foo",
+          "bf2a8f7fe3c555012a6f8046e646bc75",
+          digest_size=16,
+          key=b"bar",
+          salt=b"baz",
+          person=b"bing",
+          fanout=2,
+          depth=3,
+          leaf_size=4,
+          node_offset=5,
+          node_depth=6,
+          inner_size=7,
+          last_node=True)
+
     @requires_blake2
     def test_blake2s_vectors(self):
         for msg, key, md in read_vectors('blake2s'):
index 22b3bf5235c4173d44f8d98afeac856792e0f798..66e937e04b608deb882fb64c0f7a1faafbe7cc1b 100644 (file)
@@ -370,7 +370,8 @@ class SimpleHTTPServerTestCase(BaseTestCase):
         reader.close()
         return body
 
-    @support.requires_mac_ver(10, 5)
+    @unittest.skipIf(sys.platform == 'darwin',
+                     'undecodable name cannot always be decoded on macOS')
     @unittest.skipIf(sys.platform == 'win32',
                      'undecodable name cannot be decoded on win32')
     @unittest.skipUnless(support.TESTFN_UNDECODABLE,
index 6f35f49487ce7f979f00d255f022b8dba32cb9af..1c7605c77bb14fda0b6db30e007c0124d98f87ef 100644 (file)
@@ -315,8 +315,24 @@ class ImportTests(unittest.TestCase):
         loader.get_data(imp.__file__)  # Will need to create a newly opened file
 
     def test_load_source(self):
-        with self.assertRaisesRegex(ValueError, 'embedded null'):
-            imp.load_source(__name__, __file__ + "\0")
+        # Create a temporary module since load_source(name) modifies
+        # sys.modules[name] attributes like __loader___
+        modname = f"tmp{__name__}"
+        mod = type(sys.modules[__name__])(modname)
+        with support.swap_item(sys.modules, modname, mod):
+            with self.assertRaisesRegex(ValueError, 'embedded null'):
+                imp.load_source(modname, __file__ + "\0")
+
+    @support.cpython_only
+    def test_issue31315(self):
+        # There shouldn't be an assertion failure in imp.create_dynamic(),
+        # when spec.name is not a string.
+        create_dynamic = support.get_attribute(imp, 'create_dynamic')
+        class BadSpec:
+            name = None
+            origin = 'foo'
+        with self.assertRaises(TypeError):
+            create_dynamic(BadSpec())
 
 
 class ReloadTests(unittest.TestCase):
index e8111214b92b613b0badc44218b1e16284d86a93..b73a96f757005ecf54a9bc8bb5cae214d91ad5a8 100644 (file)
@@ -353,6 +353,18 @@ class ImportTests(unittest.TestCase):
         with self.assertRaises(ImportError):
             from test_from_import_AttributeError import does_not_exist
 
+    @cpython_only
+    def test_issue31492(self):
+        # There shouldn't be an assertion failure in case of failing to import
+        # from a module with a bad __name__ attribute, or in case of failing
+        # to access an attribute of such a module.
+        with swap_attr(os, '__name__', None):
+            with self.assertRaises(ImportError):
+                from os import does_not_exist
+
+            with self.assertRaises(AttributeError):
+                os.does_not_exist
+
     def test_concurrency(self):
         sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'data'))
         try:
index a7bf2749cf56f44ea2f14748049333707b04e30e..0cd9de4daff752f85c02c45595ddb5dd4ffd28ca 100644 (file)
@@ -82,6 +82,20 @@ class APITest:
                     self.__import__(PKG_NAME,
                                     fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
 
+    def test_blocked_fromlist(self):
+        # If fromlist entry is None, let a ModuleNotFoundError propagate.
+        # issue31642
+        mod = types.ModuleType(PKG_NAME)
+        mod.__path__ = []
+        with util.import_state(meta_path=[self.bad_finder_loader]):
+            with util.uncache(PKG_NAME, SUBMOD_NAME):
+                sys.modules[PKG_NAME] = mod
+                sys.modules[SUBMOD_NAME] = None
+                with self.assertRaises(ModuleNotFoundError) as cm:
+                    self.__import__(PKG_NAME,
+                                    fromlist=[SUBMOD_NAME.rpartition('.')[-1]])
+                self.assertEqual(cm.exception.name, SUBMOD_NAME)
+
 
 class OldAPITests(APITest):
     bad_finder_loader = BadLoaderFinder
index 14640032b4c22657af85f909f2ca803b62b6221e..018c17217619047a6c6431a1a68630d98334a425 100644 (file)
@@ -1,5 +1,6 @@
 """Test that the semantics relating to the 'fromlist' argument are correct."""
 from .. import util
+import warnings
 import unittest
 
 
@@ -73,6 +74,13 @@ class HandlingFromlist:
                 self.assertTrue(hasattr(module, 'module'))
                 self.assertEqual(module.module.__name__, 'pkg.module')
 
+    def test_nonexistent_from_package(self):
+        with util.mock_modules('pkg.__init__') as importer:
+            with util.import_state(meta_path=[importer]):
+                module = self.__import__('pkg', fromlist=['non_existent'])
+                self.assertEqual(module.__name__, 'pkg')
+                self.assertFalse(hasattr(module, 'non_existent'))
+
     def test_module_from_package_triggers_ModuleNotFoundError(self):
         # If a submodule causes an ModuleNotFoundError because it tries
         # to import a module which doesn't exist, that should let the
@@ -122,6 +130,41 @@ class HandlingFromlist:
                 self.assertEqual(module.module1.__name__, 'pkg.module1')
                 self.assertEqual(module.module2.__name__, 'pkg.module2')
 
+    def test_nonexistent_in_all(self):
+        with util.mock_modules('pkg.__init__') as importer:
+            with util.import_state(meta_path=[importer]):
+                importer['pkg'].__all__ = ['non_existent']
+                module = self.__import__('pkg', fromlist=['*'])
+                self.assertEqual(module.__name__, 'pkg')
+                self.assertFalse(hasattr(module, 'non_existent'))
+
+    def test_star_in_all(self):
+        with util.mock_modules('pkg.__init__') as importer:
+            with util.import_state(meta_path=[importer]):
+                importer['pkg'].__all__ = ['*']
+                module = self.__import__('pkg', fromlist=['*'])
+                self.assertEqual(module.__name__, 'pkg')
+                self.assertFalse(hasattr(module, '*'))
+
+    def test_invalid_type(self):
+        with util.mock_modules('pkg.__init__') as importer:
+            with util.import_state(meta_path=[importer]), \
+                 warnings.catch_warnings():
+                warnings.simplefilter('error', BytesWarning)
+                with self.assertRaisesRegex(TypeError, r'\bfrom\b'):
+                    self.__import__('pkg', fromlist=[b'attr'])
+                with self.assertRaisesRegex(TypeError, r'\bfrom\b'):
+                    self.__import__('pkg', fromlist=iter([b'attr']))
+
+    def test_invalid_type_in_all(self):
+        with util.mock_modules('pkg.__init__') as importer:
+            with util.import_state(meta_path=[importer]), \
+                 warnings.catch_warnings():
+                warnings.simplefilter('error', BytesWarning)
+                importer['pkg'].__all__ = [b'attr']
+                with self.assertRaisesRegex(TypeError, r'\bpkg\.__all__\b'):
+                    self.__import__('pkg', fromlist=['*'])
+
 
 (Frozen_FromList,
  Source_FromList
index facf040d3cd302217f766563ca2bb20850b90476..bdad38643b935cd3c1d5853c4a1720f923967c88 100644 (file)
@@ -2021,7 +2021,7 @@ class TestSignatureObject(unittest.TestCase):
                          ((('args', ..., ..., 'var_positional'),), ...))
         self.assertEqual(self.signature(A.f3),
                          ((('args', ..., ..., 'var_positional'),), ...))
-        self.assertEqual(self.signature(A.f4), 
+        self.assertEqual(self.signature(A.f4),
                          ((('args', ..., ..., 'var_positional'),
                             ('kwargs', ..., ..., 'var_keyword')), ...))
     @cpython_only
@@ -3557,6 +3557,19 @@ class TestSignatureDefinitions(unittest.TestCase):
                 self.assertIsNone(obj.__text_signature__)
 
 
+class NTimesUnwrappable:
+    def __init__(self, n):
+        self.n = n
+        self._next = None
+
+    @property
+    def __wrapped__(self):
+        if self.n <= 0:
+            raise Exception("Unwrapped too many times")
+        if self._next is None:
+            self._next = NTimesUnwrappable(self.n - 1)
+        return self._next
+
 class TestUnwrap(unittest.TestCase):
 
     def test_unwrap_one(self):
@@ -3612,6 +3625,11 @@ class TestUnwrap(unittest.TestCase):
             __wrapped__ = func
         self.assertIsNone(inspect.unwrap(C()))
 
+    def test_recursion_limit(self):
+        obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
+        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
+            inspect.unwrap(obj)
+
 class TestMain(unittest.TestCase):
     def test_only_source(self):
         module = importlib.import_module('unittest')
index 14bbd6192a0572df887fe90dcfa4e2775a4120c2..a36076e01047d60650899b410e317054c688fe43 100644 (file)
@@ -506,5 +506,13 @@ class IntTestCases(unittest.TestCase):
         check('123\ud800')
         check('123\ud800', 10)
 
+    def test_issue31619(self):
+        self.assertEqual(int('1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1', 2),
+                         0b1010101010101010101010101010101)
+        self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123)
+        self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789)
+        self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807)
+
+
 if __name__ == "__main__":
     unittest.main()
index c431f0dc6e1d7f4896906313dae62d1d05582dc9..a978134e88e754dfa437fdefbfef6431b0c5bb3e 100644 (file)
@@ -1984,6 +1984,30 @@ class RegressionTests(unittest.TestCase):
         with self.assertRaises(StopIteration):
             next(it)
 
+    def test_issue30347_1(self):
+        def f(n):
+            if n == 5:
+                list(b)
+            return n != 6
+        for (k, b) in groupby(range(10), f):
+            list(b)  # shouldn't crash
+
+    def test_issue30347_2(self):
+        class K:
+            def __init__(self, v):
+                pass
+            def __eq__(self, other):
+                nonlocal i
+                i += 1
+                if i == 1:
+                    next(g, None)
+                return True
+        i = 0
+        g = next(groupby(range(10), K))[1]
+        for j in range(2):
+            next(g, None)  # shouldn't crash
+
+
 class SubclassWithKwargsTest(unittest.TestCase):
     def test_keywords_in_subclass(self):
         # count is not subclassable...
index 56f1882001d666807998f3ebb973b40b8fb3b5ca..5dad69208704218b14539771e29aaff3a3a071e6 100644 (file)
@@ -36,6 +36,27 @@ class TestEncode(CTest):
             b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
             None)
 
+    def test_bad_str_encoder(self):
+        # Issue #31505: There shouldn't be an assertion failure in case
+        # c_make_encoder() receives a bad encoder() argument.
+        def bad_encoder1(*args):
+            return None
+        enc = self.json.encoder.c_make_encoder(None, lambda obj: str(obj),
+                                               bad_encoder1, None, ': ', ', ',
+                                               False, False, False)
+        with self.assertRaises(TypeError):
+            enc('spam', 4)
+        with self.assertRaises(TypeError):
+            enc({'spam': 42}, 4)
+
+        def bad_encoder2(*args):
+            1/0
+        enc = self.json.encoder.c_make_encoder(None, lambda obj: str(obj),
+                                               bad_encoder2, None, ': ', ', ',
+                                               False, False, False)
+        with self.assertRaises(ZeroDivisionError):
+            enc('spam', 4)
+
     def test_bad_bool_args(self):
         def test(name):
             self.json.encoder.JSONEncoder(**{name: BadBool()}).encode({'a': 1})
index 9f49886878f0ae57ed60e4cd11a0c7599851fc62..1099c759a7910e96dad0cead4a2f78ae10d52a44 100644 (file)
@@ -208,6 +208,30 @@ class TestKQueue(unittest.TestCase):
         b.close()
         kq.close()
 
+    def test_issue30058(self):
+        # changelist must be an iterable
+        kq = select.kqueue()
+        a, b = socket.socketpair()
+        ev = select.kevent(a, select.KQ_FILTER_READ, select.KQ_EV_ADD | select.KQ_EV_ENABLE)
+
+        kq.control([ev], 0)
+        # not a list
+        kq.control((ev,), 0)
+        # __len__ is not consistent with __iter__
+        class BadList:
+            def __len__(self):
+                return 0
+            def __iter__(self):
+                for i in range(100):
+                    yield ev
+        kq.control(BadList(), 0)
+        # doesn't have __len__
+        kq.control(iter([ev]), 0)
+
+        a.close()
+        b.close()
+        kq.close()
+
     def test_close(self):
         open_file = open(__file__, "rb")
         self.addCleanup(open_file.close)
index 25046c3c38ab3e198bcb74ca854b3a267c4b0a01..b325f7697f73e786dc11c6ef94d7901a72a907be 100644 (file)
@@ -3881,7 +3881,6 @@ class BasicConfigTest(unittest.TestCase):
 
 
 class LoggerAdapterTest(unittest.TestCase):
-
     def setUp(self):
         super(LoggerAdapterTest, self).setUp()
         old_handler_list = logging._handlerList[:]
@@ -3956,15 +3955,37 @@ class LoggerAdapterTest(unittest.TestCase):
         self.assertFalse(self.adapter.hasHandlers())
 
     def test_nested(self):
+        class Adapter(logging.LoggerAdapter):
+            prefix = 'Adapter'
+
+            def process(self, msg, kwargs):
+                return f"{self.prefix} {msg}", kwargs
+
         msg = 'Adapters can be nested, yo.'
-        adapter_adapter = logging.LoggerAdapter(logger=self.adapter, extra=None)
+        adapter = Adapter(logger=self.logger, extra=None)
+        adapter_adapter = Adapter(logger=adapter, extra=None)
+        adapter_adapter.prefix = 'AdapterAdapter'
+        self.assertEqual(repr(adapter), repr(adapter_adapter))
         adapter_adapter.log(logging.CRITICAL, msg, self.recording)
-
         self.assertEqual(len(self.recording.records), 1)
         record = self.recording.records[0]
         self.assertEqual(record.levelno, logging.CRITICAL)
-        self.assertEqual(record.msg, msg)
+        self.assertEqual(record.msg, f"Adapter AdapterAdapter {msg}")
         self.assertEqual(record.args, (self.recording,))
+        orig_manager = adapter_adapter.manager
+        self.assertIs(adapter.manager, orig_manager)
+        self.assertIs(self.logger.manager, orig_manager)
+        temp_manager = object()
+        try:
+            adapter_adapter.manager = temp_manager
+            self.assertIs(adapter_adapter.manager, temp_manager)
+            self.assertIs(adapter.manager, temp_manager)
+            self.assertIs(self.logger.manager, temp_manager)
+        finally:
+            adapter_adapter.manager = orig_manager
+        self.assertIs(adapter_adapter.manager, orig_manager)
+        self.assertIs(adapter.manager, orig_manager)
+        self.assertIs(self.logger.manager, orig_manager)
 
 
 class LoggerTest(BaseTest):
index 2ba944335ae87db5ee9fc8254d9e4aa2ea9780bb..3807b95b158263a7c162e9da7504dc4cd1f620cf 100644 (file)
@@ -746,7 +746,7 @@ class TestMaildir(TestMailbox, unittest.TestCase):
             hostname = hostname.replace(':', r'\072')
         pid = os.getpid()
         pattern = re.compile(r"(?P<time>\d+)\.M(?P<M>\d{1,6})P(?P<P>\d+)"
-                             r"Q(?P<Q>\d+)\.(?P<host>[^:/]+)")
+                             r"Q(?P<Q>\d+)\.(?P<host>[^:/]*)")
         previous_groups = None
         for x in range(repetitions):
             tmp_file = self._box._create_tmp()
index b378ffea00c0a787217ed92173b5c862b15c3bfd..29dda987d0bb7f28c59e16ccb4769acb469ce00a 100644 (file)
@@ -34,6 +34,29 @@ class IntTestCase(unittest.TestCase, HelperMixin):
                 self.helper(expected)
             n = n >> 1
 
+    def test_int64(self):
+        # Simulate int marshaling with TYPE_INT64.
+        maxint64 = (1 << 63) - 1
+        minint64 = -maxint64-1
+        for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
+            while base:
+                s = b'I' + int.to_bytes(base, 8, 'little', signed=True)
+                got = marshal.loads(s)
+                self.assertEqual(base, got)
+                if base == -1:  # a fixed-point for shifting right 1
+                    base = 0
+                else:
+                    base >>= 1
+
+        got = marshal.loads(b'I\xfe\xdc\xba\x98\x76\x54\x32\x10')
+        self.assertEqual(got, 0x1032547698badcfe)
+        got = marshal.loads(b'I\x01\x23\x45\x67\x89\xab\xcd\xef')
+        self.assertEqual(got, -0x1032547698badcff)
+        got = marshal.loads(b'I\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f')
+        self.assertEqual(got, 0x7f6e5d4c3b2a1908)
+        got = marshal.loads(b'I\xf7\xe6\xd5\xc4\xb3\xa2\x91\x80')
+        self.assertEqual(got, -0x7f6e5d4c3b2a1909)
+
     def test_bool(self):
         for b in (True, False):
             self.helper(b)
index f656f7234e2d333810f154ce51436dfda32ced58..fec435e05b747c4d4257cac6c8477e8ee638883a 100644 (file)
@@ -1,7 +1,64 @@
 """ Test suite for the code in msilib """
+import os.path
 import unittest
-from test.support import import_module
+from test.support import TESTFN, import_module, unlink
 msilib = import_module('msilib')
+import msilib.schema
+
+
+def init_database():
+    path = TESTFN + '.msi'
+    db = msilib.init_database(
+        path,
+        msilib.schema,
+        'Python Tests',
+        'product_code',
+        '1.0',
+        'PSF',
+    )
+    return db, path
+
+
+class MsiDatabaseTestCase(unittest.TestCase):
+
+    def test_view_fetch_returns_none(self):
+        db, db_path = init_database()
+        properties = []
+        view = db.OpenView('SELECT Property, Value FROM Property')
+        view.Execute(None)
+        while True:
+            record = view.Fetch()
+            if record is None:
+                break
+            properties.append(record.GetString(1))
+        view.Close()
+        self.assertEqual(
+            properties,
+            [
+                'ProductName', 'ProductCode', 'ProductVersion',
+                'Manufacturer', 'ProductLanguage',
+            ]
+        )
+        self.addCleanup(unlink, db_path)
+
+    def test_database_open_failed(self):
+        with self.assertRaises(msilib.MSIError) as cm:
+            msilib.OpenDatabase('non-existent.msi', msilib.MSIDBOPEN_READONLY)
+        self.assertEqual(str(cm.exception), 'open failed')
+
+    def test_database_create_failed(self):
+        db_path = os.path.join(TESTFN, 'test.msi')
+        with self.assertRaises(msilib.MSIError) as cm:
+            msilib.OpenDatabase(db_path, msilib.MSIDBOPEN_CREATE)
+        self.assertEqual(str(cm.exception), 'create failed')
+
+    def test_get_property_vt_empty(self):
+        db, db_path = init_database()
+        summary = db.GetSummaryInformation(0)
+        self.assertIsNone(summary.GetProperty(msilib.PID_SECURITY))
+        del db
+        self.addCleanup(unlink, db_path)
+
 
 class Test_make_id(unittest.TestCase):
     #http://msdn.microsoft.com/en-us/library/aa369212(v=vs.85).aspx
index 60a3ec9565b4cf77f265dde72706a09590358e08..ca6f27d03c3afd273c381ef9fc00cd8f41772861 100644 (file)
@@ -1,7 +1,6 @@
-import netrc, os, unittest, sys, textwrap
+import netrc, os, unittest, sys, tempfile, textwrap
 from test import support
 
-temp_filename = support.TESTFN
 
 class NetrcTestCase(unittest.TestCase):
 
@@ -10,7 +9,8 @@ class NetrcTestCase(unittest.TestCase):
         mode = 'w'
         if sys.platform != 'cygwin':
             mode += 't'
-        with open(temp_filename, mode) as fp:
+        temp_fd, temp_filename = tempfile.mkstemp()
+        with os.fdopen(temp_fd, mode=mode) as fp:
             fp.write(test_data)
         self.addCleanup(os.unlink, temp_filename)
         return netrc.netrc(temp_filename)
@@ -24,6 +24,9 @@ class NetrcTestCase(unittest.TestCase):
                          ('log1', 'acct1', 'pass1'))
         self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2'))
 
+        nrc2 = self.make_nrc(nrc.__repr__())
+        self.assertEqual(nrc.hosts, nrc2.hosts)
+
     def test_macros(self):
         nrc = self.make_nrc("""\
             macdef macro1
index 3e84f3429ee8546c8bbb9510e3a95b52052e0850..d7642bc66ab346422a666bd646ecc49d7b306e72 100644 (file)
@@ -166,6 +166,7 @@ class NetworkedNNTPTestsMixin:
         # XXX this could exceptionally happen...
         self.assertNotIn(article.lines[-1], (b".", b".\n", b".\r\n"))
 
+    @unittest.skipIf(True, "FIXME: see bpo-32128")
     def test_article_head_body(self):
         resp, count, first, last, name = self.server.group(self.GROUP_NAME)
         # Try to find an available article
index 6502413a73d061bb11b0656e2c70da5dcc3c72bf..6672c448f4fb0560b7f1fe71519a6513e72d2290 100644 (file)
@@ -11,7 +11,6 @@ import unittest
 from unittest import mock
 
 from test import support
-android_not_root = support.android_not_root
 TESTFN = support.TESTFN
 
 try:
@@ -1914,10 +1913,12 @@ class _BasePathTest(object):
         self.assertFalse((P / 'fileA' / 'bah').is_fifo())
 
     @unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required")
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def test_is_fifo_true(self):
         P = self.cls(BASE, 'myfifo')
-        os.mkfifo(str(P))
+        try:
+            os.mkfifo(str(P))
+        except PermissionError as e:
+            self.skipTest('os.mkfifo(): %s' % e)
         self.assertTrue(P.is_fifo())
         self.assertFalse(P.is_socket())
         self.assertFalse(P.is_file())
index e6c5d08522aa8e90ffb1d0842d6ccdc980e0581e..895ed48df1d8d20c2ac6b1c3f8f68e994143c483 100644 (file)
@@ -6,6 +6,7 @@ import io
 import collections
 import struct
 import sys
+import weakref
 
 import unittest
 from test import support
@@ -26,8 +27,13 @@ except ImportError:
     has_c_implementation = False
 
 
-class PickleTests(AbstractPickleModuleTests):
-    pass
+class PyPickleTests(AbstractPickleModuleTests):
+    dump = staticmethod(pickle._dump)
+    dumps = staticmethod(pickle._dumps)
+    load = staticmethod(pickle._load)
+    loads = staticmethod(pickle._loads)
+    Pickler = pickle._Pickler
+    Unpickler = pickle._Unpickler
 
 
 class PyUnpicklerTests(AbstractUnpickleTests):
@@ -112,6 +118,66 @@ class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests,
     pickler = pickle._Pickler
     unpickler = pickle._Unpickler
 
+    @support.cpython_only
+    def test_pickler_reference_cycle(self):
+        def check(Pickler):
+            for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+                f = io.BytesIO()
+                pickler = Pickler(f, proto)
+                pickler.dump('abc')
+                self.assertEqual(self.loads(f.getvalue()), 'abc')
+            pickler = Pickler(io.BytesIO())
+            self.assertEqual(pickler.persistent_id('def'), 'def')
+            r = weakref.ref(pickler)
+            del pickler
+            self.assertIsNone(r())
+
+        class PersPickler(self.pickler):
+            def persistent_id(subself, obj):
+                return obj
+        check(PersPickler)
+
+        class PersPickler(self.pickler):
+            @classmethod
+            def persistent_id(cls, obj):
+                return obj
+        check(PersPickler)
+
+        class PersPickler(self.pickler):
+            @staticmethod
+            def persistent_id(obj):
+                return obj
+        check(PersPickler)
+
+    @support.cpython_only
+    def test_unpickler_reference_cycle(self):
+        def check(Unpickler):
+            for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+                unpickler = Unpickler(io.BytesIO(self.dumps('abc', proto)))
+                self.assertEqual(unpickler.load(), 'abc')
+            unpickler = Unpickler(io.BytesIO())
+            self.assertEqual(unpickler.persistent_load('def'), 'def')
+            r = weakref.ref(unpickler)
+            del unpickler
+            self.assertIsNone(r())
+
+        class PersUnpickler(self.unpickler):
+            def persistent_load(subself, pid):
+                return pid
+        check(PersUnpickler)
+
+        class PersUnpickler(self.unpickler):
+            @classmethod
+            def persistent_load(cls, pid):
+                return pid
+        check(PersUnpickler)
+
+        class PersUnpickler(self.unpickler):
+            @staticmethod
+            def persistent_load(pid):
+                return pid
+        check(PersUnpickler)
+
 
 class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests):
 
@@ -136,6 +202,9 @@ class PyChainDispatchTableTests(AbstractDispatchTableTests):
 
 
 if has_c_implementation:
+    class CPickleTests(AbstractPickleModuleTests):
+        from _pickle import dump, dumps, load, loads, Pickler, Unpickler
+
     class CUnpicklerTests(PyUnpicklerTests):
         unpickler = _pickle.Unpickler
         bad_stack_errors = (pickle.UnpicklingError,)
@@ -189,7 +258,7 @@ if has_c_implementation:
         check_sizeof = support.check_sizeof
 
         def test_pickler(self):
-            basesize = support.calcobjsize('5P2n3i2n3iP')
+            basesize = support.calcobjsize('6P2n3i2n3iP')
             p = _pickle.Pickler(io.BytesIO())
             self.assertEqual(object.__sizeof__(p), basesize)
             MT_size = struct.calcsize('3nP0n')
@@ -206,7 +275,7 @@ if has_c_implementation:
                 0)  # Write buffer is cleared after every dump().
 
         def test_unpickler(self):
-            basesize = support.calcobjsize('2Pn2P 2P2n2i5P 2P3n6P2n2i')
+            basesize = support.calcobjsize('2P2n2P 2P2n2i5P 2P3n6P2n2i')
             unpickler = _pickle.Unpickler
             P = struct.calcsize('P')  # Size of memo table entry.
             n = struct.calcsize('n')  # Size of mark table entry.
@@ -426,12 +495,12 @@ class CompatPickleTests(unittest.TestCase):
 
 
 def test_main():
-    tests = [PickleTests, PyUnpicklerTests, PyPicklerTests,
+    tests = [PyPickleTests, PyUnpicklerTests, PyPicklerTests,
              PyPersPicklerTests, PyIdPersPicklerTests,
              PyDispatchTableTests, PyChainDispatchTableTests,
              CompatPickleTests]
     if has_c_implementation:
-        tests.extend([CUnpicklerTests, CPicklerTests,
+        tests.extend([CPickleTests, CUnpicklerTests, CPicklerTests,
                       CPersPicklerTests, CIdPersPicklerTests,
                       CDumpPickle_LoadPickle, DumpPickle_CLoadPickle,
                       PyPicklerUnpicklerObjectTests,
index 86bebfa0266862fbded64e3d7e6bf16f661830be..b3cab0e4fb338a6fb61c730d831bcf64453c6324 100644 (file)
@@ -2,10 +2,9 @@ import pickle
 import pickletools
 from test import support
 from test.pickletester import AbstractPickleTests
-from test.pickletester import AbstractPickleModuleTests
 import unittest
 
-class OptimizedPickleTests(AbstractPickleTests, AbstractPickleModuleTests):
+class OptimizedPickleTests(AbstractPickleTests):
 
     def dumps(self, arg, proto=None):
         return pickletools.optimize(pickle.dumps(arg, proto))
index c77a6bf9d03fd385baa58885f2d23255a6c72883..90641a7635c0b5dd7a51144cc2e10d5afb083e32 100644 (file)
@@ -169,6 +169,17 @@ class TestPlistlib(unittest.TestCase):
                     self.assertRaises(OverflowError, plistlib.dumps,
                                       pl, fmt=fmt)
 
+    def test_bytearray(self):
+        for pl in (b'<binary gunk>', b"<lots of binary gunk>\0\1\2\3" * 10):
+            for fmt in ALL_FORMATS:
+                with self.subTest(pl=pl, fmt=fmt):
+                    data = plistlib.dumps(bytearray(pl), fmt=fmt)
+                    pl2 = plistlib.loads(data)
+                    self.assertIsInstance(pl2, bytes)
+                    self.assertEqual(pl2, pl)
+                    data2 = plistlib.dumps(pl2, fmt=fmt)
+                    self.assertEqual(data, data2)
+
     def test_bytes(self):
         pl = self._create()
         data = plistlib.dumps(pl)
@@ -354,11 +365,13 @@ class TestPlistlib(unittest.TestCase):
             testString = "string containing %s" % c
             if i >= 32 or c in "\r\n\t":
                 # \r, \n and \t are the only legal control chars in XML
-                plistlib.dumps(testString, fmt=plistlib.FMT_XML)
+                data = plistlib.dumps(testString, fmt=plistlib.FMT_XML)
+                if c != "\r":
+                    self.assertEqual(plistlib.loads(data), testString)
             else:
-                self.assertRaises(ValueError,
-                                  plistlib.dumps,
-                                  testString)
+                with self.assertRaises(ValueError):
+                    plistlib.dumps(testString, fmt=plistlib.FMT_XML)
+            plistlib.dumps(testString, fmt=plistlib.FMT_BINARY)
 
     def test_non_bmp_characters(self):
         pl = {'python': '\U0001f40d'}
@@ -367,6 +380,14 @@ class TestPlistlib(unittest.TestCase):
                 data = plistlib.dumps(pl, fmt=fmt)
                 self.assertEqual(plistlib.loads(data), pl)
 
+    def test_lone_surrogates(self):
+        for fmt in ALL_FORMATS:
+            with self.subTest(fmt=fmt):
+                with self.assertRaises(UnicodeEncodeError):
+                    plistlib.dumps('\ud8ff', fmt=fmt)
+                with self.assertRaises(UnicodeEncodeError):
+                    plistlib.dumps('\udcff', fmt=fmt)
+
     def test_nondictroot(self):
         for fmt in ALL_FORMATS:
             with self.subTest(fmt=fmt):
@@ -422,6 +443,9 @@ class TestPlistlib(unittest.TestCase):
                 pl2 = plistlib.loads(data)
                 self.assertEqual(dict(pl), dict(pl2))
 
+
+class TestBinaryPlistlib(unittest.TestCase):
+
     def test_nonstandard_refs_size(self):
         # Issue #21538: Refs and offsets are 24-bit integers
         data = (b'bplist00'
@@ -434,6 +458,47 @@ class TestPlistlib(unittest.TestCase):
                 b'\x00\x00\x00\x00\x00\x00\x00\x13')
         self.assertEqual(plistlib.loads(data), {'a': 'b'})
 
+    def test_dump_duplicates(self):
+        # Test effectiveness of saving duplicated objects
+        for x in (None, False, True, 12345, 123.45, 'abcde', b'abcde',
+                  datetime.datetime(2004, 10, 26, 10, 33, 33),
+                  plistlib.Data(b'abcde'), bytearray(b'abcde'),
+                  [12, 345], (12, 345), {'12': 345}):
+            with self.subTest(x=x):
+                data = plistlib.dumps([x]*1000, fmt=plistlib.FMT_BINARY)
+                self.assertLess(len(data), 1100, repr(data))
+
+    def test_identity(self):
+        for x in (None, False, True, 12345, 123.45, 'abcde', b'abcde',
+                  datetime.datetime(2004, 10, 26, 10, 33, 33),
+                  plistlib.Data(b'abcde'), bytearray(b'abcde'),
+                  [12, 345], (12, 345), {'12': 345}):
+            with self.subTest(x=x):
+                data = plistlib.dumps([x]*2, fmt=plistlib.FMT_BINARY)
+                a, b = plistlib.loads(data)
+                if isinstance(x, tuple):
+                    x = list(x)
+                self.assertEqual(a, x)
+                self.assertEqual(b, x)
+                self.assertIs(a, b)
+
+    def test_cycles(self):
+        # recursive list
+        a = []
+        a.append(a)
+        b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY))
+        self.assertIs(b[0], b)
+        # recursive tuple
+        a = ([],)
+        a[0].append(a)
+        b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY))
+        self.assertIs(b[0][0], b)
+        # recursive dict
+        a = {}
+        a['x'] = a
+        b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY))
+        self.assertIs(b['x'], b)
+
     def test_large_timestamp(self):
         # Issue #26709: 32-bit timestamp out of range
         for ts in -2**31-1, 2**31:
@@ -443,6 +508,56 @@ class TestPlistlib(unittest.TestCase):
                 data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY)
                 self.assertEqual(plistlib.loads(data), d)
 
+    def test_invalid_binary(self):
+        for data in [
+                # too short data
+                b'',
+                # too large offset_table_offset and nonstandard offset_size
+                b'\x00\x08'
+                b'\x00\x00\x00\x00\x00\x00\x03\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x2a',
+                # integer overflow in offset_table_offset
+                b'\x00\x08'
+                b'\x00\x00\x00\x00\x00\x00\x01\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\xff\xff\xff\xff\xff\xff\xff\xff',
+                # offset_size = 0
+                b'\x00\x08'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x09',
+                # ref_size = 0
+                b'\xa1\x01\x00\x08\x0a'
+                b'\x00\x00\x00\x00\x00\x00\x01\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x02'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x0b',
+                # integer overflow in offset
+                b'\x00\xff\xff\xff\xff\xff\xff\xff\xff'
+                b'\x00\x00\x00\x00\x00\x00\x08\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x09',
+                # invalid ASCII
+                b'\x51\xff\x08'
+                b'\x00\x00\x00\x00\x00\x00\x01\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x0a',
+                # invalid UTF-16
+                b'\x61\xd8\x00\x08'
+                b'\x00\x00\x00\x00\x00\x00\x01\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x01'
+                b'\x00\x00\x00\x00\x00\x00\x00\x00'
+                b'\x00\x00\x00\x00\x00\x00\x00\x0b',
+                ]:
+            with self.assertRaises(plistlib.InvalidFileException):
+                plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY)
+
 
 class TestPlistlibDeprecated(unittest.TestCase):
     def test_io_deprecated(self):
index 6a2bf6ea7b77c9e9ecbc3f4a70174de72dec7298..e8725c3df8fd7f226502afff95651790af3f3d73 100644 (file)
@@ -208,6 +208,28 @@ class PollTests(unittest.TestCase):
             os.write(w, b'spam')
             t.join()
 
+    @unittest.skipUnless(threading, 'Threading required for this test.')
+    @reap_threads
+    def test_poll_blocks_with_negative_ms(self):
+        for timeout_ms in [None, -1000, -1, -1.0, -0.1, -1e-100]:
+            # Create two file descriptors. This will be used to unlock
+            # the blocking call to poll.poll inside the thread
+            r, w = os.pipe()
+            pollster = select.poll()
+            pollster.register(r, select.POLLIN)
+
+            poll_thread = threading.Thread(target=pollster.poll, args=(timeout_ms,))
+            poll_thread.start()
+            poll_thread.join(timeout=0.1)
+            self.assertTrue(poll_thread.is_alive())
+
+            # Write to the pipe so pollster.poll unblocks and the thread ends.
+            os.write(w, b'spam')
+            poll_thread.join()
+            self.assertFalse(poll_thread.is_alive())
+            os.close(r)
+            os.close(w)
+
 
 def test_main():
     run_unittest(PollTests)
index 9df3206324fc67d2b636130780989ee6a1d818f0..85eae47b8a5b02d864c9ec57823857c8e95c6125 100644 (file)
@@ -1,7 +1,6 @@
 "Test posix functions"
 
 from test import support
-android_not_root = support.android_not_root
 
 # Skip these tests if there is no posix module.
 posix = support.import_module('posix')
@@ -423,15 +422,16 @@ class PosixTester(unittest.TestCase):
                 posix.stat, list(os.fsencode(support.TESTFN)))
 
     @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def test_mkfifo(self):
         support.unlink(support.TESTFN)
-        posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
+        try:
+            posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
+        except PermissionError as e:
+            self.skipTest('posix.mkfifo(): %s' % e)
         self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
 
     @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
                          "don't have mknod()/S_IFIFO")
-    @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
     def test_mknod(self):
         # Test using mknod() to create a FIFO (the only use specified
         # by POSIX).
@@ -442,7 +442,7 @@ class PosixTester(unittest.TestCase):
         except OSError as e:
             # Some old systems don't allow unprivileged users to use
             # mknod(), or only support creating device nodes.
-            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
+            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
         else:
             self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
 
@@ -452,7 +452,7 @@ class PosixTester(unittest.TestCase):
             posix.mknod(path=support.TESTFN, mode=mode, device=0,
                 dir_fd=None)
         except OSError as e:
-            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
+            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
 
     @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
     @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
@@ -937,11 +937,13 @@ class PosixTester(unittest.TestCase):
             posix.close(f)
 
     @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
-    @unittest.skipIf(android_not_root, "hard link not allowed, non root user")
     def test_link_dir_fd(self):
         f = posix.open(posix.getcwd(), posix.O_RDONLY)
         try:
             posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
+        except PermissionError as e:
+            self.skipTest('posix.link(): %s' % e)
+        else:
             # should have same inodes
             self.assertEqual(posix.stat(support.TESTFN)[1],
                 posix.stat(support.TESTFN + 'link')[1])
@@ -961,7 +963,6 @@ class PosixTester(unittest.TestCase):
 
     @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
                          "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
-    @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
     def test_mknod_dir_fd(self):
         # Test using mknodat() to create a FIFO (the only use specified
         # by POSIX).
@@ -973,7 +974,7 @@ class PosixTester(unittest.TestCase):
         except OSError as e:
             # Some old systems don't allow unprivileged users to use
             # mknod(), or only support creating device nodes.
-            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
+            self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
         else:
             self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
         finally:
@@ -1045,12 +1046,15 @@ class PosixTester(unittest.TestCase):
             posix.close(f)
 
     @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def test_mkfifo_dir_fd(self):
         support.unlink(support.TESTFN)
         f = posix.open(posix.getcwd(), posix.O_RDONLY)
         try:
-            posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
+            try:
+                posix.mkfifo(support.TESTFN,
+                             stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
+            except PermissionError as e:
+                self.skipTest('posix.mkfifo(): %s' % e)
             self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
         finally:
             posix.close(f)
index 15f88e4fcd79848042717d3ea60741189fac4710..45ebea51a050bbe410a985a19fe99ab2f2128ebc 100644 (file)
@@ -10,6 +10,7 @@ import sys
 import select
 import signal
 import socket
+import io # readline
 import unittest
 
 TEST_STRING_1 = b"I wish to buy a fish license.\n"
@@ -23,6 +24,16 @@ else:
         pass
 
 
+# Note that os.read() is nondeterministic so we need to be very careful
+# to make the test suite deterministic.  A normal call to os.read() may
+# give us less than expected.
+#
+# Beware, on my Linux system, if I put 'foo\n' into a terminal fd, I get
+# back 'foo\r\n' at the other end.  The behavior depends on the termios
+# setting.  The newline translation may be OS-specific.  To make the
+# test suite deterministic and OS-independent, the functions _readline
+# and normalize_output can be used.
+
 def normalize_output(data):
     # Some operating systems do conversions on newline.  We could possibly
     # fix that by doing the appropriate termios.tcsetattr()s.  I couldn't
@@ -44,6 +55,12 @@ def normalize_output(data):
 
     return data
 
+def _readline(fd):
+    """Read one line.  May block forever if no newline is read."""
+    reader = io.FileIO(fd, mode='rb', closefd=False)
+    return reader.readline()
+
+
 
 # Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
 # because pty code is not too portable.
@@ -98,14 +115,14 @@ class PtyTest(unittest.TestCase):
 
         debug("Writing to slave_fd")
         os.write(slave_fd, TEST_STRING_1)
-        s1 = os.read(master_fd, 1024)
+        s1 = _readline(master_fd)
         self.assertEqual(b'I wish to buy a fish license.\n',
                          normalize_output(s1))
 
         debug("Writing chunked output")
         os.write(slave_fd, TEST_STRING_2[:5])
         os.write(slave_fd, TEST_STRING_2[5:])
-        s2 = os.read(master_fd, 1024)
+        s2 = _readline(master_fd)
         self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2))
 
         os.close(slave_fd)
index 03adc0a72294ab721e998d50717a9e4166cb8b1e..b42bf2a7124cf110473dac64f7328fb5b0592934 100644 (file)
@@ -423,6 +423,44 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
             ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
              '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])
 
+    def test_bug_31478(self):
+        # There shouldn't be an assertion failure in _random.Random.seed() in
+        # case the argument has a bad __abs__() method.
+        class BadInt(int):
+            def __abs__(self):
+                return None
+        try:
+            self.gen.seed(BadInt())
+        except TypeError:
+            pass
+
+    def test_bug_31482(self):
+        # Verify that version 1 seeds are unaffected by hash randomization
+        # when the seeds are expressed as bytes rather than strings.
+        # The hash(b) values listed are the Python2.7 hash() values
+        # which were used for seeding.
+
+        self.gen.seed(b'nofar', version=1)   # hash('nofar') == 5990528763808513177
+        self.assertEqual([self.gen.random().hex() for i in range(4)],
+            ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5',
+             '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6'])
+
+        self.gen.seed(b'rachel', version=1)  # hash('rachel') == -9091735575445484789
+        self.assertEqual([self.gen.random().hex() for i in range(4)],
+            ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3',
+             '0x1.3052b9c072678p-2', '0x1.578f332106574p-3'])
+
+        self.gen.seed(b'', version=1)        # hash('') == 0
+        self.assertEqual([self.gen.random().hex() for i in range(4)],
+            ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
+             '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])
+
+        b = b'\x00\x20\x40\x60\x80\xA0\xC0\xE0\xF0'
+        self.gen.seed(b, version=1)         # hash(b) == 5015594239749365497
+        self.assertEqual([self.gen.random().hex() for i in range(4)],
+            ['0x1.52c2fde444d23p-1', '0x1.875174f0daea4p-2',
+             '0x1.9e9b2c50e5cd2p-1', '0x1.fa57768bd321cp-2'])
+
     def test_setstate_first_arg(self):
         self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
 
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
new file mode 100644 (file)
index 0000000..9efd459
--- /dev/null
@@ -0,0 +1,62 @@
+"""Test the interactive interpreter."""
+
+import sys
+import os
+import unittest
+import subprocess
+from textwrap import dedent
+from test.support import cpython_only, SuppressCrashReport
+from test.support.script_helper import kill_python
+
+def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
+    """Run the Python REPL with the given arguments.
+
+    kw is extra keyword args to pass to subprocess.Popen. Returns a Popen
+    object.
+    """
+
+    # To run the REPL without using a terminal, spawn python with the command
+    # line option '-i' and the process name set to '<stdin>'.
+    # The directory of argv[0] must match the directory of the Python
+    # executable for the Popen() call to python to succeed as the directory
+    # path may be used by Py_GetPath() to build the default module search
+    # path.
+    stdin_fname = os.path.join(os.path.dirname(sys.executable), "<stdin>")
+    cmd_line = [stdin_fname, '-E', '-i']
+    cmd_line.extend(args)
+
+    # Set TERM=vt100, for the rationale see the comments in spawn_python() of
+    # test.support.script_helper.
+    env = kw.setdefault('env', dict(os.environ))
+    env['TERM'] = 'vt100'
+    return subprocess.Popen(cmd_line, executable=sys.executable,
+                            stdin=subprocess.PIPE,
+                            stdout=stdout, stderr=stderr,
+                            **kw)
+
+class TestInteractiveInterpreter(unittest.TestCase):
+
+    @cpython_only
+    def test_no_memory(self):
+        # Issue #30696: Fix the interactive interpreter looping endlessly when
+        # no memory. Check also that the fix does not break the interactive
+        # loop when an exception is raised.
+        user_input = """
+            import sys, _testcapi
+            1/0
+            print('After the exception.')
+            _testcapi.set_nomemory(0)
+            sys.exit(0)
+        """
+        user_input = dedent(user_input)
+        user_input = user_input.encode()
+        p = spawn_repl()
+        with SuppressCrashReport():
+            p.stdin.write(user_input)
+        output = kill_python(p)
+        self.assertIn(b'After the exception.', output)
+        # Exit code 120: Py_FinalizeEx() failed to flush stdout and stderr.
+        self.assertIn(p.returncode, (1, 120))
+
+if __name__ == "__main__":
+    unittest.main()
index 0f64ba8b060defbbc129423f063f18d4aa2ac498..e47344c11953144b39a8925609e7526565b10fbf 100644 (file)
@@ -2,7 +2,6 @@ import io
 import os
 import unittest
 import urllib.robotparser
-from collections import namedtuple
 from test import support
 from http.server import BaseHTTPRequestHandler, HTTPServer
 try:
@@ -90,6 +89,10 @@ class BaseRequestRateTest(BaseRobotTest):
                         self.parser.crawl_delay(agent), self.crawl_delay
                     )
                 if self.request_rate:
+                    self.assertIsInstance(
+                        self.parser.request_rate(agent),
+                        urllib.robotparser.RequestRate
+                    )
                     self.assertEqual(
                         self.parser.request_rate(agent).requests,
                         self.request_rate.requests
@@ -111,7 +114,7 @@ Disallow: /a%2fb.html
 Disallow: /%7ejoe/index.html
     """
     agent = 'figtree'
-    request_rate = namedtuple('req_rate', 'requests seconds')(9, 30)
+    request_rate = urllib.robotparser.RequestRate(9, 30)
     crawl_delay = 3
     good = [('figtree', '/foo.html')]
     bad = ['/tmp', '/tmp.html', '/tmp/a.html', '/a%3cd.html', '/a%3Cd.html',
@@ -240,7 +243,7 @@ Crawl-delay: 1
 Request-rate: 3/15
 Disallow: /cyberworld/map/
     """
-    request_rate = namedtuple('req_rate', 'requests seconds')(3, 15)
+    request_rate = urllib.robotparser.RequestRate(3, 15)
     crawl_delay = 1
     good = ['/', '/test.html']
     bad = ['/cyberworld/map/index.html']
index b2ab1af296d682b35ab010e36a42ef8e495290df..95717a48ff1079ef68c7bbdf8fe91d44e5d84765 100644 (file)
@@ -23,8 +23,7 @@ import zipfile
 import warnings
 
 from test import support
-from test.support import (TESTFN, check_warnings, captured_stdout,
-                          android_not_root)
+from test.support import TESTFN, check_warnings, captured_stdout
 
 TESTFN2 = TESTFN + "2"
 
@@ -771,7 +770,6 @@ class TestShutil(unittest.TestCase):
 
     @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
     @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
-    @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
     def test_dont_copy_file_onto_link_to_itself(self):
         # bug 851123.
         os.mkdir(TESTFN)
@@ -780,7 +778,10 @@ class TestShutil(unittest.TestCase):
         try:
             with open(src, 'w') as f:
                 f.write('cheddar')
-            os.link(src, dst)
+            try:
+                os.link(src, dst)
+            except PermissionError as e:
+                self.skipTest('os.link(): %s' % e)
             self.assertRaises(shutil.SameFileError, shutil.copyfile, src, dst)
             with open(src, 'r') as f:
                 self.assertEqual(f.read(), 'cheddar')
@@ -824,9 +825,11 @@ class TestShutil(unittest.TestCase):
 
     # Issue #3002: copyfile and copytree block indefinitely on named pipes
     @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def test_copyfile_named_pipe(self):
-        os.mkfifo(TESTFN)
+        try:
+            os.mkfifo(TESTFN)
+        except PermissionError as e:
+            self.skipTest('os.mkfifo(): %s' % e)
         try:
             self.assertRaises(shutil.SpecialFileError,
                                 shutil.copyfile, TESTFN, TESTFN2)
@@ -835,7 +838,6 @@ class TestShutil(unittest.TestCase):
         finally:
             os.remove(TESTFN)
 
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
     @support.skip_unless_symlink
     def test_copytree_named_pipe(self):
@@ -844,7 +846,10 @@ class TestShutil(unittest.TestCase):
             subdir = os.path.join(TESTFN, "subdir")
             os.mkdir(subdir)
             pipe = os.path.join(subdir, "mypipe")
-            os.mkfifo(pipe)
+            try:
+                os.mkfifo(pipe)
+            except PermissionError as e:
+                self.skipTest('os.mkfifo(): %s' % e)
             try:
                 shutil.copytree(TESTFN, TESTFN2)
             except shutil.Error as e:
index 80dfc405c7180929d2734a59a2217e37a9970a13..a79ebfe9a349ad5c9b16425ceff59f605663b070 100644 (file)
@@ -4373,6 +4373,10 @@ class NetworkConnectionNoServer(unittest.TestCase):
         expected_errnos = [ errno.ECONNREFUSED, ]
         if hasattr(errno, 'ENETUNREACH'):
             expected_errnos.append(errno.ENETUNREACH)
+        if hasattr(errno, 'EADDRNOTAVAIL'):
+            # bpo-31910: socket.create_connection() fails randomly
+            # with EADDRNOTAVAIL on Travis CI
+            expected_errnos.append(errno.EADDRNOTAVAIL)
 
         self.assertIn(cm.exception.errno, expected_errnos)
 
@@ -5415,6 +5419,9 @@ class LinuxKernelCryptoAPI(unittest.TestCase):
         else:
             return sock
 
+    # bpo-31705: On kernel older than 4.5, sendto() failed with ENOKEY,
+    # at least on ppc64le architecture
+    @support.requires_linux_version(4, 5)
     def test_sha256(self):
         expected = bytes.fromhex("ba7816bf8f01cfea414140de5dae2223b00361a396"
                                  "177a9cb410ff61f20015ad")
index 140a6abf9efb9cedba32cae734d2d7fa39d13e72..43621337e03dee4260ec695c8bc47d8f73171e22 100644 (file)
@@ -68,6 +68,20 @@ def simple_subprocess(testcase):
     testcase.assertEqual(72 << 8, status)
 
 
+def close_server(server):
+    server.server_close()
+
+    if hasattr(server, 'active_children'):
+        # ForkingMixIn: Manually reap all child processes, since server_close()
+        # calls waitpid() in non-blocking mode using the WNOHANG flag.
+        for pid in server.active_children.copy():
+            try:
+                os.waitpid(pid, 0)
+            except ChildProcessError:
+                pass
+        server.active_children.clear()
+
+
 @unittest.skipUnless(threading, 'Threading required for this test.')
 class SocketServerTest(unittest.TestCase):
     """Test all socket servers."""
@@ -142,7 +156,7 @@ class SocketServerTest(unittest.TestCase):
         if verbose: print("waiting for server")
         server.shutdown()
         t.join()
-        server.server_close()
+        close_server(server)
         self.assertEqual(-1, server.socket.fileno())
         if verbose: print("done")
 
@@ -266,7 +280,7 @@ class SocketServerTest(unittest.TestCase):
             s.shutdown()
         for t, s in threads:
             t.join()
-            s.server_close()
+            close_server(s)
 
     def test_tcpserver_bind_leak(self):
         # Issue #22435: the server socket wouldn't be closed if bind()/listen()
@@ -292,6 +306,7 @@ class ErrorHandlerTest(unittest.TestCase):
 
     def tearDown(self):
         test.support.unlink(test.support.TESTFN)
+        reap_children()
 
     def test_sync_handled(self):
         BaseErrorTestServer(ValueError)
@@ -337,7 +352,7 @@ class BaseErrorTestServer(socketserver.TCPServer):
         try:
             self.handle_request()
         finally:
-            self.server_close()
+            close_server(self)
         self.wait_done()
 
     def handle_error(self, request, client_address):
@@ -371,10 +386,7 @@ class ThreadingErrorTestServer(socketserver.ThreadingMixIn,
 
 if HAVE_FORKING:
     class ForkingErrorTestServer(socketserver.ForkingMixIn, BaseErrorTestServer):
-        def wait_done(self):
-            [child] = self.active_children
-            os.waitpid(child, 0)
-            self.active_children.clear()
+        pass
 
 
 class SocketWriterTest(unittest.TestCase):
@@ -386,7 +398,7 @@ class SocketWriterTest(unittest.TestCase):
                 self.server.request_fileno = self.request.fileno()
 
         server = socketserver.TCPServer((HOST, 0), Handler)
-        self.addCleanup(server.server_close)
+        self.addCleanup(close_server, server)
         s = socket.socket(
             server.address_family, socket.SOCK_STREAM, socket.IPPROTO_TCP)
         with s:
@@ -410,7 +422,7 @@ class SocketWriterTest(unittest.TestCase):
                 self.server.sent2 = self.wfile.write(big_chunk)
 
         server = socketserver.TCPServer((HOST, 0), Handler)
-        self.addCleanup(server.server_close)
+        self.addCleanup(close_server, server)
         interrupted = threading.Event()
 
         def signal_handler(signum, frame):
@@ -486,7 +498,7 @@ class MiscTestCase(unittest.TestCase):
         s.close()
         server.handle_request()
         self.assertEqual(server.shutdown_called, 1)
-        server.server_close()
+        close_server(server)
 
 
 if __name__ == "__main__":
index cd02a6ee37452b9687c01e24e1ec471ad96726a4..73cd901bdbf5c1a192470791212391a23a4f7959 100644 (file)
@@ -1,7 +1,7 @@
 import unittest
 import os
 import sys
-from test.support import TESTFN, import_fresh_module, android_not_root
+from test.support import TESTFN, import_fresh_module
 
 c_stat = import_fresh_module('stat', fresh=['_stat'])
 py_stat = import_fresh_module('stat', blocked=['_stat'])
@@ -168,9 +168,11 @@ class TestFilemode:
             self.assertS_IS("LNK", st_mode)
 
     @unittest.skipUnless(hasattr(os, 'mkfifo'), 'os.mkfifo not available')
-    @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
     def test_fifo(self):
-        os.mkfifo(TESTFN, 0o700)
+        try:
+            os.mkfifo(TESTFN, 0o700)
+        except PermissionError as e:
+            self.skipTest('os.mkfifo(): %s' % e)
         st_mode, modestr = self.get_mode()
         self.assertEqual(modestr, 'prwx------')
         self.assertS_IS("FIFO", st_mode)
index 72b1910c3838f2bfdd29ad5a1b18671c4f9a287e..ec305e54ff24f0c88d0f405855f27370406e28c7 100644 (file)
@@ -58,8 +58,10 @@ class StrftimeTest(unittest.TestCase):
             import java
             java.util.Locale.setDefault(java.util.Locale.US)
         except ImportError:
-            import locale
-            locale.setlocale(locale.LC_TIME, 'C')
+            from locale import setlocale, LC_TIME
+            saved_locale = setlocale(LC_TIME)
+            setlocale(LC_TIME, 'C')
+            self.addCleanup(setlocale, LC_TIME, saved_locale)
 
     def test_strftime(self):
         now = time.time()
index 70439f85c89555ef08dca3d7c566f896f2b967cb..8db23e76c1c6ad5a2e7b61b2491e0f2736898cf7 100644 (file)
@@ -271,6 +271,12 @@ class TestTemplate(unittest.TestCase):
         raises(ValueError, s.substitute, dict(who='tim'))
         s = Template('$who likes $100')
         raises(ValueError, s.substitute, dict(who='tim'))
+        # Template.idpattern should match to only ASCII characters.
+        # https://bugs.python.org/issue31672
+        s = Template("$who likes $\u0131")  # (DOTLESS I)
+        raises(ValueError, s.substitute, dict(who='tim'))
+        s = Template("$who likes $\u0130")  # (LATIN CAPITAL LETTER I WITH DOT ABOVE)
+        raises(ValueError, s.substitute, dict(who='tim'))
 
     def test_idpattern_override(self):
         class PathPattern(Template):
index 391d08cd9c3c3a7e427aae96adfa3ffdc3ad5ce5..5016513decd8c7c6d553fdebe404929dae35074b 100644 (file)
@@ -1568,8 +1568,10 @@ class POSIXProcessTestCase(BaseTestCase):
 
         fork_exec.side_effect = proper_error
 
-        with self.assertRaises(IsADirectoryError):
-            self.PopenNoDestructor(["non_existent_command"])
+        with mock.patch("subprocess.os.waitpid",
+                        side_effect=ChildProcessError):
+            with self.assertRaises(IsADirectoryError):
+                self.PopenNoDestructor(["non_existent_command"])
 
     @mock.patch("subprocess._posixsubprocess.fork_exec")
     def test_exception_errpipe_bad_data(self, fork_exec):
@@ -1586,8 +1588,10 @@ class POSIXProcessTestCase(BaseTestCase):
 
         fork_exec.side_effect = bad_error
 
-        with self.assertRaises(subprocess.SubprocessError) as e:
-            self.PopenNoDestructor(["non_existent_command"])
+        with mock.patch("subprocess.os.waitpid",
+                        side_effect=ChildProcessError):
+            with self.assertRaises(subprocess.SubprocessError) as e:
+                self.PopenNoDestructor(["non_existent_command"])
 
         self.assertIn(repr(error_data), str(e.exception))
 
index ddd65092312a3b495b08f9f062a44647c714eff8..c070809cbe9bf684c48cdf5c078b1d2304bf3867 100644 (file)
@@ -365,6 +365,64 @@ class TestSupport(unittest.TestCase):
 
         self.assertRaises(AssertionError, support.check__all__, self, unittest)
 
+    def test_match_test(self):
+        class Test:
+            def __init__(self, test_id):
+                self.test_id = test_id
+
+            def id(self):
+                return self.test_id
+
+        test_access = Test('test.test_os.FileTests.test_access')
+        test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir')
+
+        with support.swap_attr(support, '_match_test_func', None):
+            # match all
+            support.set_match_tests([])
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            # match all using None
+            support.set_match_tests(None)
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            # match the full test identifier
+            support.set_match_tests([test_access.id()])
+            self.assertTrue(support.match_test(test_access))
+            self.assertFalse(support.match_test(test_chdir))
+
+            # match the module name
+            support.set_match_tests(['test_os'])
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            # Test '*' pattern
+            support.set_match_tests(['test_*'])
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            # Test case sensitivity
+            support.set_match_tests(['filetests'])
+            self.assertFalse(support.match_test(test_access))
+            support.set_match_tests(['FileTests'])
+            self.assertTrue(support.match_test(test_access))
+
+            # Test pattern containing '.' and a '*' metacharacter
+            support.set_match_tests(['*test_os.*.test_*'])
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            # Multiple patterns
+            support.set_match_tests([test_access.id(), test_chdir.id()])
+            self.assertTrue(support.match_test(test_access))
+            self.assertTrue(support.match_test(test_chdir))
+
+            support.set_match_tests(['test_access', 'DONTMATCH'])
+            self.assertTrue(support.match_test(test_access))
+            self.assertFalse(support.match_test(test_chdir))
+
+
     # XXX -follows a list of untested API
     # make_legacy_pyc
     # is_resource_enabled
index 7f7e6dafcf9008708646d3c3b00334ce9e9d862b..b7095a2cdb030b033c5e42dba420a30b5e83a67d 100644 (file)
@@ -384,6 +384,15 @@ Misuse of the nonlocal and global statement can lead to a few unique syntax erro
      ...
    SyntaxError: name 'x' is used prior to nonlocal declaration
 
+   >>> def f():
+   ...     x = 1
+   ...     def g():
+   ...         x = 2
+   ...         nonlocal x
+   Traceback (most recent call last):
+     ...
+   SyntaxError: name 'x' is assigned to before nonlocal declaration
+
    >>> def f(x):
    ...     nonlocal x
    Traceback (most recent call last):
@@ -409,24 +418,7 @@ From SF bug #1705365
      ...
    SyntaxError: nonlocal declaration not allowed at module level
 
-TODO(jhylton): Figure out how to test SyntaxWarning with doctest.
-
-##   >>> def f(x):
-##   ...     def f():
-##   ...         print(x)
-##   ...         nonlocal x
-##   Traceback (most recent call last):
-##     ...
-##   SyntaxWarning: name 'x' is assigned to before nonlocal declaration
-
-##   >>> def f():
-##   ...     x = 1
-##   ...     nonlocal x
-##   Traceback (most recent call last):
-##     ...
-##   SyntaxWarning: name 'x' is assigned to before nonlocal declaration
-
- From https://bugs.python.org/issue25973
+From https://bugs.python.org/issue25973
    >>> class A:
    ...     def f(self):
    ...         nonlocal __x
index e151f493d4e36c95961b80020b2f52767056a0ff..7866a5c0054a69c0cd0581aa815895aaca866119 100644 (file)
@@ -778,6 +778,10 @@ class SysModuleTest(unittest.TestCase):
     @unittest.skipUnless(hasattr(sys, "getallocatedblocks"),
                          "sys.getallocatedblocks unavailable on this build")
     def test_getallocatedblocks(self):
+        if (os.environ.get('PYTHONMALLOC', None)
+           and not sys.flags.ignore_environment):
+            self.skipTest("cannot test if PYTHONMALLOC env var is set")
+
         # Some sanity checks
         with_pymalloc = sysconfig.get_config_var('WITH_PYMALLOC')
         a = sys.getallocatedblocks()
@@ -826,6 +830,39 @@ class SysModuleTest(unittest.TestCase):
         rc, stdout, stderr = assert_python_ok('-c', code)
         self.assertEqual(stdout.rstrip(), b'True')
 
+    def test_sys_tracebacklimit(self):
+        code = """if 1:
+            import sys
+            def f1():
+                1 / 0
+            def f2():
+                f1()
+            sys.tracebacklimit = %r
+            f2()
+        """
+        def check(tracebacklimit, expected):
+            p = subprocess.Popen([sys.executable, '-c', code % tracebacklimit],
+                                 stderr=subprocess.PIPE)
+            out = p.communicate()[1]
+            self.assertEqual(out.splitlines(), expected)
+
+        traceback = [
+            b'Traceback (most recent call last):',
+            b'  File "<string>", line 8, in <module>',
+            b'  File "<string>", line 6, in f2',
+            b'  File "<string>", line 4, in f1',
+            b'ZeroDivisionError: division by zero'
+        ]
+        check(10, traceback)
+        check(3, traceback)
+        check(2, traceback[:1] + traceback[2:])
+        check(1, traceback[:1] + traceback[3:])
+        check(0, [traceback[-1]])
+        check(-1, [traceback[-1]])
+        check(1<<1000, traceback)
+        check(-1<<1000, [traceback[-1]])
+        check(None, traceback)
+
 
 @test.support.cpython_only
 class SizeofTest(unittest.TestCase):
@@ -1092,6 +1129,7 @@ class SizeofTest(unittest.TestCase):
             fmt += '3n2P'
         s = vsize(fmt)
         check(int, s)
+        # class
         s = vsize(fmt +                 # PyTypeObject
                   '3P'                  # PyAsyncMethods
                   '36P'                 # PyNumberMethods
@@ -1099,13 +1137,17 @@ class SizeofTest(unittest.TestCase):
                   '10P'                 # PySequenceMethods
                   '2P'                  # PyBufferProcs
                   '4P')
-        # Separate block for PyDictKeysObject with 8 keys and 5 entries
-        s += calcsize("2nP2n") + 8 + 5*calcsize("n2P")
-        # class
         class newstyleclass(object): pass
-        check(newstyleclass, s)
+        # Separate block for PyDictKeysObject with 8 keys and 5 entries
+        check(newstyleclass, s + calcsize("2nP2n0P") + 8 + 5*calcsize("n2P"))
+        # dict with shared keys
+        check(newstyleclass().__dict__, size('nQ2P') + 5*self.P)
+        o = newstyleclass()
+        o.a = o.b = o.c = o.d = o.e = o.f = o.g = o.h = 1
+        # Separate block for PyDictKeysObject with 16 keys and 10 entries
+        check(newstyleclass, s + calcsize("2nP2n0P") + 16 + 10*calcsize("n2P"))
         # dict with shared keys
-        check(newstyleclass().__dict__, size('nQ2P' + '2nP2n'))
+        check(newstyleclass().__dict__, size('nQ2P') + 10*self.P)
         # unicode
         # each tuple contains a string and its expected character size
         # don't put any static strings here, as they may contain
index 8ffd1853147e49dfa93ca61d53aba4cd2f9eada0..db99b75eec6458e277703feadd4ca7900b1d40db 100644 (file)
@@ -662,32 +662,44 @@ class BigmemTclTest(unittest.TestCase):
     @support.bigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False)
     def test_huge_string_call(self, size):
         value = ' ' * size
-        self.assertRaises(OverflowError, self.interp.call, 'set', '_', value)
+        self.assertRaises(OverflowError, self.interp.call, 'string', 'index', value, 0)
 
     @support.cpython_only
     @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
-    @support.bigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False)
+    @support.bigmemtest(size=INT_MAX + 1, memuse=2, dry_run=False)
     def test_huge_string_builtins(self, size):
+        tk = self.interp.tk
         value = '1' + ' ' * size
-        self.assertRaises(OverflowError, self.interp.tk.getint, value)
-        self.assertRaises(OverflowError, self.interp.tk.getdouble, value)
-        self.assertRaises(OverflowError, self.interp.tk.getboolean, value)
-        self.assertRaises(OverflowError, self.interp.eval, value)
-        self.assertRaises(OverflowError, self.interp.evalfile, value)
-        self.assertRaises(OverflowError, self.interp.record, value)
-        self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
-        self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a')
-        self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a')
-        self.assertRaises(OverflowError, self.interp.unsetvar, value)
-        self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value)
-        self.assertRaises(OverflowError, self.interp.adderrorinfo, value)
-        self.assertRaises(OverflowError, self.interp.exprstring, value)
-        self.assertRaises(OverflowError, self.interp.exprlong, value)
-        self.assertRaises(OverflowError, self.interp.exprboolean, value)
-        self.assertRaises(OverflowError, self.interp.splitlist, value)
-        self.assertRaises(OverflowError, self.interp.split, value)
-        self.assertRaises(OverflowError, self.interp.createcommand, value, max)
-        self.assertRaises(OverflowError, self.interp.deletecommand, value)
+        self.assertRaises(OverflowError, tk.getint, value)
+        self.assertRaises(OverflowError, tk.getdouble, value)
+        self.assertRaises(OverflowError, tk.getboolean, value)
+        self.assertRaises(OverflowError, tk.eval, value)
+        self.assertRaises(OverflowError, tk.evalfile, value)
+        self.assertRaises(OverflowError, tk.record, value)
+        self.assertRaises(OverflowError, tk.adderrorinfo, value)
+        self.assertRaises(OverflowError, tk.setvar, value, 'x', 'a')
+        self.assertRaises(OverflowError, tk.setvar, 'x', value, 'a')
+        self.assertRaises(OverflowError, tk.unsetvar, value)
+        self.assertRaises(OverflowError, tk.unsetvar, 'x', value)
+        self.assertRaises(OverflowError, tk.adderrorinfo, value)
+        self.assertRaises(OverflowError, tk.exprstring, value)
+        self.assertRaises(OverflowError, tk.exprlong, value)
+        self.assertRaises(OverflowError, tk.exprboolean, value)
+        self.assertRaises(OverflowError, tk.splitlist, value)
+        self.assertRaises(OverflowError, tk.split, value)
+        self.assertRaises(OverflowError, tk.createcommand, value, max)
+        self.assertRaises(OverflowError, tk.deletecommand, value)
+
+    @support.cpython_only
+    @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX")
+    @support.bigmemtest(size=INT_MAX + 1, memuse=6, dry_run=False)
+    def test_huge_string_builtins2(self, size):
+        # These commands require larger memory for possible error messages
+        tk = self.interp.tk
+        value = '1' + ' ' * size
+        self.assertRaises(OverflowError, tk.evalfile, value)
+        self.assertRaises(OverflowError, tk.unsetvar, value)
+        self.assertRaises(OverflowError, tk.unsetvar, 'x', value)
 
 
 def setUpModule():
index 9cadc0f1c025a912e90c02f6febcad75b88d4bd6..b42314fdbb20d623f05b2bacd935827c82c905ad 100644 (file)
@@ -542,6 +542,35 @@ class ThreadTests(BaseTestCase):
         self.assertEqual(err, b"")
         self.assertEqual(data, "Thread-1\nTrue\nTrue\n")
 
+    def test_main_thread_during_shutdown(self):
+        # bpo-31516: current_thread() should still point to the main thread
+        # at shutdown
+        code = """if 1:
+            import gc, threading
+
+            main_thread = threading.current_thread()
+            assert main_thread is threading.main_thread()  # sanity check
+
+            class RefCycle:
+                def __init__(self):
+                    self.cycle = self
+
+                def __del__(self):
+                    print("GC:",
+                          threading.current_thread() is main_thread,
+                          threading.main_thread() is main_thread,
+                          threading.enumerate() == [main_thread])
+
+            RefCycle()
+            gc.collect()  # sanity check
+            x = RefCycle()
+        """
+        _, out, err = assert_python_ok("-c", code)
+        data = out.decode()
+        self.assertEqual(err, b"")
+        self.assertEqual(data.splitlines(),
+                         ["GC: True True True"] * 2)
+
     def test_tstate_lock(self):
         # Test an implementation detail of Thread objects.
         started = _thread.allocate_lock()
index 7093fc6a2ec1729dde75c216bb45372a75d809c5..5b6e58fa55756eb29abf39b7544a0fa006e4c9e4 100644 (file)
@@ -36,6 +36,8 @@ class _PyTime(enum.IntEnum):
     ROUND_CEILING = 1
     # Round to nearest with ties going to nearest even integer
     ROUND_HALF_EVEN = 2
+    # Round away from zero
+    ROUND_UP = 3
 
 # Rounding modes supported by PyTime
 ROUNDING_MODES = (
@@ -43,6 +45,7 @@ ROUNDING_MODES = (
     (_PyTime.ROUND_FLOOR, decimal.ROUND_FLOOR),
     (_PyTime.ROUND_CEILING, decimal.ROUND_CEILING),
     (_PyTime.ROUND_HALF_EVEN, decimal.ROUND_HALF_EVEN),
+    (_PyTime.ROUND_UP, decimal.ROUND_UP),
 )
 
 
index 10e0ad807798e154e4842f27bd5c7d379b6e7f56..ef02342244c5ae2bb3f597e938a8c5b783a2f15a 100644 (file)
@@ -630,6 +630,11 @@ def"', """\
     NAME       'async'       (1, 0) (1, 5)
     OP         '='           (1, 6) (1, 7)
     NUMBER     '1'           (1, 8) (1, 9)
+    """)
+
+        self.check_tokenize("async\\", """\
+    ERRORTOKEN '\\\\'          (1, 5) (1, 6)
+    NAME       'async'       (1, 0) (1, 5)
     """)
 
         self.check_tokenize("a = (async = 1)", """\
index 65dee1b5ae4960e77dc7e698f3a3a6900457f76b..f3386f5e31a2df7c5209b60e41e8cb95aa62a9c8 100644 (file)
@@ -263,15 +263,18 @@ class UnparseTestCase(ASTTestCase):
 
 class DirectoryTestCase(ASTTestCase):
     """Test roundtrip behaviour on all files in Lib and Lib/test."""
+    NAMES = None
 
     # test directories, relative to the root of the distribution
     test_directories = 'Lib', os.path.join('Lib', 'test')
 
-    def test_files(self):
-        # get names of files to test
+    @classmethod
+    def get_names(cls):
+        if cls.NAMES is not None:
+            return cls.NAMES
 
         names = []
-        for d in self.test_directories:
+        for d in cls.test_directories:
             test_dir = os.path.join(basepath, d)
             for n in os.listdir(test_dir):
                 if n.endswith('.py') and not n.startswith('bad'):
@@ -280,6 +283,14 @@ class DirectoryTestCase(ASTTestCase):
         # Test limited subset of files unless the 'cpu' resource is specified.
         if not test.support.is_resource_enabled("cpu"):
             names = random.sample(names, 10)
+        # bpo-31174: Store the names sample to always test the same files.
+        # It prevents false alarms when hunting reference leaks.
+        cls.NAMES = names
+        return names
+
+    def test_files(self):
+        # get names of files to test
+        names = self.get_names()
 
         for filename in names:
             if test.support.verbose:
index e4833535890d157f88643403d157f1d1d1695d81..bffc03e663ff787f29c0bb9c8fcb9ace7586bc09 100644 (file)
@@ -443,6 +443,33 @@ class TracebackFormatTests(unittest.TestCase):
             '    return traceback.format_stack()\n' % (__file__, lineno+1),
         ])
 
+    @cpython_only
+    def test_unhashable(self):
+        from _testcapi import exception_print
+
+        class UnhashableException(Exception):
+            def __eq__(self, other):
+                return True
+
+        ex1 = UnhashableException('ex1')
+        ex2 = UnhashableException('ex2')
+        try:
+            raise ex2 from ex1
+        except UnhashableException:
+            try:
+                raise ex1
+            except UnhashableException:
+                exc_type, exc_val, exc_tb = sys.exc_info()
+
+        with captured_output("stderr") as stderr_f:
+            exception_print(exc_val)
+
+        tb = stderr_f.getvalue().strip().splitlines()
+        self.assertEqual(11, len(tb))
+        self.assertEqual(context_message.strip(), tb[5])
+        self.assertIn('UnhashableException: ex2', tb[3])
+        self.assertIn('UnhashableException: ex1', tb[10])
+
 
 cause_message = (
     "\nThe above exception was the direct cause "
@@ -994,6 +1021,25 @@ class TestTracebackException(unittest.TestCase):
         self.assertEqual(exc_info[0], exc.exc_type)
         self.assertEqual(str(exc_info[1]), str(exc))
 
+    def test_unhashable(self):
+        class UnhashableException(Exception):
+            def __eq__(self, other):
+                return True
+
+        ex1 = UnhashableException('ex1')
+        ex2 = UnhashableException('ex2')
+        try:
+            raise ex2 from ex1
+        except UnhashableException:
+            try:
+                raise ex1
+            except UnhashableException:
+                exc_info = sys.exc_info()
+        exc = traceback.TracebackException(*exc_info)
+        formatted = list(exc.format())
+        self.assertIn('UnhashableException: ex2\n', formatted[2])
+        self.assertIn('UnhashableException: ex1\n', formatted[6])
+
     def test_limit(self):
         def recurse(n):
             if n:
index 382ca03e5ad2b8deb843b504d5ad55b0e9c9ec6e..73fbdbf9b904c995d80fdd06c534e0b6cf5c8723 100644 (file)
@@ -846,6 +846,28 @@ class ClassCreationTests(unittest.TestCase):
         self.assertIs(ns, expected_ns)
         self.assertEqual(len(kwds), 0)
 
+    def test_bad___prepare__(self):
+        # __prepare__() must return a mapping.
+        class BadMeta(type):
+            @classmethod
+            def __prepare__(*args):
+                return None
+        with self.assertRaisesRegex(TypeError,
+                                    r'^BadMeta\.__prepare__\(\) must '
+                                    r'return a mapping, not NoneType$'):
+            class Foo(metaclass=BadMeta):
+                pass
+        # Also test the case in which the metaclass is not a type.
+        class BadMeta:
+            @classmethod
+            def __prepare__(*args):
+                return None
+        with self.assertRaisesRegex(TypeError,
+                                    r'^<metaclass>\.__prepare__\(\) must '
+                                    r'return a mapping, not NoneType$'):
+            class Bar(metaclass=BadMeta()):
+                pass
+
     def test_metaclass_derivation(self):
         # issue1294232: correct metaclass calculation
         new_calls = []  # to check the order of __new__ calls
@@ -1029,6 +1051,8 @@ class SimpleNamespaceTests(unittest.TestCase):
 
         with self.assertRaises(TypeError):
             types.SimpleNamespace(1, 2, 3)
+        with self.assertRaises(TypeError):
+            types.SimpleNamespace(**{1: 2})
 
         self.assertEqual(len(ns1.__dict__), 0)
         self.assertEqual(vars(ns1), {})
index a3b2ea7f03e5f2f3de5b494930f39791cb13bb21..fe5247c260278a201afc310e437d873a89a14d92 100644 (file)
@@ -37,6 +37,9 @@ except ImportError:
     from test import mod_generics_cache
 
 
+PY36 = sys.version_info[:2] >= (3, 6)
+
+
 class BaseTestCase(TestCase):
 
     def assertIsSubclass(self, cls, class_or_tuple, msg=None):
@@ -633,6 +636,27 @@ class GenericTests(BaseTestCase):
         with self.assertRaises(TypeError):
             Generic[T, S, T]
 
+    @skipUnless(PY36, "__init_subclass__ support required")
+    def test_init_subclass(self):
+        class X(typing.Generic[T]):
+            def __init_subclass__(cls, **kwargs):
+                super().__init_subclass__(**kwargs)
+                cls.attr = 42
+        class Y(X):
+            pass
+        self.assertEqual(Y.attr, 42)
+        with self.assertRaises(AttributeError):
+            X.attr
+        X.attr = 1
+        Y.attr = 2
+        class Z(Y):
+            pass
+        class W(X[int]):
+            pass
+        self.assertEqual(Y.attr, 2)
+        self.assertEqual(Z.attr, 42)
+        self.assertEqual(W.attr, 42)
+
     def test_repr(self):
         self.assertEqual(repr(SimpleMapping),
                          __name__ + '.' + 'SimpleMapping')
@@ -1080,6 +1104,30 @@ class GenericTests(BaseTestCase):
                 self.assertTrue(t is copy(t))
                 self.assertTrue(t is deepcopy(t))
 
+    def test_copy_generic_instances(self):
+        T = TypeVar('T')
+        class C(Generic[T]):
+            def __init__(self, attr: T) -> None:
+                self.attr = attr
+
+        c = C(42)
+        self.assertEqual(copy(c).attr, 42)
+        self.assertEqual(deepcopy(c).attr, 42)
+        self.assertIsNot(copy(c), c)
+        self.assertIsNot(deepcopy(c), c)
+        c.attr = 1
+        self.assertEqual(copy(c).attr, 1)
+        self.assertEqual(deepcopy(c).attr, 1)
+        ci = C[int](42)
+        self.assertEqual(copy(ci).attr, 42)
+        self.assertEqual(deepcopy(ci).attr, 42)
+        self.assertIsNot(copy(ci), ci)
+        self.assertIsNot(deepcopy(ci), ci)
+        ci.attr = 1
+        self.assertEqual(copy(ci).attr, 1)
+        self.assertEqual(deepcopy(ci).attr, 1)
+        self.assertEqual(ci.__orig_class__, C[int])
+
     def test_weakref_all(self):
         T = TypeVar('T')
         things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any],
@@ -1471,8 +1519,8 @@ class ForwardRefTests(BaseTestCase):
     def test_meta_no_type_check(self):
 
         @no_type_check_decorator
-        def magic_decorator(deco):
-            return deco
+        def magic_decorator(func):
+            return func
 
         self.assertEqual(magic_decorator.__name__, 'magic_decorator')
 
@@ -1580,8 +1628,6 @@ else:
     asyncio = None
     AwaitableWrapper = AsyncIteratorWrapper = ACM = object
 
-PY36 = sys.version_info[:2] >= (3, 6)
-
 PY36_TESTS = """
 from test import ann_module, ann_module2, ann_module3
 from typing import AsyncContextManager
index 47248f92c7b6af3275029f702526d21316d091ec..4373fba12ac85e96e2ed2123061d479f8183db6a 100644 (file)
@@ -438,59 +438,57 @@ eth0      Link encap:Ethernet  HWaddr 12:34:56:78:90:ab
 
         self.assertEqual(mac, 0x1234567890ab)
 
-    def check_node(self, node, requires=None, network=False):
+    def check_node(self, node, requires=None):
         if requires and node is None:
             self.skipTest('requires ' + requires)
         hex = '%012x' % node
         if support.verbose >= 2:
             print(hex, end=' ')
-        if network:
-            # 47 bit will never be set in IEEE 802 addresses obtained
-            # from network cards.
-            self.assertFalse(node & 0x010000000000, hex)
         self.assertTrue(0 < node < (1 << 48),
                         "%s is not an RFC 4122 node ID" % hex)
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
     def test_ifconfig_getnode(self):
         node = uuid._ifconfig_getnode()
-        self.check_node(node, 'ifconfig', True)
+        self.check_node(node, 'ifconfig')
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
     def test_ip_getnode(self):
         node = uuid._ip_getnode()
-        self.check_node(node, 'ip', True)
+        self.check_node(node, 'ip')
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
     def test_arp_getnode(self):
         node = uuid._arp_getnode()
-        self.check_node(node, 'arp', True)
+        self.check_node(node, 'arp')
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
     def test_lanscan_getnode(self):
         node = uuid._lanscan_getnode()
-        self.check_node(node, 'lanscan', True)
+        self.check_node(node, 'lanscan')
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
     def test_netstat_getnode(self):
         node = uuid._netstat_getnode()
-        self.check_node(node, 'netstat', True)
+        self.check_node(node, 'netstat')
 
     @unittest.skipUnless(os.name == 'nt', 'requires Windows')
     def test_ipconfig_getnode(self):
         node = uuid._ipconfig_getnode()
-        self.check_node(node, 'ipconfig', True)
+        self.check_node(node, 'ipconfig')
 
     @unittest.skipUnless(importable('win32wnet'), 'requires win32wnet')
     @unittest.skipUnless(importable('netbios'), 'requires netbios')
     def test_netbios_getnode(self):
         node = uuid._netbios_getnode()
-        self.check_node(node, network=True)
+        self.check_node(node)
 
     def test_random_getnode(self):
         node = uuid._random_getnode()
-        # Least significant bit of first octet must be set.
-        self.assertTrue(node & 0x010000000000, '%012x' % node)
+        # The multicast bit, i.e. the least significant bit of first octet,
+        # must be set for randomly generated MAC addresses.  See RFC 4122,
+        # $4.1.6.
+        self.assertTrue(node & (1 << 40), '%012x' % node)
         self.check_node(node)
 
     @unittest.skipUnless(os.name == 'posix', 'requires Posix')
index 2691632ff4f857a0a1b487c648e6590305ca07a5..0c1ea89b51c0d85ab74aeb32eb3635492b2816d9 100644 (file)
@@ -13,7 +13,7 @@ import struct
 import subprocess
 import sys
 import tempfile
-from test.support import (captured_stdout, captured_stderr,
+from test.support import (captured_stdout, captured_stderr, requires_zlib,
                           can_symlink, EnvironmentVarGuard, rmtree)
 import unittest
 import venv
@@ -424,6 +424,7 @@ class EnsurePipTest(BaseTest):
                                     ' module unconditionally')
     # Issue #26610: pip/pep425tags.py requires ctypes
     @unittest.skipUnless(ctypes, 'pip requires ctypes')
+    @requires_zlib
     def test_with_pip(self):
         self.do_test_with_pip(False)
         self.do_test_with_pip(True)
index 354da6b46f01d01861589573292efbcef160405a..ea81d119160c8e1176b35e0378d2717439a36616 100644 (file)
@@ -794,6 +794,42 @@ class _WarningsTests(BaseTest, unittest.TestCase):
         self.assertNotIn(b'Warning!', stderr)
         self.assertNotIn(b'Error', stderr)
 
+    def test_issue31285(self):
+        # warn_explicit() should neither raise a SystemError nor cause an
+        # assertion failure, in case the return value of get_source() has a
+        # bad splitlines() method.
+        def get_bad_loader(splitlines_ret_val):
+            class BadLoader:
+                def get_source(self, fullname):
+                    class BadSource(str):
+                        def splitlines(self):
+                            return splitlines_ret_val
+                    return BadSource('spam')
+            return BadLoader()
+
+        wmod = self.module
+        with original_warnings.catch_warnings(module=wmod):
+            wmod.filterwarnings('default', category=UserWarning)
+
+            with support.captured_stderr() as stderr:
+                wmod.warn_explicit(
+                    'foo', UserWarning, 'bar', 1,
+                    module_globals={'__loader__': get_bad_loader(42),
+                                    '__name__': 'foobar'})
+            self.assertIn('UserWarning: foo', stderr.getvalue())
+
+            show = wmod._showwarnmsg
+            try:
+                del wmod._showwarnmsg
+                with support.captured_stderr() as stderr:
+                    wmod.warn_explicit(
+                        'eggs', UserWarning, 'bar', 1,
+                        module_globals={'__loader__': get_bad_loader([42]),
+                                        '__name__': 'foobar'})
+                self.assertIn('UserWarning: eggs', stderr.getvalue())
+            finally:
+                wmod._showwarnmsg = show
+
     @support.cpython_only
     def test_issue31411(self):
         # warn_explicit() shouldn't raise a SystemError in case
@@ -820,6 +856,16 @@ class _WarningsTests(BaseTest, unittest.TestCase):
                  self.assertRaises(TypeError):
                 wmod.warn_explicit('foo', Warning, 'bar', 1)
 
+    @support.cpython_only
+    def test_issue31566(self):
+        # warn() shouldn't cause an assertion failure in case of a bad
+        # __name__ global.
+        with original_warnings.catch_warnings(module=self.module):
+            self.module.filterwarnings('error', category=UserWarning)
+            with support.swap_item(globals(), '__name__', b'foo'), \
+                 support.swap_item(globals(), '__file__', None):
+                self.assertRaises(UserWarning, self.module.warn, 'bar')
+
 
 class WarningsDisplayTests(BaseTest):
 
index ad0ffb31aa49a0809f19625f249bdf20a02813ba..7adfbdfd7a9e94a83e34bd98ea38229e459666d2 100644 (file)
@@ -33,6 +33,7 @@ try:
 except UnicodeEncodeError:
     raise unittest.SkipTest("filename is not encodable to utf8")
 SIMPLE_NS_XMLFILE = findfile("simple-ns.xml", subdir="xmltestdata")
+UTF8_BUG_XMLFILE = findfile("expat224_utf8_bug.xml", subdir="xmltestdata")
 
 SAMPLE_XML = """\
 <body>
@@ -1724,6 +1725,37 @@ class BugsTest(unittest.TestCase):
         self.assertIsInstance(e[0].tag, str)
         self.assertEqual(e[0].tag, 'changed')
 
+    def check_expat224_utf8_bug(self, text):
+        xml = b'<a b="%s"/>' % text
+        root = ET.XML(xml)
+        self.assertEqual(root.get('b'), text.decode('utf-8'))
+
+    def test_expat224_utf8_bug(self):
+        # bpo-31170: Expat 2.2.3 had a bug in its UTF-8 decoder.
+        # Check that Expat 2.2.4 fixed the bug.
+        #
+        # Test buffer bounds at odd and even positions.
+
+        text = b'\xc3\xa0' * 1024
+        self.check_expat224_utf8_bug(text)
+
+        text = b'x' + b'\xc3\xa0' * 1024
+        self.check_expat224_utf8_bug(text)
+
+    def test_expat224_utf8_bug_file(self):
+        with open(UTF8_BUG_XMLFILE, 'rb') as fp:
+            raw = fp.read()
+        root = ET.fromstring(raw)
+        xmlattr = root.get('b')
+
+        # "Parse" manually the XML file to extract the value of the 'b'
+        # attribute of the <a b='xxx' /> XML element
+        text = raw.decode('utf-8').strip()
+        text = text.replace('\r\n', ' ')
+        text = text[6:-4]
+        self.assertEqual(root.get('b'), text)
+
+
 
 # --------------------------------------------------------------------
 
index b2200d31f59dbfc01e9b113caf6b3b6863bb7eda..d99b4e7527fbd9c6043b94d7b45991f1c7f144cb 100644 (file)
@@ -84,6 +84,38 @@ class MiscTests(unittest.TestCase):
         # and so destroy the parser
         support.gc_collect()
 
+    def test_bpo_31728(self):
+        # A crash or an assertion failure shouldn't happen, in case garbage
+        # collection triggers a call to clear() or a reading of text or tail,
+        # while a setter or clear() or __setstate__() is already running.
+        elem = cET.Element('elem')
+        class X:
+            def __del__(self):
+                elem.text
+                elem.tail
+                elem.clear()
+
+        elem.text = X()
+        elem.clear()  # shouldn't crash
+
+        elem.tail = X()
+        elem.clear()  # shouldn't crash
+
+        elem.text = X()
+        elem.text = X()  # shouldn't crash
+        elem.clear()
+
+        elem.tail = X()
+        elem.tail = X()  # shouldn't crash
+        elem.clear()
+
+        elem.text = X()
+        elem.__setstate__({'tag': 42})  # shouldn't cause an assertion failure
+        elem.clear()
+
+        elem.tail = X()
+        elem.__setstate__({'tag': 42})  # shouldn't cause an assertion failure
+
 
 @unittest.skipUnless(cET, 'requires _elementtree')
 class TestAliasWorking(unittest.TestCase):
index ae0a28e7215741b1be12675281e62c0a23ed406c..f3652b86f75102431c26908a10cc58f5d96e7905 100644 (file)
@@ -4,6 +4,8 @@ from test import support
 
 import xmlrpc.client as xmlrpclib
 
+
+@unittest.skip('XXX: buildbot.python.org/all/xmlrpc/ is gone')
 class PythonBuildersTest(unittest.TestCase):
 
     def test_python_builders(self):
diff --git a/Lib/test/xmltestdata/expat224_utf8_bug.xml b/Lib/test/xmltestdata/expat224_utf8_bug.xml
new file mode 100644 (file)
index 0000000..d66a8e6
--- /dev/null
@@ -0,0 +1,2 @@
+<a b='01234567890123456古人咏雪抽幽思骋妍辞竞险韵偶得一编奇绝辄擅美当时流声后代是以北门之风南山之雅梁园之简黄台之赋至今为作家称述尚矣及至洛阳之卧剡溪之兴灞桥之思亦皆传为故事钱塘沈履德先生隐居西湖两峰间孤高贞洁与雪同调方大雪满天皴肤粟背之际先生乃鹿中豹舄端居闭门或扶童曳杖踏遍六桥三竺时取古人诗讽咏之合唐宋元诸名家集句成诗得二百四十章联络通穿如出一人如呵一气气立于言表格备于篇中略无掇拾补凑之形非胸次包罗壮阔笔底驱走鲍谢欧苏诸公不能为此世称王荆公为集句擅长观其在钟山对雪仅题数篇未见有此噫嘻奇矣哉亦富矣哉予慕先生有袁安之节愧不能为慧可之立乃取新集命工传写使海内同好者知先生为博古传述之士而一新世人之耳目他日必有慕潜德阐幽光而剞劂以传者余实为之执殳矣\r
+弘治戊午仲冬望日慈溪杨子器衵于海虞官舍序毕诗部' />\r
index 95978d310a2f3aa9780248dac71d0b7bca113d37..bb2556544b07814608d0e6b23a70045139810ebd 100644 (file)
@@ -1182,8 +1182,8 @@ class Timer(Thread):
             self.function(*self.args, **self.kwargs)
         self.finished.set()
 
+
 # Special thread class to represent the main thread
-# This is garbage collected through an exit handler
 
 class _MainThread(Thread):
 
@@ -1293,7 +1293,6 @@ def _shutdown():
     while t:
         t.join()
         t = _pickSomeNonDaemonThread()
-    _main_thread._delete()
 
 def _pickSomeNonDaemonThread():
     for t in enumerate():
index 26766a8a1fe75b095f311003d0a0068b9a979f89..ab0db2878e13df4dcf000c3635eef2ffdd107207 100644 (file)
@@ -1556,7 +1556,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
         self.tv.selection_toggle((c1, c3))
         self.assertEqual(self.tv.selection(), (c3, item2))
 
-        if sys.version_info >= (3, 7):
+        if sys.version_info >= (3, 8):
             import warnings
             warnings.warn(
                 'Deprecated API of Treeview.selection() should be removed')
index 2a3e1cec7015a003d2756599788cdbbbfbe404b0..635b500579ec6918bf39ca165dfc80e86d5864e8 100644 (file)
@@ -1404,13 +1404,13 @@ class Treeview(Widget, tkinter.XView, tkinter.YView):
             import warnings
             warnings.warn(
                 "The selop=None argument of selection() is deprecated "
-                "and will be removed in Python 3.7",
+                "and will be removed in Python 3.8",
                 DeprecationWarning, 3)
         elif selop in ('set', 'add', 'remove', 'toggle'):
             import warnings
             warnings.warn(
                 "The selop argument of selection() is deprecated "
-                "and will be removed in Python 3.7, "
+                "and will be removed in Python 3.8, "
                 "use selection_%s() instead" % (selop,),
                 DeprecationWarning, 3)
         else:
index 09bda717ad04768c73ed1d23d799aaa50f031b82..41fefff9c2dcfe420b77e1bf6ed18db6e2843067 100644 (file)
@@ -459,11 +459,11 @@ class TracebackException:
         # Handle loops in __cause__ or __context__.
         if _seen is None:
             _seen = set()
-        _seen.add(exc_value)
+        _seen.add(id(exc_value))
         # Gracefully handle (the way Python 2.4 and earlier did) the case of
         # being called with no type or value (None, None, None).
         if (exc_value and exc_value.__cause__ is not None
-            and exc_value.__cause__ not in _seen):
+            and id(exc_value.__cause__) not in _seen):
             cause = TracebackException(
                 type(exc_value.__cause__),
                 exc_value.__cause__,
@@ -475,7 +475,7 @@ class TracebackException:
         else:
             cause = None
         if (exc_value and exc_value.__context__ is not None
-            and exc_value.__context__ not in _seen):
+            and id(exc_value.__context__) not in _seen):
             context = TracebackException(
                 type(exc_value.__context__),
                 exc_value.__context__,
index 0a58332a6664007ff111e0008c49b80619872f8e..6daf694427d4cfe6dfef6898204722cf7ec7b2dd 100644 (file)
@@ -136,7 +136,7 @@ class DemoWindow(object):
             import subprocess
             # Make sure we are the currently activated OS X application
             # so that our menu bar appears.
-            p = subprocess.Popen(
+            subprocess.run(
                     [
                         'osascript',
                         '-e', 'tell application "System Events"',
index c00a3a10e1fae1b1538fbb7f15ce7a0968d5adde..b5564cc29a2d830eb833564d37e332a7e7ee9b49 100644 (file)
@@ -973,7 +973,8 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
         # remove bare Generic from bases if there are other generic bases
         if any(isinstance(b, GenericMeta) and b is not Generic for b in bases):
             bases = tuple(b for b in bases if b is not Generic)
-        namespace.update({'__origin__': origin, '__extra__': extra})
+        namespace.update({'__origin__': origin, '__extra__': extra,
+                          '_gorg': None if not origin else origin._gorg})
         self = super().__new__(cls, name, bases, namespace, _root=True)
         super(GenericMeta, self).__setattr__('_gorg',
                                              self if not origin else origin._gorg)
@@ -1160,17 +1161,12 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
         # classes are supposed to be rare anyways.
         return issubclass(instance.__class__, self)
 
-    def __copy__(self):
-        return self.__class__(self.__name__, self.__bases__,
-                              _no_slots_copy(self.__dict__),
-                              self.__parameters__, self.__args__, self.__origin__,
-                              self.__extra__, self.__orig_bases__)
-
     def __setattr__(self, attr, value):
         # We consider all the subscripted generics as proxies for original class
         if (
             attr.startswith('__') and attr.endswith('__') or
-            attr.startswith('_abc_')
+            attr.startswith('_abc_') or
+            self._gorg is None  # The class is not fully created, see #typing/506
         ):
             super(GenericMeta, self).__setattr__(attr, value)
         else:
index f4dbc52852dc1356f7b69254ad36deb8ea72f2b0..c3634ec997f86bd3b278124efbe19113e9dfbe21 100644 (file)
@@ -842,7 +842,8 @@ class TestCase(object):
         """Fail if the two objects are unequal as determined by their
            difference rounded to the given number of decimal places
            (default 7) and comparing to zero, or by comparing that the
-           between the two objects is more than the given delta.
+           difference between the two objects is more than the given
+           delta.
 
            Note that decimal places (from zero) are usually not the same
            as significant digits (measured from the most significant digit).
@@ -881,7 +882,7 @@ class TestCase(object):
         """Fail if the two objects are equal as determined by their
            difference rounded to the given number of decimal places
            (default 7) and comparing to zero, or by comparing that the
-           between the two objects is less than the given delta.
+           difference between the two objects is less than the given delta.
 
            Note that decimal places (from zero) are usually not the same
            as significant digits (measured from the most significant digit).
index 9dab4c1c3a8880c5d306030610d9accad528bf4e..daac29c68dc36d2c771ae2a8f13b07aa36a4b2c9 100644 (file)
@@ -16,6 +16,9 @@ import urllib.request
 
 __all__ = ["RobotFileParser"]
 
+RequestRate = collections.namedtuple("RequestRate", "requests seconds")
+
+
 class RobotFileParser:
     """ This class provides a set of methods to read, parse and answer
     questions about a single robots.txt file.
@@ -136,11 +139,7 @@ class RobotFileParser:
                         # check if all values are sane
                         if (len(numbers) == 2 and numbers[0].strip().isdigit()
                             and numbers[1].strip().isdigit()):
-                            req_rate = collections.namedtuple('req_rate',
-                                                              'requests seconds')
-                            entry.req_rate = req_rate
-                            entry.req_rate.requests = int(numbers[0])
-                            entry.req_rate.seconds = int(numbers[1])
+                            entry.req_rate = RequestRate(int(numbers[0]), int(numbers[1]))
                         state = 2
         if state == 2:
             self._add_entry(entry)
index 200c800b34e4bbd36e124c7b5326126fba5716e9..20b02da1ae4e7edb44aefccd9be5c92178458b2b 100644 (file)
@@ -349,8 +349,9 @@ def _find_mac(command, args, hw_identifiers, get_index):
 def _ifconfig_getnode():
     """Get the hardware address on Unix by running ifconfig."""
     # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
+    keywords = (b'hwaddr', b'ether', b'address:', b'lladdr')
     for args in ('', '-a', '-av'):
-        mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1)
+        mac = _find_mac('ifconfig', args, keywords, lambda i: i+1)
         if mac:
             return mac
 
@@ -370,7 +371,20 @@ def _arp_getnode():
         return None
 
     # Try getting the MAC addr from arp based on our IP address (Solaris).
-    return _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
+    mac = _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1)
+    if mac:
+        return mac
+
+    # This works on OpenBSD
+    mac = _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: i+1)
+    if mac:
+        return mac
+
+    # This works on Linux, FreeBSD and NetBSD
+    mac = _find_mac('arp', '-an', [os.fsencode('(%s)' % ip_addr)],
+                    lambda i: i+2)
+    if mac:
+        return mac
 
 def _lanscan_getnode():
     """Get the hardware address on Unix by running lanscan."""
index c78a4efa153fc4a37a74731a4776ad4255456327..fff0765af53b82d550d55833e98a72dbdc457ddb 100644 (file)
@@ -3,13 +3,13 @@
 
 deactivate () {
     # reset old environment variables
-    if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
-        PATH="$_OLD_VIRTUAL_PATH"
+    if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
+        PATH="${_OLD_VIRTUAL_PATH:-}"
         export PATH
         unset _OLD_VIRTUAL_PATH
     fi
-    if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
-        PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
+    if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
+        PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
         export PYTHONHOME
         unset _OLD_VIRTUAL_PYTHONHOME
     fi
@@ -17,12 +17,12 @@ deactivate () {
     # This should detect bash and zsh, which have a hash command that must
     # be called to get it to forget past commands.  Without forgetting
     # past commands the $PATH changes we made may not be respected
-    if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+    if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
         hash -r
     fi
 
-    if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
-        PS1="$_OLD_VIRTUAL_PS1"
+    if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
+        PS1="${_OLD_VIRTUAL_PS1:-}"
         export PS1
         unset _OLD_VIRTUAL_PS1
     fi
@@ -47,15 +47,15 @@ export PATH
 # unset PYTHONHOME if set
 # this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
 # could use `if (set -u; : $PYTHONHOME) ;` in bash
-if [ -n "$PYTHONHOME" ] ; then
-    _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
+if [ -n "${PYTHONHOME:-}" ] ; then
+    _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
     unset PYTHONHOME
 fi
 
-if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
-    _OLD_VIRTUAL_PS1="$PS1"
+if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
+    _OLD_VIRTUAL_PS1="${PS1:-}"
     if [ "x__VENV_PROMPT__" != x ] ; then
-       PS1="__VENV_PROMPT__$PS1"
+       PS1="__VENV_PROMPT__${PS1:-}"
     else
     if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
         # special case for Aspen magic directories
@@ -71,6 +71,6 @@ fi
 # This should detect bash and zsh, which have a hash command that must
 # be called to get it to forget past commands.  Without forgetting
 # past commands the $PATH changes we made may not be respected
-if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
+if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
     hash -r
 fi
index 4cb7e3214cd40a0c7abbf6f3ffaa2bfdce39d1bb..52f391a43166330b77644c6cad1a6409133a52fd 100755 (executable)
@@ -213,9 +213,9 @@ def library_recipes():
 
     result.extend([
           dict(
-              name="OpenSSL 1.0.2k",
-              url="https://www.openssl.org/source/openssl-1.0.2k.tar.gz",
-              checksum='f965fc0bf01bf882b31314b61391ae65',
+              name="OpenSSL 1.0.2m",
+              url="https://www.openssl.org/source/openssl-1.0.2m.tar.gz",
+              checksum='10e9e37f492094b9ef296f68f24a7666',
               patches=[
                   "openssl_sdk_makedepend.patch",
                    ],
@@ -315,9 +315,9 @@ def library_recipes():
                   ),
           ),
           dict(
-              name="SQLite 3.14.2",
-              url="https://www.sqlite.org/2016/sqlite-autoconf-3140200.tar.gz",
-              checksum='90c53cacb811db27f990b8292bd96159',
+              name="SQLite 3.21.0",
+              url="https://www.sqlite.org/2017/sqlite-autoconf-3210000.tar.gz",
+              checksum='7913de4c3126ba3c24689cb7a199ea31',
               extra_cflags=('-Os '
                             '-DSQLITE_ENABLE_FTS5 '
                             '-DSQLITE_ENABLE_FTS4 '
@@ -844,7 +844,6 @@ def build_universal_openssl(basedir, archList):
             "enable-tlsext",
             "no-ssl2",
             "no-ssl3",
-            "no-ssl3-method",
             # "enable-unit-test",
             "shared",
             "--install_prefix=%s"%shellQuote(archbase),
index 6cb0c63e5d620ea3eb675e2a6b213ac126f34432..5e88e3f6aa1ec0b0716030f724cae8c9905c697a 100644 (file)
@@ -230,6 +230,7 @@ PYTHON=             python$(EXE)
 BUILDPYTHON=   python$(BUILDEXE)
 
 PYTHON_FOR_REGEN=@PYTHON_FOR_REGEN@
+UPDATE_FILE=@PYTHON_FOR_REGEN@ $(srcdir)/Tools/scripts/update_file.py
 PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@
 _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@
 BUILD_GNU_TYPE=        @build@
@@ -439,7 +440,17 @@ DTRACE_DEPS = \
 
 # Default target
 all:           @DEF_MAKE_ALL_RULE@
-build_all:     $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Programs/_testembed python-config
+build_all:     check-clean-src $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks \
+               Programs/_testembed python-config
+
+# Check that the source is clean when building out of source.
+check-clean-src:
+       @if test -n "$(VPATH)" -a -f "$(srcdir)/Programs/python.o"; then \
+               echo "Error: The source directory ($(srcdir)) is not clean" ; \
+               echo "Building Python out of the source tree (in $(abs_builddir)) requires a clean source tree ($(abs_srcdir))" ; \
+               echo "Try to run: make -C \"$(srcdir)\" clean" ; \
+               exit 1; \
+       fi
 
 # Compile a binary with profile guided optimization.
 profile-opt:
@@ -529,7 +540,7 @@ coverage-report: regen-grammar regen-importlib
 # Run "Argument Clinic" over all source files
 # (depends on python having already been built)
 .PHONY=clinic
-clinic: $(BUILDPYTHON) $(srcdir)/Modules/_blake2/blake2s_impl.c
+clinic: check-clean-src $(BUILDPYTHON) $(srcdir)/Modules/_blake2/blake2s_impl.c
        $(RUNSHARED) $(PYTHON_FOR_BUILD) ./Tools/clinic/clinic.py --make
 
 # Build the interpreter
@@ -696,12 +707,14 @@ regen-importlib: Programs/_freeze_importlib
        # from Lib/importlib/_bootstrap_external.py using _freeze_importlib
        ./Programs/_freeze_importlib \
            $(srcdir)/Lib/importlib/_bootstrap_external.py \
-           $(srcdir)/Python/importlib_external.h
+           $(srcdir)/Python/importlib_external.h.new
+       $(UPDATE_FILE) $(srcdir)/Python/importlib_external.h $(srcdir)/Python/importlib_external.h.new
        # Regenerate Python/importlib.h from Lib/importlib/_bootstrap.py
        # using _freeze_importlib
        ./Programs/_freeze_importlib \
            $(srcdir)/Lib/importlib/_bootstrap.py \
-           $(srcdir)/Python/importlib.h
+           $(srcdir)/Python/importlib.h.new
+       $(UPDATE_FILE) $(srcdir)/Python/importlib.h $(srcdir)/Python/importlib.h.new
 
 
 ############################################################################
@@ -775,8 +788,10 @@ regen-grammar: $(PGEN)
        # from Grammar/Grammar using pgen
        @$(MKDIR_P) Include
        $(PGEN) $(srcdir)/Grammar/Grammar \
-               $(srcdir)/Include/graminit.h \
-               $(srcdir)/Python/graminit.c
+               $(srcdir)/Include/graminit.h.new \
+               $(srcdir)/Python/graminit.c.new
+       $(UPDATE_FILE) $(srcdir)/Include/graminit.h $(srcdir)/Include/graminit.h.new
+       $(UPDATE_FILE) $(srcdir)/Python/graminit.c $(srcdir)/Python/graminit.c.new
 
 Parser/grammar.o:      $(srcdir)/Parser/grammar.c \
                                $(srcdir)/Include/token.h \
@@ -794,13 +809,15 @@ regen-ast:
        # Regenerate Include/Python-ast.h using Parser/asdl_c.py -h
        $(MKDIR_P) $(srcdir)/Include
        $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \
-               -h $(srcdir)/Include \
+               -h $(srcdir)/Include/Python-ast.h.new \
                $(srcdir)/Parser/Python.asdl
+       $(UPDATE_FILE) $(srcdir)/Include/Python-ast.h $(srcdir)/Include/Python-ast.h.new
        # Regenerate Python/Python-ast.c using Parser/asdl_c.py -c
        $(MKDIR_P) $(srcdir)/Python
        $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \
-               -c $(srcdir)/Python \
+               -c $(srcdir)/Python/Python-ast.c.new \
                $(srcdir)/Parser/Python.asdl
+       $(UPDATE_FILE) $(srcdir)/Python/Python-ast.c $(srcdir)/Python/Python-ast.c.new
 
 .PHONY: regen-opcode
 regen-opcode:
@@ -808,7 +825,8 @@ regen-opcode:
        # using Tools/scripts/generate_opcode_h.py
        $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_opcode_h.py \
                $(srcdir)/Lib/opcode.py \
-               $(srcdir)/Include/opcode.h
+               $(srcdir)/Include/opcode.h.new
+       $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new
 
 Python/compile.o Python/symtable.o Python/ast.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h
 
@@ -865,7 +883,8 @@ regen-opcode-targets:
        # Regenerate Python/opcode_targets.h from Lib/opcode.py
        # using Python/makeopcodetargets.py
        $(PYTHON_FOR_REGEN) $(srcdir)/Python/makeopcodetargets.py \
-               $(srcdir)/Python/opcode_targets.h
+               $(srcdir)/Python/opcode_targets.h.new
+       $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new
 
 Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h
 
@@ -892,7 +911,8 @@ regen-typeslots:
        # using Objects/typeslots.py
        $(PYTHON_FOR_REGEN) $(srcdir)/Objects/typeslots.py \
                < $(srcdir)/Include/typeslots.h \
-               $(srcdir)/Objects/typeslots.inc
+               $(srcdir)/Objects/typeslots.inc.new
+       $(UPDATE_FILE) $(srcdir)/Objects/typeslots.inc $(srcdir)/Objects/typeslots.inc.new
 
 ############################################################################
 # Header files
@@ -1081,7 +1101,7 @@ altinstall: commoninstall
                        $$ensurepip --root=$(DESTDIR)/ ; \
        fi
 
-commoninstall:  @FRAMEWORKALTINSTALLFIRST@ \
+commoninstall:  check-clean-src @FRAMEWORKALTINSTALLFIRST@ \
                altbininstall libinstall inclinstall libainstall \
                sharedinstall oldsharedinstall altmaninstall \
                @FRAMEWORKALTINSTALLLAST@
@@ -1579,10 +1599,9 @@ autoconf:
 
 # Create a tags file for vi
 tags::
-       cd $(srcdir); \
-       ctags -w Include/*.h; \
-       for i in $(SRCDIRS); do ctags -w -a $$i/*.[ch]; \
-       done; \
+       ctags -w $(srcdir)/Include/*.h
+       for i in $(SRCDIRS); do ctags -f tags -w -a $(srcdir)/$$i/*.[ch]; done
+       ctags -f tags -w -a $(srcdir)/Modules/_ctypes/*.[ch]
        LC_ALL=C sort -o tags tags
 
 # Create a tags file for GNU Emacs
@@ -1704,7 +1723,7 @@ patchcheck: @DEF_MAKE_RULE@
 Python/thread.o: @THREADHEADERS@
 
 # Declare targets that aren't real files
-.PHONY: all build_all sharedmods oldsharedmods test quicktest
+.PHONY: all build_all sharedmods check-clean-src oldsharedmods test quicktest
 .PHONY: install altinstall oldsharedinstall bininstall altbininstall
 .PHONY: maninstall libinstall inclinstall libainstall sharedinstall
 .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
index 83336eca5b9d2595bedc1f89ec67850438ac1d4a..5f21c4bce07ac9f0311441dad7cc9fb86d198e79 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -145,6 +145,7 @@ Dominic Binks
 Philippe Biondi
 Michael Birtwell
 Stuart Bishop
+Zane Bitter
 Roy Bixler
 Daniel Black
 Jonathan Black
@@ -289,6 +290,7 @@ Brad Clements
 Robbie Clemons
 Steve Clift
 Hervé Coatanhay
+Riccardo Coccioli
 Nick Coghlan
 Josh Cogliati
 Dave Cole
@@ -356,6 +358,7 @@ Vincent Delft
 Arnaud Delobelle
 Konrad Delong
 Erik Demaine
+Jeroen Demeyer
 Martin Dengler
 John Dennis
 L. Peter Deutsch
@@ -847,6 +850,7 @@ Vladimir Kushnir
 Erno Kuusela
 Ross Lagerwall
 Cameron Laird
+Loïc Lajeanne
 David Lam
 Thomas Lamb
 Valerie Lambert
index 79995215efb5bdafec027ab137e3798f409edb6b..d0a15b1d7490a4ea57cf9a469235e1487b7142d2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,454 @@
 Python News
 +++++++++++
 
+What's New in Python 3.6.4 final?
+=================================
+
+*Release date: 2017-12-18*
+
+There were no new code changes in version 3.6.4 since v3.6.4rc1.
+
+
+
+What's New in Python 3.6.4 release candidate 1?
+===============================================
+
+*Release date: 2017-12-05*
+
+Core and Builtins
+-----------------
+
+- bpo-32176: co_flags.CO_NOFREE is now always set correctly by the code
+  object constructor based on freevars and cellvars, rather than needing to
+  be set correctly by the caller. This ensures it will be cleared
+  automatically when additional cell references are injected into a modified
+  code object and function.
+
+- bpo-31949: Fixed several issues in printing tracebacks
+  (PyTraceBack_Print()).
+
+  * Setting sys.tracebacklimit to 0 or less now suppresses printing tracebacks.
+  * Setting sys.tracebacklimit to None now causes using the default limit.
+  * Setting sys.tracebacklimit to an integer larger than LONG_MAX now means using
+    the limit LONG_MAX rather than the default limit.
+  * Fixed integer overflows in the case of more than 2**31 traceback items on
+    Windows.
+  * Fixed output errors handling.
+
+- bpo-30696: Fix the interactive interpreter looping endlessly when no
+  memory.
+
+- bpo-20047: Bytearray methods partition() and rpartition() now accept only
+  bytes-like objects as separator, as documented.  In particular they now
+  raise TypeError rather of returning a bogus result when an integer is
+  passed as a separator.
+
+- bpo-31852: Fix a segmentation fault caused by a combination of the async
+  soft keyword and continuation lines.
+
+- bpo-21720: BytesWarning no longer emitted when the *fromlist* argument of
+  ``__import__()`` or the ``__all__`` attribute of the module contain bytes
+  instances.
+
+- bpo-31825: Fixed OverflowError in the 'unicode-escape' codec and in
+  codecs.escape_decode() when decode an escaped non-ascii byte.
+
+- bpo-28603: Print the full context/cause chain of exceptions on interpreter
+  exit, even if an exception in the chain is unhashable or compares equal to
+  later ones. Patch by Zane Bitter.
+
+- bpo-31786: Fix timeout rounding in the select module to round correctly
+  negative timeouts between -1.0 and 0.0. The functions now block waiting
+  for events as expected. Previously, the call was incorrectly non-blocking.
+  Patch by Pablo Galindo.
+
+- bpo-31642: Restored blocking "from package import module" by setting
+  sys.modules["package.module"] to None.
+
+- bpo-31626: Fixed a bug in debug memory allocator.  There was a write to
+  freed memory after shrinking a memory block.
+
+- bpo-31619: Fixed a ValueError when convert a string with large number of
+  underscores to integer with binary base.
+
+- bpo-31592: Fixed an assertion failure in Python parser in case of a bad
+  `unicodedata.normalize()`. Patch by Oren Milman.
+
+- bpo-31588: Raise a `TypeError` with a helpful error message when class
+  creation fails due to a metaclass with a bad ``__prepare__()`` method.
+  Patch by Oren Milman.
+
+- bpo-31566: Fix an assertion failure in `_warnings.warn()` in case of a bad
+  ``__name__`` global. Patch by Oren Milman.
+
+- bpo-31505: Fix an assertion failure in `json`, in case
+  `_json.make_encoder()` received a bad `encoder()` argument. Patch by Oren
+  Milman.
+
+- bpo-31492: Fix assertion failures in case of failing to import from a
+  module with a bad ``__name__`` attribute, and in case of failing to access
+  an attribute of such a module. Patch by Oren Milman.
+
+- bpo-31490: Fix an assertion failure in `ctypes` class definition, in case
+  the class has an attribute whose name is specified in ``_anonymous_`` but
+  not in ``_fields_``. Patch by Oren Milman.
+
+- bpo-31478: Fix an assertion failure in `_random.Random.seed()` in case the
+  argument has a bad ``__abs__()`` method. Patch by Oren Milman.
+
+- bpo-31315: Fix an assertion failure in imp.create_dynamic(), when
+  spec.name is not a string. Patch by Oren Milman.
+
+- bpo-31311: Fix a crash in the ``__setstate__()`` method of
+  `ctypes._CData`, in case of a bad ``__dict__``. Patch by Oren Milman.
+
+- bpo-31293: Fix crashes in true division and multiplication of a timedelta
+  object by a float with a bad as_integer_ratio() method. Patch by Oren
+  Milman.
+
+- bpo-31285: Fix an assertion failure in `warnings.warn_explicit`, when the
+  return value of the received loader's get_source() has a bad splitlines()
+  method. Patch by Oren Milman.
+
+- bpo-30817: `PyErr_PrintEx()` clears now the ignored exception that may be
+  raised by `_PySys_SetObjectId()`, for example when no memory.
+
+Library
+-------
+
+- bpo-28556: Two minor fixes for ``typing`` module: allow shallow copying
+  instances of generic classes, improve interaction of ``__init_subclass__``
+  with generics. Original PRs by Ivan Levkivskyi.
+
+- bpo-27240: The header folding algorithm for the new email policies has
+  been rewritten, which also fixes bpo-30788, bpo-31831, and bpo-32182.  In
+  particular, RFC2231 folding is now done correctly.
+
+- bpo-32186: io.FileIO.readall() and io.FileIO.read() now release the GIL
+  when getting the file size. Fixed hang of all threads with inaccessible
+  NFS server. Patch by Nir Soffer.
+
+- bpo-12239: Make :meth:`msilib.SummaryInformation.GetProperty` return
+  ``None`` when the value of property is ``VT_EMPTY``.  Initial patch by
+  Mark Mc Mahon.
+
+- bpo-31325: Fix wrong usage of :func:`collections.namedtuple` in the
+  :meth:`RobotFileParser.parse() <urllib.robotparser.RobotFileParser.parse>`
+  method.
+
+  Initial patch by Robin Wellner.
+
+- bpo-12382: :func:`msilib.OpenDatabase` now raises a better exception
+  message when it couldn't open or create an MSI file.  Initial patch by
+  William Tisäter.
+
+- bpo-32110: ``codecs.StreamReader.read(n)`` now returns not more than *n*
+  characters/bytes for non-negative *n*. This makes it compatible with
+  ``read()`` methods of other file-like objects.
+
+- bpo-32072: Fixed issues with binary plists:
+
+  * Fixed saving bytearrays.
+  * Identical objects will be saved only once.
+  * Equal references will be load as identical objects.
+  * Added support for saving and loading recursive data structures.
+
+- bpo-32034: Make asyncio.IncompleteReadError and LimitOverrunError
+  pickleable.
+
+- bpo-32015: Fixed the looping of asyncio in the case of reconnection the
+  socket during waiting async read/write from/to the socket.
+
+- bpo-32011: Restored support of loading marshal files with the TYPE_INT64
+  code. These files can be produced in Python 2.7.
+
+- bpo-31970: Reduce performance overhead of asyncio debug mode.
+
+- bpo-9678: Fixed determining the MAC address in the uuid module:
+
+  * Using ifconfig on NetBSD and OpenBSD.
+  * Using arp on Linux, FreeBSD, NetBSD and OpenBSD.
+
+  Based on patch by Takayuki Shimizukawa.
+
+- bpo-30057: Fix potential missed signal in signal.signal().
+
+- bpo-31933: Fix Blake2 params leaf_size and node_offset on big endian
+  platforms. Patch by Jack O'Connor.
+
+- bpo-31927: Fixed compilation of the socket module on NetBSD 8.  Fixed
+  assertion failure or reading arbitrary data when parse a AF_BLUETOOTH
+  address on NetBSD and DragonFly BSD.
+
+- bpo-27666: Fixed stack corruption in curses.box() and curses.ungetmouse()
+  when the size of types chtype or mmask_t is less than the size of C long.
+  curses.box() now accepts characters as arguments.  Based on patch by Steve
+  Fink.
+
+- bpo-31897: plistlib now catches more errors when read binary plists and
+  raises InvalidFileException instead of unexpected exceptions.
+
+- bpo-25720: Fix the method for checking pad state of curses WINDOW. Patch
+  by Masayuki Yamamoto.
+
+- bpo-31893: Fixed the layout of the kqueue_event structure on OpenBSD and
+  NetBSD. Fixed the comparison of the kqueue_event objects.
+
+- bpo-31891: Fixed building the curses module on NetBSD.
+
+- bpo-28416: Instances of pickle.Pickler subclass with the persistent_id()
+  method and pickle.Unpickler subclass with the persistent_load() method no
+  longer create reference cycles.
+
+- bpo-28326: Fix multiprocessing.Process when stdout and/or stderr is closed
+  or None.
+
+- bpo-31457: If nested log adapters are used, the inner ``process()``
+  methods are no longer omitted.
+
+- bpo-31457: The ``manager`` property on LoggerAdapter objects is now
+  properly settable.
+
+- bpo-31806: Fix timeout rounding in time.sleep(), threading.Lock.acquire()
+  and socket.socket.settimeout() to round correctly negative timeouts
+  between -1.0 and 0.0. The functions now block waiting for events as
+  expected. Previously, the call was incorrectly non-blocking. Patch by
+  Pablo Galindo.
+
+- bpo-28603: traceback: Fix a TypeError that occurred during printing of
+  exception tracebacks when either the current exception or an exception in
+  its context/cause chain is unhashable. Patch by Zane Bitter.
+
+- bpo-30058: Fixed buffer overflow in select.kqueue.control().
+
+- bpo-31770: Prevent a crash when calling the ``__init__()`` method of a
+  ``sqlite3.Cursor`` object more than once. Patch by Oren Milman.
+
+- bpo-31672: ``idpattern`` in ``string.Template`` matched some non-ASCII
+  characters. Now it uses ``-i`` regular expression local flag to avoid non-
+  ASCII characters.
+
+- bpo-31764: Prevent a crash in ``sqlite3.Cursor.close()`` in case the
+  ``Cursor`` object is uninitialized. Patch by Oren Milman.
+
+- bpo-31752: Fix possible crash in timedelta constructor called with custom
+  integers.
+
+- bpo-31701: On Windows, faulthandler.enable() now ignores MSC and COM
+  exceptions.
+
+- bpo-31728: Prevent crashes in `_elementtree` due to unsafe cleanup of
+  `Element.text` and `Element.tail`. Patch by Oren Milman.
+
+- bpo-31620: an empty asyncio.Queue now doesn't leak memory when queue.get
+  pollers timeout
+
+- bpo-31632: Fix method set_protocol() of class _SSLProtocolTransport in
+  asyncio module. This method was previously modifying a wrong reference to
+  the protocol.
+
+- bpo-31675: Fixed memory leaks in Tkinter's methods splitlist() and split()
+  when pass a string larger than 2 GiB.
+
+- bpo-31673: Fixed typo in the name of Tkinter's method adderrorinfo().
+
+- bpo-30806: Fix the string representation of a netrc object.
+
+- bpo-15037: Added a workaround for getkey() in curses for ncurses 5.7 and
+  earlier.
+
+- bpo-25351: Avoid venv activate failures with undefined variables
+
+- bpo-25532: inspect.unwrap() will now only try to unwrap an object
+  sys.getrecursionlimit() times, to protect against objects which create a
+  new object on every attribute access.
+
+- bpo-30347: Stop crashes when concurrently iterate over itertools.groupby()
+  iterators.
+
+- bpo-31516: ``threading.current_thread()`` should not return a dummy thread
+  at shutdown.
+
+- bpo-31351: python -m ensurepip now exits with non-zero exit code if pip
+  bootstrapping has failed.
+
+- bpo-31482: ``random.seed()`` now works with bytes in version=1
+
+- bpo-31334: Fix ``poll.poll([timeout])`` in the ``select`` module for
+  arbitrary negative timeouts on all OSes where it can only be a non-
+  negative integer or -1. Patch by Riccardo Coccioli.
+
+- bpo-31310: multiprocessing's semaphore tracker should be launched again if
+  crashed.
+
+- bpo-31308: Make multiprocessing's forkserver process immune to Ctrl-C and
+  other user interruptions. If it crashes, restart it when necessary.
+
+Documentation
+-------------
+
+- bpo-32105: Added asyncio.BaseEventLoop.connect_accepted_socket
+  versionaddded marker.
+
+- bpo-31537: Fix incorrect usage of ``get_history_length`` in readline
+  documentation example code. Patch by Brad Smith.
+
+- bpo-30085: The operator functions without double underscores are preferred
+  for clarity. The one with underscores are only kept for back-
+  compatibility.
+
+Tests
+-----
+
+- bpo-31380: Skip test_httpservers test_undecodable_file on macOS: fails on
+  APFS.
+
+- bpo-31705: Skip test_socket.test_sha256() on Linux kernel older than 4.5.
+  The test fails with ENOKEY on kernel 3.10 (on ppc64le). A fix was merged
+  into the kernel 4.5.
+
+- bpo-31174: Fix test_tools.test_unparse: DirectoryTestCase now stores the
+  names sample to always test the same files. It prevents false alarms when
+  hunting reference leaks.
+
+- bpo-30695: Add the `set_nomemory(start, stop)` and `remove_mem_hooks()`
+  functions to the _testcapi module.
+
+Build
+-----
+
+- bpo-32059: ``detect_modules()`` in ``setup.py`` now also searches the
+  sysroot paths when cross-compiling.
+
+- bpo-31957: Fixes Windows SDK version detection when building for Windows.
+
+- bpo-31609: Fixes quotes in PCbuild/clean.bat
+
+- bpo-31934: Abort the build when building out of a not clean source tree.
+
+- bpo-31926: Fixed Argument Clinic sometimes causing compilation errors when
+  there was more than one function and/or method in a .c file with the same
+  name.
+
+- bpo-28791: Update Windows builds to use SQLite 3.21.0.
+
+- bpo-28791: Update OS X installer to use SQLite 3.21.0.
+
+- bpo-22140: Prevent double substitution of prefix in python-config.sh.
+
+- bpo-31536: Avoid wholesale rebuild after `make regen-all` if nothing
+  changed.
+
+Windows
+-------
+
+- bpo-1102: Return ``None`` when ``View.Fetch()`` returns
+  ``ERROR_NO_MORE_ITEMS`` instead of raising ``MSIError``.
+
+  Initial patch by Anthony Tuininga.
+
+- bpo-31944: Fixes Modify button in Apps and Features dialog.
+
+macOS
+-----
+
+- bpo-31392: Update macOS installer to use OpenSSL 1.0.2m
+
+IDLE
+----
+
+- bpo-32207: Improve tk event exception tracebacks in IDLE. When tk event
+  handling is driven by IDLE's run loop, a confusing and distracting
+  queue.EMPTY traceback context is no longer added to tk event exception
+  tracebacks.  The traceback is now the same as when event handling is
+  driven by user code.  Patch based on a suggestion by Serhiy Storchaka.
+
+- bpo-32164: Delete unused file idlelib/tabbedpages.py. Use of TabbedPageSet
+  in configdialog was replaced by ttk.Notebook.
+
+- bpo-32100: IDLE: Fix old and new bugs in pathbrowser; improve tests. Patch
+  mostly by Cheryl Sabella.
+
+- bpo-31858: IDLE -- Restrict shell prompt manipulaton to the shell. Editor
+  and output windows only see an empty last prompt line.  This simplifies
+  the code and fixes a minor bug when newline is inserted. Sys.ps1, if
+  present, is read on Shell start-up, but is not set or changed.
+
+- bpo-31860: The font sample in the IDLE configuration dialog is now
+  editable. Changes persist while IDLE remains open
+
+- bpo-31836: Test_code_module now passes if run after test_idle, which sets
+  ps1.
+
+  The code module uses sys.ps1 if present or sets it to '>>> ' if not.
+  Test_code_module now properly tests both behaviors.  Ditto for ps2.
+
+- bpo-28603: Fix a TypeError that caused a shell restart when printing a
+  traceback that includes an exception that is unhashable. Patch by Zane
+  Bitter.
+
+- bpo-13802: Use non-Latin characters in the IDLE's Font settings sample.
+  Even if one selects a font that defines a limited subset of the unicode
+  Basic Multilingual Plane, tcl/tk will use other fonts that define a
+  character. The expanded example give users of non-Latin characters a
+  better idea of what they might see in IDLE's shell and editors. To make
+  room for the expanded sample, frames on the Font tab are re-arranged. The
+  Font/Tabs help explains a bit about the additions.
+
+- bpo-31460: Simplify the API of IDLE's Module Browser.
+
+  Passing a widget instead of an flist with a root widget opens the option
+  of creating a browser frame that is only part of a window.  Passing a full
+  file name instead of pieces assumed to come from a .py file opens the
+  possibility of browsing python files that do not end in .py.
+
+- bpo-31649: IDLE - Make _htest, _utest parameters keyword only.
+
+- bpo-31559: Remove test order dependence in idle_test.test_browser.
+
+- bpo-31459: Rename IDLE's module browser from Class Browser to Module
+  Browser. The original module-level class and method browser became a
+  module browser, with the addition of module-level functions, years ago.
+  Nested classes and functions were added yesterday.  For back-
+  compatibility, the virtual event <<open-class-browser>>, which appears on
+  the Keys tab of the Settings dialog, is not changed. Patch by Cheryl
+  Sabella.
+
+- bpo-31500: Default fonts now are scaled on HiDPI displays.
+
+- bpo-1612262: IDLE module browser now shows nested classes and functions.
+  Original patches for code and tests by Guilherme Polo and Cheryl Sabella,
+  respectively.
+
+Tools/Demos
+-----------
+
+- bpo-30722: Make redemo work with Python 3.6 and newer versions.
+
+  In Python 3.6, flags like re.DOTALL became members of an enum.IntFlag so
+  usages like ``getattr(re, 'DOTALL')`` are invalid.
+
+  Also, remove the ``LOCALE`` option since it doesn't work with string
+  patterns in Python 3.
+
+  Patch by Christoph Sarnowski.
+
+C API
+-----
+
+- bpo-20891: Fix PyGILState_Ensure(). When PyGILState_Ensure() is called in
+  a non-Python thread before PyEval_InitThreads(), only call
+  PyEval_InitThreads() after calling PyThreadState_New() to fix a crash.
+
+- bpo-31532: Fix memory corruption due to allocator mix in getpath.c between
+  Py_GetPath() and Py_SetPath()
+
+- bpo-30697: The `PyExc_RecursionErrorInst` singleton is removed and
+  `PyErr_NormalizeException()` does not use it anymore. This singleton is
+  persistent and its members being never cleared may cause a segfault during
+  finalization of the interpreter. See also issue #22898.
+
+
 What's New in Python 3.6.3 final?
 =================================
 
@@ -5282,12 +5730,11 @@ Library
   correctly.  Initial patch by ingrid.
 
 - A new version of typing.py provides several new classes and features:
-  @overload outside stubs, Reversible, DefaultDict, Text, ContextManager,
-  Type[], NewType(), TYPE_CHECKING, and numerous bug fixes (note that some
-  of the new features are not yet implemented in mypy or other static
-  analyzers). Also classes for PEP 492 (Awaitable, AsyncIterable,
-  AsyncIterator) have been added (in fact they made it into 3.5.1 but were
-  never mentioned).
+  @overload outside stubs, DefaultDict, Text, ContextManager, Type[],
+  NewType(), TYPE_CHECKING, and numerous bug fixes (note that some of the
+  new features are not yet implemented in mypy or other static analyzers).
+  Also classes for PEP 492 (Awaitable, AsyncIterable, AsyncIterator) have
+  been added (in fact they made it into 3.5.1 but were never mentioned).
 
 - bpo-25738: Stop http.server.BaseHTTPRequestHandler.send_error() from
   sending a message body for 205 Reset Content.  Also, don't send Content
index 30c6927871001dafc368e31e8c70717b5d9a979b..d1d3275fa2758d90963c4c85c9dd5ab95f7a16bc 100644 (file)
@@ -24,17 +24,18 @@ installed_prefix ()
     echo $RESULT
 }
 
-prefix_build="@prefix@"
 prefix_real=$(installed_prefix "$0")
 
 # Use sed to fix paths from their built-to locations to their installed-to
-# locations.
-prefix=$(echo "$prefix_build" | sed "s#$prefix_build#$prefix_real#")
-exec_prefix_build="@exec_prefix@"
-exec_prefix=$(echo "$exec_prefix_build" | sed "s#$exec_prefix_build#$prefix_real#")
-includedir=$(echo "@includedir@" | sed "s#$prefix_build#$prefix_real#")
-libdir=$(echo "@libdir@" | sed "s#$prefix_build#$prefix_real#")
-CFLAGS=$(echo "@CFLAGS@" | sed "s#$prefix_build#$prefix_real#")
+# locations. Keep prefix & exec_prefix using their original values in case
+# they are referenced in other configure variables, to prevent double
+# substitution, issue #22140.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+exec_prefix_real=${prefix_real}
+includedir=$(echo "@includedir@" | sed "s#$prefix#$prefix_real#")
+libdir=$(echo "@libdir@" | sed "s#$prefix#$prefix_real#")
+CFLAGS=$(echo "@CFLAGS@" | sed "s#$prefix#$prefix_real#")
 VERSION="@VERSION@"
 LIBM="@LIBM@"
 LIBC="@LIBC@"
@@ -47,8 +48,8 @@ LINKFORSHARED="@LINKFORSHARED@"
 OPT="@OPT@"
 PY_ENABLE_SHARED="@PY_ENABLE_SHARED@"
 LDVERSION="@LDVERSION@"
-LIBDEST=${prefix}/lib/python${VERSION}
-LIBPL=$(echo "@LIBPL@" | sed "s#$prefix_build#$prefix_real#")
+LIBDEST=${prefix_real}/lib/python${VERSION}
+LIBPL=$(echo "@LIBPL@" | sed "s#$prefix#$prefix_real#")
 SO="@EXT_SUFFIX@"
 PYTHONFRAMEWORK="@PYTHONFRAMEWORK@"
 INCDIR="-I$includedir/python${VERSION}${ABIFLAGS}"
@@ -73,10 +74,10 @@ for ARG in "$@"
 do
     case "$ARG" in
         --prefix)
-            echo "$prefix"
+            echo "$prefix_real"
         ;;
         --exec-prefix)
-            echo "$exec_prefix"
+            echo "$exec_prefix_real"
         ;;
         --includes)
             echo "$INCDIR $PLATINCDIR"
index 58b502bb349b820394e8caaa849faac558ef5d69..09b200ebe1726c33faea57795ce60c293b66401b 100644 (file)
@@ -166,7 +166,8 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
             goto error;
         }
     }
-    self->param.leaf_length = (unsigned int)leaf_size;
+    // NB: Simple assignment here would be incorrect on big endian platforms.
+    store32(&(self->param.leaf_length), leaf_size);
 
     if (node_offset_obj != NULL) {
         node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
@@ -182,7 +183,8 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
      }
     store48(&(self->param.node_offset), node_offset);
 #else
-    self->param.node_offset = node_offset;
+    // NB: Simple assignment here would be incorrect on big endian platforms.
+    store64(&(self->param.node_offset), node_offset);
 #endif
 
     if (node_depth < 0 || node_depth > 255) {
index 11d2e02251b8bd4f2ad8d0612845d58a7baed22c..735b6f08deb6f8bc8bc04a8c4ec854d47b100483 100644 (file)
@@ -166,7 +166,8 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
             goto error;
         }
     }
-    self->param.leaf_length = (unsigned int)leaf_size;
+    // NB: Simple assignment here would be incorrect on big endian platforms.
+    store32(&(self->param.leaf_length), leaf_size);
 
     if (node_offset_obj != NULL) {
         node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
@@ -182,7 +183,8 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
      }
     store48(&(self->param.node_offset), node_offset);
 #else
-    self->param.node_offset = node_offset;
+    // NB: Simple assignment here would be incorrect on big endian platforms.
+    store64(&(self->param.node_offset), node_offset);
 #endif
 
     if (node_depth < 0 || node_depth > 255) {
index a3b5d65e2d39b65ca1ae237d430cffbd04310d35..2797722b37b15e4e769e92b582c1baeea5e596ef 100644 (file)
@@ -18,8 +18,9 @@
 
 #define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */
 
+#if 0
 /* Basic VPPERM emulation, for testing purposes */
-/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
+static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
 {
    const __m128i sixteen = _mm_set1_epi8(16);
    const __m128i t0 = _mm_shuffle_epi8(src1, sel);
@@ -27,7 +28,8 @@
    const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen),
                                      _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */
    return _mm_blendv_epi8(t0, s1, mask);
-}*/
+}
+#endif
 
 #define LOAD_MSG_0_1(buf) \
 buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
index e7a24f3f058ce062c2665d5d1c233a0ed888ca75..af20d6edd9185915b4ddb089eef0b1bf2aefb5c0 100644 (file)
@@ -2276,7 +2276,9 @@ _count_elements(PyObject *self, PyObject *args)
     dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
 
     if (mapping_get != NULL && mapping_get == dict_get &&
-        mapping_setitem != NULL && mapping_setitem == dict_setitem) {
+        mapping_setitem != NULL && mapping_setitem == dict_setitem &&
+        PyDict_Check(mapping))
+    {
         while (1) {
             /* Fast path advantages:
                    1. Eliminate double hashing
index 1ced6305d3d93f5a79464065b75ab8f3ff58ba14..258e805870b11db29bbf27c66e4e39daf43a9601 100644 (file)
@@ -990,6 +990,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     if (proto) {
         StgDictObject *itemdict = PyType_stgdict(proto);
         const char *current_format;
+        /* PyCPointerType_SetProto has verified proto has a stgdict. */
         assert(itemdict);
         /* If itemdict->format is NULL, then this is a pointer to an
            incomplete type.  We create a generic format string
@@ -1036,7 +1037,11 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
     StgDictObject *dict;
 
     dict = PyType_stgdict((PyObject *)self);
-    assert(dict);
+    if (!dict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "abstract class");
+        return NULL;
+    }
 
     if (-1 == PyCPointerType_SetProto(dict, type))
         return NULL;
@@ -1062,7 +1067,11 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
     }
 
     typedict = PyType_stgdict(type);
-    assert(typedict); /* Cannot be NULL for pointer types */
+    if (!typedict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "abstract class");
+        return NULL;
+    }
 
     /* If we expect POINTER(<type>), but receive a <type> instance, accept
        it by calling byref(<type>).
@@ -2127,7 +2136,11 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
     }
 
     dict = PyType_stgdict(type);
-    assert(dict);
+    if (!dict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "abstract class");
+        return NULL;
+    }
 
     /* I think we can rely on this being a one-character string */
     fmt = PyUnicode_AsUTF8(dict->proto);
@@ -2663,6 +2676,16 @@ PyCData_setstate(PyObject *myself, PyObject *args)
         len = self->b_size;
     memmove(self->b_ptr, data, len);
     mydict = PyObject_GetAttrString(myself, "__dict__");
+    if (mydict == NULL) {
+        return NULL;
+    }
+    if (!PyDict_Check(mydict)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.200s.__dict__ must be a dictionary, not %.200s",
+                     Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name);
+        Py_DECREF(mydict);
+        return NULL;
+    }
     res = PyDict_Update(mydict, dict);
     Py_DECREF(mydict);
     if (res == -1)
@@ -3221,7 +3244,11 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
     PyObject *argtypes;
 
     dict = PyType_stgdict((PyObject *)type);
-    assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
+    if (!dict) {
+        PyErr_SetString(PyExc_TypeError,
+                        "abstract class");
+        return 0;
+    }
     argtypes = dict->argtypes;
 
     if (paramflags == NULL || dict->argtypes == NULL)
@@ -4852,7 +4879,7 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
     }
 
     stgdict = PyObject_stgdict((PyObject *)self);
-    assert(stgdict); /* Cannot be NULL fr pointer instances */
+    assert(stgdict); /* Cannot be NULL for pointer instances */
 
     proto = stgdict->proto;
     assert(proto);
@@ -4880,7 +4907,7 @@ Pointer_get_contents(CDataObject *self, void *closure)
     }
 
     stgdict = PyObject_stgdict((PyObject *)self);
-    assert(stgdict); /* Cannot be NULL fr pointer instances */
+    assert(stgdict); /* Cannot be NULL for pointer instances */
     return PyCData_FromBaseObj(stgdict->proto,
                              (PyObject *)self, 0,
                              *(void **)self->b_ptr);
@@ -4899,7 +4926,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
         return -1;
     }
     stgdict = PyObject_stgdict((PyObject *)self);
-    assert(stgdict); /* Cannot be NULL fr pointer instances */
+    assert(stgdict); /* Cannot be NULL for pointer instances */
     assert(stgdict->proto);
     if (!CDataObject_Check(value)) {
         int res = PyObject_IsInstance(value, stgdict->proto);
index 113a815db151b258da3924aedfd93617a34553a6..e39065fa9393b029efe2936601be71b1e0ac4d5e 100644 (file)
@@ -205,7 +205,11 @@ PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
 {
     CDataObject *dst;
     char *ptr;
-    assert(CDataObject_Check(inst));
+    if (!CDataObject_Check(inst)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "not a ctype instance");
+        return -1;
+    }
     dst = (CDataObject *)inst;
     ptr = dst->b_ptr + self->offset;
     if (value == NULL) {
@@ -225,7 +229,11 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
         Py_INCREF(self);
         return (PyObject *)self;
     }
-    assert(CDataObject_Check(inst));
+    if (!CDataObject_Check(inst)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "not a ctype instance");
+        return NULL;
+    }
     src = (CDataObject *)inst;
     return PyCData_get(self->proto, self->getfunc, inst,
                      self->index, self->size, src->b_ptr + self->offset);
index 716d1e9e8eb5df76d10078afff02072e9ecd71db..8278b2fbefbfc0110ef3d679c65421dbb24739e6 100644 (file)
@@ -282,7 +282,15 @@ MakeAnonFields(PyObject *type)
             Py_DECREF(anon_names);
             return -1;
         }
-        assert(Py_TYPE(descr) == &PyCField_Type);
+        if (Py_TYPE(descr) != &PyCField_Type) {
+            PyErr_Format(PyExc_AttributeError,
+                         "'%U' is specified in _anonymous_ but not in "
+                         "_fields_",
+                         fname);
+            Py_DECREF(anon_names);
+            Py_DECREF(descr);
+            return -1;
+        }
         descr->anonymous = 1;
 
         /* descr is in the field descriptor. */
index 7a7095118a0bafd8fe244deafa533a778f344291..9a691dbe714e807f53d3ee0694457a7f982ccebc 100644 (file)
@@ -112,13 +112,13 @@ char *PyCursesVersion = "2.2";
 #define CURSES_MODULE
 #include "py_curses.h"
 
-/*  These prototypes are in <term.h>, but including this header
-    #defines many common symbols (such as "lines") which breaks the
-    curses module in other ways.  So the code will just specify
-    explicit prototypes here. */
-extern int setupterm(char *,int,int *);
-#ifdef __sgi
+#if defined(HAVE_TERM_H) || defined(__sgi)
+/* For termname, longname, putp, tigetflag, tigetnum, tigetstr, tparm
+   which are not declared in SysV curses and for setupterm. */
 #include <term.h>
+/* Including <term.h> #defines many common symbols. */
+#undef lines
+#undef columns
 #endif
 
 #ifdef HAVE_LANGINFO_H
@@ -484,7 +484,9 @@ Window_NoArgNoReturnVoidFunction(wclrtobot)
 Window_NoArgNoReturnVoidFunction(wclear)
 
 Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
+#ifdef HAVE_CURSES_IMMEDOK
 Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
+#endif
 Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
 
 Window_NoArg2TupleReturnFunction(getyx, int, "ii")
@@ -494,21 +496,15 @@ Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
 
 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
-#if defined(__NetBSD__)
-Window_OneArgNoReturnVoidFunction(keypad, int, "i;True(1) or False(0)")
-#else
 Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
-#endif
 Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
-#if defined(__NetBSD__)
-Window_OneArgNoReturnVoidFunction(nodelay, int, "i;True(1) or False(0)")
-#else
 Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
-#endif
 Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
 Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
 Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
+#ifdef HAVE_CURSES_SYNCOK
 Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
+#endif
 
 Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
 Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
@@ -916,12 +912,19 @@ PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
 static PyObject *
 PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
 {
+    PyObject *temp1, *temp2;
     chtype ch1=0,ch2=0;
     switch(PyTuple_Size(args)){
     case 0: break;
     default:
-        if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
+        if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
             return NULL;
+        if (!PyCurses_ConvertToChtype(self, temp1, &ch1)) {
+            return NULL;
+        }
+        if (!PyCurses_ConvertToChtype(self, temp2, &ch2)) {
+            return NULL;
+        }
     }
     box(self->win,ch1,ch2);
     Py_INCREF(Py_None);
@@ -940,8 +943,14 @@ int py_mvwdelch(WINDOW *w, int y, int x)
 }
 #endif
 
-/* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
+#if defined(HAVE_CURSES_IS_PAD)
+#define py_is_pad(win)      is_pad(win)
+#elif defined(WINDOW_HAS_FLAGS)
+#define py_is_pad(win)      ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
+#endif
 
+/* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
+#ifdef HAVE_CURSES_WCHGAT
 static PyObject *
 PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
 {
@@ -994,7 +1003,7 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
     }
     return PyCursesCheckERR(rtn, "chgat");
 }
-
+#endif
 
 static PyObject *
 PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args)
@@ -1079,10 +1088,11 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
     if (!PyCurses_ConvertToChtype(self, temp, &ch))
         return NULL;
 
-#ifdef WINDOW_HAS_FLAGS
-    if (self->win->_flags & _ISPAD)
+#ifdef py_is_pad
+    if (py_is_pad(self->win)) {
         return PyCursesCheckERR(pechochar(self->win, ch | attr),
                                 "echochar");
+    }
     else
 #endif
         return PyCursesCheckERR(wechochar(self->win, ch | attr),
@@ -1162,15 +1172,18 @@ PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
         if (!PyErr_Occurred())
             PyErr_SetString(PyCursesError, "no input");
         return NULL;
-    } else if (rtn<=255) {
-        return Py_BuildValue("C", rtn);
-    } else {
-        const char *knp;
-#if defined(__NetBSD__)
-        knp = unctrl(rtn);
-#else
-        knp = keyname(rtn);
+    } else if (rtn <= 255) {
+#ifdef NCURSES_VERSION_MAJOR
+#if NCURSES_VERSION_MAJOR*100+NCURSES_VERSION_MINOR <= 507
+        /* Work around a bug in ncurses 5.7 and earlier */
+        if (rtn < 0) {
+            rtn += 256;
+        }
+#endif
 #endif
+        return PyUnicode_FromOrdinal(rtn);
+    } else {
+        const char *knp = keyname(rtn);
         return PyUnicode_FromString((knp == NULL) ? "" : knp);
     }
 }
@@ -1616,10 +1629,10 @@ PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
     int rtn;
 
-#ifndef WINDOW_HAS_FLAGS
+#ifndef py_is_pad
     if (0)
 #else
-        if (self->win->_flags & _ISPAD)
+        if (py_is_pad(self->win))
 #endif
         {
             switch(PyTuple_Size(args)) {
@@ -1791,10 +1804,10 @@ PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
     int rtn;
 
-#ifndef WINDOW_HAS_FLAGS
+#ifndef py_is_pad
     if (0)
 #else
-        if (self->win->_flags & _ISPAD)
+        if (py_is_pad(self->win))
 #endif
         {
             switch(PyTuple_Size(args)) {
@@ -1860,9 +1873,10 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
     }
 
     /* printf("Subwin: %i %i %i %i   \n", nlines, ncols, begin_y, begin_x); */
-#ifdef WINDOW_HAS_FLAGS
-    if (self->win->_flags & _ISPAD)
+#ifdef py_is_pad
+    if (py_is_pad(self->win)) {
         win = subpad(self->win, nlines, ncols, begin_y, begin_x);
+    }
     else
 #endif
         win = subwin(self->win, nlines, ncols, begin_y, begin_x);
@@ -2002,7 +2016,9 @@ static PyMethodDef PyCursesWindow_Methods[] = {
     {"attron",          (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS},
     {"attrset",         (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS},
     {"bkgd",            (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS},
+#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},
@@ -2033,7 +2049,9 @@ static PyMethodDef PyCursesWindow_Methods[] = {
     {"hline",           (PyCFunction)PyCursesWindow_Hline, METH_VARARGS},
     {"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},
     {"insdelln",        (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
@@ -2069,7 +2087,9 @@ static PyMethodDef PyCursesWindow_Methods[] = {
     {"subpad",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
     {"subwin",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
     {"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},
@@ -2161,6 +2181,7 @@ NoArgTrueFalseFunction(isendwin)
 NoArgNoReturnVoidFunction(flushinp)
 NoArgNoReturnVoidFunction(noqiflush)
 
+#ifdef HAVE_CURSES_FILTER
 static PyObject *
 PyCurses_filter(PyObject *self)
 {
@@ -2170,6 +2191,7 @@ PyCurses_filter(PyObject *self)
     Py_INCREF(Py_None);
     return Py_None;
 }
+#endif
 
 static PyObject *
 PyCurses_Color_Content(PyObject *self, PyObject *args)
@@ -2241,6 +2263,7 @@ PyCurses_EraseChar(PyObject *self)
     return PyBytes_FromStringAndSize(&ch, 1);
 }
 
+#ifdef getsyx
 static PyObject *
 PyCurses_getsyx(PyObject *self)
 {
@@ -2253,6 +2276,7 @@ PyCurses_getsyx(PyObject *self)
 
     return Py_BuildValue("(ii)", y, x);
 }
+#endif
 
 #ifdef NCURSES_MOUSE_VERSION
 static PyObject *
@@ -2268,24 +2292,30 @@ PyCurses_GetMouse(PyObject *self)
         PyErr_SetString(PyCursesError, "getmouse() returned ERR");
         return NULL;
     }
-    return Py_BuildValue("(hiiil)",
+    return Py_BuildValue("(hiiik)",
                          (short)event.id,
-                         event.x, event.y, event.z,
-                         (long) event.bstate);
+                         (int)event.x, (int)event.y, (int)event.z,
+                         (unsigned long) event.bstate);
 }
 
 static PyObject *
 PyCurses_UngetMouse(PyObject *self, PyObject *args)
 {
     MEVENT event;
+    short id;
+    int x, y, z;
+    unsigned long bstate;
 
     PyCursesInitialised;
-    if (!PyArg_ParseTuple(args, "hiiil",
-                          &event.id,
-                          &event.x, &event.y, &event.z,
-                          (int *) &event.bstate))
+    if (!PyArg_ParseTuple(args, "hiiik",
+                          &id, &x, &y, &z, &bstate))
         return NULL;
 
+    event.id = id;
+    event.x = x;
+    event.y = y;
+    event.z = z;
+    event.bstate = bstate;
     return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
 }
 #endif
@@ -2363,9 +2393,9 @@ PyCurses_HalfDelay(PyObject *self, PyObject *args)
     return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
 }
 
-#ifndef STRICT_SYSV_CURSES
-/* No has_key! */
-static PyObject * PyCurses_has_key(PyObject *self, PyObject *args)
+#ifdef HAVE_CURSES_HAS_KEY
+static PyObject *
+PyCurses_has_key(PyObject *self, PyObject *args)
 {
     int ch;
 
@@ -2380,7 +2410,7 @@ static PyObject * PyCurses_has_key(PyObject *self, PyObject *args)
     Py_INCREF(Py_True);
     return Py_True;
 }
-#endif /* STRICT_SYSV_CURSES */
+#endif
 
 static PyObject *
 PyCurses_Init_Color(PyObject *self, PyObject *args)
@@ -2621,7 +2651,6 @@ PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
 }
 #endif /* HAVE_CURSES_IS_TERM_RESIZED */
 
-#if !defined(__NetBSD__)
 static PyObject *
 PyCurses_KeyName(PyObject *self, PyObject *args)
 {
@@ -2640,7 +2669,6 @@ PyCurses_KeyName(PyObject *self, PyObject *args)
 
     return PyBytes_FromString((knp == NULL) ? "" : knp);
 }
-#endif
 
 static PyObject *
 PyCurses_KillChar(PyObject *self)
@@ -2686,14 +2714,15 @@ PyCurses_MouseInterval(PyObject *self, PyObject *args)
 static PyObject *
 PyCurses_MouseMask(PyObject *self, PyObject *args)
 {
-    int newmask;
+    unsigned long newmask;
     mmask_t oldmask, availmask;
 
     PyCursesInitialised;
-    if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
+    if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
         return NULL;
-    availmask = mousemask(newmask, &oldmask);
-    return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
+    availmask = mousemask((mmask_t)newmask, &oldmask);
+    return Py_BuildValue("(kk)",
+                         (unsigned long)availmask, (unsigned long)oldmask);
 }
 #endif
 
@@ -2947,6 +2976,7 @@ PyCurses_Resize_Term(PyObject *self, PyObject *args)
 }
 #endif /* HAVE_CURSES_RESIZE_TERM */
 
+#ifdef getsyx
 static PyObject *
 PyCurses_setsyx(PyObject *self, PyObject *args)
 {
@@ -2966,6 +2996,7 @@ PyCurses_setsyx(PyObject *self, PyObject *args)
     Py_INCREF(Py_None);
     return Py_None;
 }
+#endif
 
 static PyObject *
 PyCurses_Start_Color(PyObject *self)
@@ -3064,6 +3095,7 @@ PyCurses_tparm(PyObject *self, PyObject *args)
     return PyBytes_FromString(result);
 }
 
+#ifdef HAVE_CURSES_TYPEAHEAD
 static PyObject *
 PyCurses_TypeAhead(PyObject *self, PyObject *args)
 {
@@ -3075,6 +3107,7 @@ PyCurses_TypeAhead(PyObject *self, PyObject *args)
 
     return PyCursesCheckERR(typeahead( fd ), "typeahead");
 }
+#endif
 
 static PyObject *
 PyCurses_UnCtrl(PyObject *self, PyObject *args)
@@ -3174,6 +3207,7 @@ PyCurses_Unget_Wch(PyObject *self, PyObject *args)
 }
 #endif
 
+#ifdef HAVE_CURSES_TYPEAHEAD
 static PyObject *
 PyCurses_Use_Env(PyObject *self, PyObject *args)
 {
@@ -3192,6 +3226,7 @@ PyCurses_Use_Env(PyObject *self, PyObject *args)
     Py_INCREF(Py_None);
     return Py_None;
 }
+#endif
 
 #ifndef STRICT_SYSV_CURSES
 static PyObject *
@@ -3230,19 +3265,23 @@ static PyMethodDef PyCurses_methods[] = {
     {"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},
-#ifndef STRICT_SYSV_CURSES
+#ifdef HAVE_CURSES_HAS_KEY
     {"has_key",             (PyCFunction)PyCurses_has_key, METH_VARARGS},
 #endif
     {"halfdelay",           (PyCFunction)PyCurses_HalfDelay, METH_VARARGS},
@@ -3254,9 +3293,7 @@ static PyMethodDef PyCurses_methods[] = {
 #ifdef HAVE_CURSES_IS_TERM_RESIZED
     {"is_term_resized",     (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS},
 #endif
-#if !defined(__NetBSD__)
     {"keyname",             (PyCFunction)PyCurses_KeyName, METH_VARARGS},
-#endif
     {"killchar",            (PyCFunction)PyCurses_KillChar, METH_NOARGS},
     {"longname",            (PyCFunction)PyCurses_longname, METH_NOARGS},
     {"meta",                (PyCFunction)PyCurses_Meta, METH_VARARGS},
@@ -3288,7 +3325,9 @@ static PyMethodDef PyCurses_methods[] = {
     {"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},
@@ -3298,7 +3337,9 @@ static PyMethodDef PyCurses_methods[] = {
     {"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)
@@ -3307,7 +3348,9 @@ static PyMethodDef PyCurses_methods[] = {
 #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
@@ -3385,9 +3428,7 @@ PyInit__curses(void)
     SetDictInt("A_DIM",                 A_DIM);
     SetDictInt("A_BOLD",                A_BOLD);
     SetDictInt("A_ALTCHARSET",          A_ALTCHARSET);
-#if !defined(__NetBSD__)
     SetDictInt("A_INVIS",           A_INVIS);
-#endif
     SetDictInt("A_PROTECT",         A_PROTECT);
     SetDictInt("A_CHARTEXT",        A_CHARTEXT);
     SetDictInt("A_COLOR",           A_COLOR);
@@ -3459,7 +3500,6 @@ PyInit__curses(void)
         int key;
         char *key_n;
         char *key_n2;
-#if !defined(__NetBSD__)
         for (key=KEY_MIN;key < KEY_MAX; key++) {
             key_n = (char *)keyname(key);
             if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
@@ -3487,7 +3527,6 @@ PyInit__curses(void)
             if (key_n2 != key_n)
                 PyMem_Free(key_n2);
         }
-#endif
         SetDictInt("KEY_MIN", KEY_MIN);
         SetDictInt("KEY_MAX", KEY_MAX);
     }
index c2ad9a203e965274de43cb0941889a18ed4bdd09..fe92b93cb4e82e08b40e9786cb42fc877ea4e6b9 100644 (file)
@@ -1533,6 +1533,7 @@ delta_to_microseconds(PyDateTime_Delta *self)
     if (x2 == NULL)
         goto Done;
     result = PyNumber_Add(x1, x2);
+    assert(result == NULL || PyLong_CheckExact(result));
 
 Done:
     Py_XDECREF(x1);
@@ -1555,6 +1556,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
     PyObject *num = NULL;
     PyObject *result = NULL;
 
+    assert(PyLong_CheckExact(pyus));
     tuple = PyNumber_Divmod(pyus, us_per_second);
     if (tuple == NULL)
         goto Done;
@@ -1646,6 +1648,33 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
     return result;
 }
 
+static PyObject *
+get_float_as_integer_ratio(PyObject *floatobj)
+{
+    PyObject *ratio;
+
+    assert(floatobj && PyFloat_Check(floatobj));
+    ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
+    if (ratio == NULL) {
+        return NULL;
+    }
+    if (!PyTuple_Check(ratio)) {
+        PyErr_Format(PyExc_TypeError,
+                     "unexpected return type from as_integer_ratio(): "
+                     "expected tuple, got '%.200s'",
+                     Py_TYPE(ratio)->tp_name);
+        Py_DECREF(ratio);
+        return NULL;
+    }
+    if (PyTuple_Size(ratio) != 2) {
+        PyErr_SetString(PyExc_ValueError,
+                        "as_integer_ratio() must return a 2-tuple");
+        Py_DECREF(ratio);
+        return NULL;
+    }
+    return ratio;
+}
+
 static PyObject *
 multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
 {
@@ -1656,9 +1685,10 @@ multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
     pyus_in = delta_to_microseconds(delta);
     if (pyus_in == NULL)
         return NULL;
-    ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
-    if (ratio == NULL)
+    ratio = get_float_as_integer_ratio(floatobj);
+    if (ratio == NULL) {
         goto error;
+    }
     temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
     Py_DECREF(pyus_in);
     pyus_in = NULL;
@@ -1754,9 +1784,10 @@ truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
     pyus_in = delta_to_microseconds(delta);
     if (pyus_in == NULL)
         return NULL;
-    ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
-    if (ratio == NULL)
+    ratio = get_float_as_integer_ratio(f);
+    if (ratio == NULL) {
         goto error;
+    }
     temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
     Py_DECREF(pyus_in);
     pyus_in = NULL;
@@ -2079,11 +2110,13 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
     assert(num != NULL);
 
     if (PyLong_Check(num)) {
-        prod = PyNumber_Multiply(num, factor);
+        prod = PyNumber_Multiply(factor, num);
         if (prod == NULL)
             return NULL;
+        assert(PyLong_CheckExact(prod));
         sum = PyNumber_Add(sofar, prod);
         Py_DECREF(prod);
+        assert(sum == NULL || PyLong_CheckExact(sum));
         return sum;
     }
 
@@ -2126,7 +2159,7 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
          * fractional part requires float arithmetic, and may
          * lose a little info.
          */
-        assert(PyLong_Check(factor));
+        assert(PyLong_CheckExact(factor));
         dnum = PyLong_AsDouble(factor);
 
         dnum *= fracpart;
@@ -2141,6 +2174,7 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
         Py_DECREF(sum);
         Py_DECREF(x);
         *leftover += fracpart;
+        assert(y == NULL || PyLong_CheckExact(y));
         return y;
     }
 
index a6d6c61dd24e08c6004a4da44be5f4fd1c67416a..707ab2912b3502e232c1e7f8349362ac8ad4302c 100644 (file)
@@ -61,15 +61,22 @@ do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0)
 #define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag)))
 #define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1))
 
+/* Py_SETREF for a PyObject* that uses a join flag. */
+Py_LOCAL_INLINE(void)
+_set_joined_ptr(PyObject **p, PyObject *new_joined_ptr)
+{
+    PyObject *tmp = JOIN_OBJ(*p);
+    *p = new_joined_ptr;
+    Py_DECREF(tmp);
+}
+
 /* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by
  * reference since this function sets it to NULL.
 */
 static void _clear_joined_ptr(PyObject **p)
 {
     if (*p) {
-        PyObject *tmp = JOIN_OBJ(*p);
-        *p = NULL;
-        Py_DECREF(tmp);
+        _set_joined_ptr(p, NULL);
     }
 }
 
@@ -356,7 +363,6 @@ static int
 element_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
     PyObject *tag;
-    PyObject *tmp;
     PyObject *attrib = NULL;
     ElementObject *self_elem;
 
@@ -397,15 +403,11 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
     Py_INCREF(tag);
     Py_XSETREF(self_elem->tag, tag);
 
-    tmp = self_elem->text;
     Py_INCREF(Py_None);
-    self_elem->text = Py_None;
-    Py_DECREF(JOIN_OBJ(tmp));
+    _set_joined_ptr(&self_elem->text, Py_None);
 
-    tmp = self_elem->tail;
     Py_INCREF(Py_None);
-    self_elem->tail = Py_None;
-    Py_DECREF(JOIN_OBJ(tmp));
+    _set_joined_ptr(&self_elem->tail, Py_None);
 
     return 0;
 }
@@ -675,12 +677,10 @@ _elementtree_Element_clear_impl(ElementObject *self)
     dealloc_extra(self);
 
     Py_INCREF(Py_None);
-    Py_DECREF(JOIN_OBJ(self->text));
-    self->text = Py_None;
+    _set_joined_ptr(&self->text, Py_None);
 
     Py_INCREF(Py_None);
-    Py_DECREF(JOIN_OBJ(self->tail));
-    self->tail = Py_None;
+    _set_joined_ptr(&self->tail, Py_None);
 
     Py_RETURN_NONE;
 }
@@ -702,13 +702,11 @@ _elementtree_Element___copy___impl(ElementObject *self)
     if (!element)
         return NULL;
 
-    Py_DECREF(JOIN_OBJ(element->text));
-    element->text = self->text;
-    Py_INCREF(JOIN_OBJ(element->text));
+    Py_INCREF(JOIN_OBJ(self->text));
+    _set_joined_ptr(&element->text, self->text);
 
-    Py_DECREF(JOIN_OBJ(element->tail));
-    element->tail = self->tail;
-    Py_INCREF(JOIN_OBJ(element->tail));
+    Py_INCREF(JOIN_OBJ(self->tail));
+    _set_joined_ptr(&element->tail, self->tail);
 
     if (self->extra) {
         if (element_resize(element, self->extra->length) < 0) {
@@ -776,14 +774,12 @@ _elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo)
     text = deepcopy(JOIN_OBJ(self->text), memo);
     if (!text)
         goto error;
-    Py_DECREF(element->text);
-    element->text = JOIN_SET(text, JOIN_GET(self->text));
+    _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text)));
 
     tail = deepcopy(JOIN_OBJ(self->tail), memo);
     if (!tail)
         goto error;
-    Py_DECREF(element->tail);
-    element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
+    _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail)));
 
     if (self->extra) {
         if (element_resize(element, self->extra->length) < 0)
@@ -967,13 +963,13 @@ element_setstate_from_attributes(ElementObject *self,
     Py_INCREF(tag);
     Py_XSETREF(self->tag, tag);
 
-    _clear_joined_ptr(&self->text);
-    self->text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
-    Py_INCREF(JOIN_OBJ(self->text));
+    text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
+    Py_INCREF(JOIN_OBJ(text));
+    _set_joined_ptr(&self->text, text);
 
-    _clear_joined_ptr(&self->tail);
-    self->tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None;
-    Py_INCREF(JOIN_OBJ(self->tail));
+    tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None;
+    Py_INCREF(JOIN_OBJ(tail));
+    _set_joined_ptr(&self->tail, tail);
 
     /* Handle ATTRIB and CHILDREN. */
     if (!children && !attrib)
@@ -1980,8 +1976,7 @@ element_text_setter(ElementObject *self, PyObject *value, void *closure)
 {
     _VALIDATE_ATTR_VALUE(value);
     Py_INCREF(value);
-    Py_DECREF(JOIN_OBJ(self->text));
-    self->text = value;
+    _set_joined_ptr(&self->text, value);
     return 0;
 }
 
@@ -1990,8 +1985,7 @@ element_tail_setter(ElementObject *self, PyObject *value, void *closure)
 {
     _VALIDATE_ATTR_VALUE(value);
     Py_INCREF(value);
-    Py_DECREF(JOIN_OBJ(self->tail));
-    self->tail = value;
+    _set_joined_ptr(&self->tail, value);
     return 0;
 }
 
index 918fa577758d2807f3e8afb9540c0c3486edc049..52cbb94b24b6b572e038d4c00caeb73108495606 100644 (file)
@@ -691,10 +691,12 @@ _io_FileIO_readall_impl(fileio *self)
     Py_ssize_t bytes_read = 0;
     Py_ssize_t n;
     size_t bufsize;
+    int fstat_result;
 
     if (self->fd < 0)
         return err_closed();
 
+    Py_BEGIN_ALLOW_THREADS
     _Py_BEGIN_SUPPRESS_IPH
 #ifdef MS_WINDOWS
     pos = _lseeki64(self->fd, 0L, SEEK_CUR);
@@ -702,8 +704,10 @@ _io_FileIO_readall_impl(fileio *self)
     pos = lseek(self->fd, 0L, SEEK_CUR);
 #endif
     _Py_END_SUPPRESS_IPH
+    fstat_result = _Py_fstat_noraise(self->fd, &status);
+    Py_END_ALLOW_THREADS
 
-    if (_Py_fstat_noraise(self->fd, &status) == 0)
+    if (fstat_result == 0)
         end = status.st_size;
     else
         end = (Py_off_t)-1;
index 588c6977691cfc780a3b9d3d38d3a6a3bfb7d60a..4638b4759701f84887909c6fa38a9af66046e3fe 100644 (file)
@@ -943,6 +943,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
     else {
         PyErr_SetString(PyExc_IOError,
                         "could not determine default encoding");
+        goto error;
     }
 
     /* Check we have been asked for a real text encoding */
index 59376a7b0fbcc0af1bafb31eccf1c0b5b48923e4..8f1743bada875394a950de4ce871b0cc603c7999 100644 (file)
@@ -1431,10 +1431,20 @@ static PyObject *
 encoder_encode_string(PyEncoderObject *s, PyObject *obj)
 {
     /* Return the JSON representation of a string */
-    if (s->fast_encode)
+    PyObject *encoded;
+
+    if (s->fast_encode) {
         return s->fast_encode(NULL, obj);
-    else
-        return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
+    }
+    encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
+    if (encoded != NULL && !PyUnicode_Check(encoded)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder() must return a string, not %.80s",
+                     Py_TYPE(encoded)->tp_name);
+        Py_DECREF(encoded);
+        return NULL;
+    }
+    return encoded;
 }
 
 static int
index ef0a03b107939f1161ffa6ace9467a8a79a32b6f..7e9bb9895ca2ad5f8c0821ac9918b309fa9329a6 100644 (file)
@@ -353,6 +353,69 @@ _Pickle_FastCall(PyObject *func, PyObject *obj)
 
 /*************************************************************************/
 
+/* Retrieve and deconstruct a method for avoiding a reference cycle
+   (pickler -> bound method of pickler -> pickler) */
+static int
+init_method_ref(PyObject *self, _Py_Identifier *name,
+                PyObject **method_func, PyObject **method_self)
+{
+    PyObject *func, *func2;
+
+    /* *method_func and *method_self should be consistent.  All refcount decrements
+       should be occurred after setting *method_self and *method_func. */
+    func = _PyObject_GetAttrId(self, name);
+    if (func == NULL) {
+        *method_self = NULL;
+        Py_CLEAR(*method_func);
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+            return -1;
+        }
+        PyErr_Clear();
+        return 0;
+    }
+
+    if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) {
+        /* Deconstruct a bound Python method */
+        func2 = PyMethod_GET_FUNCTION(func);
+        Py_INCREF(func2);
+        *method_self = self; /* borrowed */
+        Py_XSETREF(*method_func, func2);
+        Py_DECREF(func);
+        return 0;
+    }
+    else {
+        *method_self = NULL;
+        Py_XSETREF(*method_func, func);
+        return 0;
+    }
+}
+
+/* Bind a method if it was deconstructed */
+static PyObject *
+reconstruct_method(PyObject *func, PyObject *self)
+{
+    if (self) {
+        return PyMethod_New(func, self);
+    }
+    else {
+        Py_INCREF(func);
+        return func;
+    }
+}
+
+static PyObject *
+call_method(PyObject *func, PyObject *self, PyObject *obj)
+{
+    if (self) {
+        return PyObject_CallFunctionObjArgs(func, self, obj, NULL);
+    }
+    else {
+        return PyObject_CallFunctionObjArgs(func, obj, NULL);
+    }
+}
+
+/*************************************************************************/
+
 /* Internal data type used as the unpickling stack. */
 typedef struct {
     PyObject_VAR_HEAD
@@ -545,6 +608,8 @@ typedef struct PicklerObject {
                                    objects to support self-referential objects
                                    pickling. */
     PyObject *pers_func;        /* persistent_id() method, can be NULL */
+    PyObject *pers_func_self;   /* borrowed reference to self if pers_func
+                                   is an unbound method, NULL otherwise */
     PyObject *dispatch_table;   /* private dispatch_table, can be NULL */
 
     PyObject *write;            /* write() method of the output stream. */
@@ -583,6 +648,8 @@ typedef struct UnpicklerObject {
     Py_ssize_t memo_len;        /* Number of objects in the memo */
 
     PyObject *pers_func;        /* persistent_load() method, can be NULL. */
+    PyObject *pers_func_self;   /* borrowed reference to self if pers_func
+                                   is an unbound method, NULL otherwise */
 
     Py_buffer buffer;
     char *input_buffer;
@@ -1731,8 +1798,10 @@ fast_save_enter(PicklerObject *self, PyObject *obj)
             }
         }
         key = PyLong_FromVoidPtr(obj);
-        if (key == NULL)
+        if (key == NULL) {
+            self->fast_nesting = -1;
             return 0;
+        }
         if (PyDict_GetItemWithError(self->fast_memo, key)) {
             Py_DECREF(key);
             PyErr_Format(PyExc_ValueError,
@@ -1743,6 +1812,8 @@ fast_save_enter(PicklerObject *self, PyObject *obj)
             return 0;
         }
         if (PyErr_Occurred()) {
+            Py_DECREF(key);
+            self->fast_nesting = -1;
             return 0;
         }
         if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
@@ -3397,7 +3468,7 @@ save_type(PicklerObject *self, PyObject *obj)
 }
 
 static int
-save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
+save_pers(PicklerObject *self, PyObject *obj)
 {
     PyObject *pid = NULL;
     int status = 0;
@@ -3405,8 +3476,7 @@ save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
     const char persid_op = PERSID;
     const char binpersid_op = BINPERSID;
 
-    Py_INCREF(obj);
-    pid = _Pickle_FastCall(func, obj);
+    pid = call_method(self->pers_func, self->pers_func_self, obj);
     if (pid == NULL)
         return -1;
 
@@ -3784,7 +3854,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
              0   if it did nothing successfully;
              1   if a persistent id was saved.
          */
-        if ((status = save_pers(self, obj, self->pers_func)) != 0)
+        if ((status = save_pers(self, obj)) != 0)
             goto done;
     }
 
@@ -4198,19 +4268,20 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
     self->fast = 0;
     self->fast_nesting = 0;
     self->fast_memo = NULL;
-    self->pers_func = NULL;
-    if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_id)) {
-        self->pers_func = _PyObject_GetAttrId((PyObject *)self,
-                                              &PyId_persistent_id);
-        if (self->pers_func == NULL)
-            return -1;
+
+    if (init_method_ref((PyObject *)self, &PyId_persistent_id,
+                        &self->pers_func, &self->pers_func_self) < 0)
+    {
+        return -1;
     }
-    self->dispatch_table = NULL;
-    if (_PyObject_HasAttrId((PyObject *)self, &PyId_dispatch_table)) {
-        self->dispatch_table = _PyObject_GetAttrId((PyObject *)self,
-                                                   &PyId_dispatch_table);
-        if (self->dispatch_table == NULL)
+
+    self->dispatch_table = _PyObject_GetAttrId((PyObject *)self,
+                                               &PyId_dispatch_table);
+    if (self->dispatch_table == NULL) {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
             return -1;
+        }
+        PyErr_Clear();
     }
 
     return 0;
@@ -4468,11 +4539,11 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj)
 static PyObject *
 Pickler_get_persid(PicklerObject *self)
 {
-    if (self->pers_func == NULL)
+    if (self->pers_func == NULL) {
         PyErr_SetString(PyExc_AttributeError, "persistent_id");
-    else
-        Py_INCREF(self->pers_func);
-    return self->pers_func;
+        return NULL;
+    }
+    return reconstruct_method(self->pers_func, self->pers_func_self);
 }
 
 static int
@@ -4489,6 +4560,7 @@ Pickler_set_persid(PicklerObject *self, PyObject *value)
         return -1;
     }
 
+    self->pers_func_self = NULL;
     Py_INCREF(value);
     Py_XSETREF(self->pers_func, value);
 
@@ -5165,22 +5237,24 @@ load_frozenset(UnpicklerObject *self)
 static PyObject *
 instantiate(PyObject *cls, PyObject *args)
 {
-    PyObject *result = NULL;
-    _Py_IDENTIFIER(__getinitargs__);
     /* Caller must assure args are a tuple.  Normally, args come from
        Pdata_poptuple which packs objects from the top of the stack
        into a newly created tuple. */
     assert(PyTuple_Check(args));
-    if (Py_SIZE(args) > 0 || !PyType_Check(cls) ||
-        _PyObject_HasAttrId(cls, &PyId___getinitargs__)) {
-        result = PyObject_CallObject(cls, args);
-    }
-    else {
+    if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) {
+        _Py_IDENTIFIER(__getinitargs__);
         _Py_IDENTIFIER(__new__);
-
-        result = _PyObject_CallMethodId(cls, &PyId___new__, "O", cls);
+        PyObject *func = _PyObject_GetAttrId(cls, &PyId___getinitargs__);
+        if (func == NULL) {
+            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+                return NULL;
+            }
+            PyErr_Clear();
+            return _PyObject_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL);
+        }
+        Py_DECREF(func);
     }
-    return result;
+    return PyObject_CallObject(cls, args);
 }
 
 static int
@@ -5436,7 +5510,7 @@ load_stack_global(UnpicklerObject *self)
 static int
 load_persid(UnpicklerObject *self)
 {
-    PyObject *pid;
+    PyObject *pid, *obj;
     Py_ssize_t len;
     char *s;
 
@@ -5456,13 +5530,12 @@ load_persid(UnpicklerObject *self)
             return -1;
         }
 
-        /* This does not leak since _Pickle_FastCall() steals the reference
-           to pid first. */
-        pid = _Pickle_FastCall(self->pers_func, pid);
-        if (pid == NULL)
+        obj = call_method(self->pers_func, self->pers_func_self, pid);
+        Py_DECREF(pid);
+        if (obj == NULL)
             return -1;
 
-        PDATA_PUSH(self->stack, pid, -1);
+        PDATA_PUSH(self->stack, obj, -1);
         return 0;
     }
     else {
@@ -5477,20 +5550,19 @@ load_persid(UnpicklerObject *self)
 static int
 load_binpersid(UnpicklerObject *self)
 {
-    PyObject *pid;
+    PyObject *pid, *obj;
 
     if (self->pers_func) {
         PDATA_POP(self->stack, pid);
         if (pid == NULL)
             return -1;
 
-        /* This does not leak since _Pickle_FastCall() steals the
-           reference to pid first. */
-        pid = _Pickle_FastCall(self->pers_func, pid);
-        if (pid == NULL)
+        obj = call_method(self->pers_func, self->pers_func_self, pid);
+        Py_DECREF(pid);
+        if (obj == NULL)
             return -1;
 
-        PDATA_PUSH(self->stack, pid, -1);
+        PDATA_PUSH(self->stack, obj, -1);
         return 0;
     }
     else {
@@ -6626,17 +6698,11 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file,
         return -1;
 
     self->fix_imports = fix_imports;
-    if (self->fix_imports == -1)
-        return -1;
 
-    if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_load)) {
-        self->pers_func = _PyObject_GetAttrId((PyObject *)self,
-                                              &PyId_persistent_load);
-        if (self->pers_func == NULL)
-            return 1;
-    }
-    else {
-        self->pers_func = NULL;
+    if (init_method_ref((PyObject *)self, &PyId_persistent_load,
+                        &self->pers_func, &self->pers_func_self) < 0)
+    {
+        return -1;
     }
 
     self->stack = (Pdata *)Pdata_New();
@@ -6923,11 +6989,11 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
 static PyObject *
 Unpickler_get_persload(UnpicklerObject *self)
 {
-    if (self->pers_func == NULL)
+    if (self->pers_func == NULL) {
         PyErr_SetString(PyExc_AttributeError, "persistent_load");
-    else
-        Py_INCREF(self->pers_func);
-    return self->pers_func;
+        return NULL;
+    }
+    return reconstruct_method(self->pers_func, self->pers_func_self);
 }
 
 static int
@@ -6945,6 +7011,7 @@ Unpickler_set_persload(UnpicklerObject *self, PyObject *value)
         return -1;
     }
 
+    self->pers_func_self = NULL;
     Py_INCREF(value);
     Py_XSETREF(self->pers_func, value);
 
index d006aebf927c38503584dfb8a2aa552c4fa5798d..769084fa88ddef9c1f99dff74cd9b2b5198cc72f 100644 (file)
@@ -259,8 +259,11 @@ random_seed(RandomObject *self, PyObject *args)
      * So: if the arg is a PyLong, use its absolute value.
      * Otherwise use its hash value, cast to unsigned.
      */
-    if (PyLong_Check(arg))
-        n = PyNumber_Absolute(arg);
+    if (PyLong_Check(arg)) {
+        /* Calling int.__abs__() prevents calling arg.__abs__(), which might
+           return an invalid value. See issue #31478. */
+        n = PyLong_Type.tp_as_number->nb_absolute(arg);
+    }
     else {
         Py_hash_t hash = PyObject_Hash(arg);
         if (hash == -1)
index 8341fb8480172c946bfdc62c0c52dcac402d221f..82373409471a88d029e78e837159e885b516cb3c 100644 (file)
@@ -39,21 +39,20 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*
     }
 
     Py_INCREF(connection);
-    self->connection = connection;
-    self->statement = NULL;
-    self->next_row = NULL;
-    self->in_weakreflist = NULL;
+    Py_XSETREF(self->connection, connection);
+    Py_CLEAR(self->statement);
+    Py_CLEAR(self->next_row);
 
-    self->row_cast_map = PyList_New(0);
+    Py_XSETREF(self->row_cast_map, PyList_New(0));
     if (!self->row_cast_map) {
         return -1;
     }
 
     Py_INCREF(Py_None);
-    self->description = Py_None;
+    Py_XSETREF(self->description, Py_None);
 
     Py_INCREF(Py_None);
-    self->lastrowid= Py_None;
+    Py_XSETREF(self->lastrowid, Py_None);
 
     self->arraysize = 1;
     self->closed = 0;
@@ -62,7 +61,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*
     self->rowcount = -1L;
 
     Py_INCREF(Py_None);
-    self->row_factory = Py_None;
+    Py_XSETREF(self->row_factory, Py_None);
 
     if (!pysqlite_check_thread(self->connection)) {
         return -1;
@@ -917,6 +916,11 @@ PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args)
 
 PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args)
 {
+    if (!self->connection) {
+        PyErr_SetString(pysqlite_ProgrammingError,
+                        "Base Cursor.__init__ not called.");
+        return NULL;
+    }
     if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
         return NULL;
     }
index a32fce47ef641a766a7a71cced585e7d04714d43..df8c6a7d96d8d875e4ff8d3d021bdb5856c7207e 100644 (file)
@@ -2736,7 +2736,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
 #endif
     SSL_CTX_set_options(self->ctx, options);
 
-    /* A bare minimum cipher list without completly broken cipher suites.
+    /* A bare minimum cipher list without completely broken cipher suites.
      * It's far from perfect but gives users a better head start. */
     if (proto_version != PY_SSL_VERSION_SSL2) {
         result = SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!eNULL:!MD5");
index ede675da28505cf9665bfb623a5293349c168042..c2c63e94db3edb9e9b868d99c6034983327a9600 100644 (file)
@@ -3016,7 +3016,8 @@ check_time_rounding(int round)
 {
     if (round != _PyTime_ROUND_FLOOR
         && round != _PyTime_ROUND_CEILING
-        && round != _PyTime_ROUND_HALF_EVEN) {
+        && round != _PyTime_ROUND_HALF_EVEN
+        && round != _PyTime_ROUND_UP) {
         PyErr_SetString(PyExc_ValueError, "invalid rounding");
         return -1;
     }
@@ -3436,6 +3437,130 @@ test_pyobject_setallocators(PyObject *self)
     return test_setallocators(PYMEM_DOMAIN_OBJ);
 }
 
+/* Most part of the following code is inherited from the pyfailmalloc project
+ * written by Victor Stinner. */
+static struct {
+    int installed;
+    PyMemAllocatorEx raw;
+    PyMemAllocatorEx mem;
+    PyMemAllocatorEx obj;
+} FmHook;
+
+static struct {
+    int start;
+    int stop;
+    Py_ssize_t count;
+} FmData;
+
+static int
+fm_nomemory(void)
+{
+    FmData.count++;
+    if (FmData.count > FmData.start &&
+            (FmData.stop <= 0 || FmData.count <= FmData.stop)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void *
+hook_fmalloc(void *ctx, size_t size)
+{
+    PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
+    if (fm_nomemory()) {
+        return NULL;
+    }
+    return alloc->malloc(alloc->ctx, size);
+}
+
+static void *
+hook_fcalloc(void *ctx, size_t nelem, size_t elsize)
+{
+    PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
+    if (fm_nomemory()) {
+        return NULL;
+    }
+    return alloc->calloc(alloc->ctx, nelem, elsize);
+}
+
+static void *
+hook_frealloc(void *ctx, void *ptr, size_t new_size)
+{
+    PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
+    if (fm_nomemory()) {
+        return NULL;
+    }
+    return alloc->realloc(alloc->ctx, ptr, new_size);
+}
+
+static void
+hook_ffree(void *ctx, void *ptr)
+{
+    PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx;
+    alloc->free(alloc->ctx, ptr);
+}
+
+static void
+fm_setup_hooks(void)
+{
+    PyMemAllocatorEx alloc;
+
+    if (FmHook.installed) {
+        return;
+    }
+    FmHook.installed = 1;
+
+    alloc.malloc = hook_fmalloc;
+    alloc.calloc = hook_fcalloc;
+    alloc.realloc = hook_frealloc;
+    alloc.free = hook_ffree;
+    PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw);
+    PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem);
+    PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj);
+
+    alloc.ctx = &FmHook.raw;
+    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc);
+
+    alloc.ctx = &FmHook.mem;
+    PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc);
+
+    alloc.ctx = &FmHook.obj;
+    PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc);
+}
+
+static void
+fm_remove_hooks(void)
+{
+    if (FmHook.installed) {
+        FmHook.installed = 0;
+        PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw);
+        PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem);
+        PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj);
+    }
+}
+
+static PyObject*
+set_nomemory(PyObject *self, PyObject *args)
+{
+    /* Memory allocation fails after 'start' allocation requests, and until
+     * 'stop' allocation requests except when 'stop' is negative or equal
+     * to 0 (default) in which case allocation failures never stop. */
+    FmData.count = 0;
+    FmData.stop = 0;
+    if (!PyArg_ParseTuple(args, "i|i", &FmData.start, &FmData.stop)) {
+        return NULL;
+    }
+    fm_setup_hooks();
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+remove_mem_hooks(PyObject *self)
+{
+    fm_remove_hooks();
+    Py_RETURN_NONE;
+}
+
 PyDoc_STRVAR(docstring_empty,
 ""
 );
@@ -4317,6 +4442,10 @@ static PyMethodDef TestMethods[] = {
      (PyCFunction)test_pymem_setallocators, METH_NOARGS},
     {"test_pyobject_setallocators",
      (PyCFunction)test_pyobject_setallocators, METH_NOARGS},
+    {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS,
+     PyDoc_STR("set_nomemory(start:int, stop:int = 0)")},
+    {"remove_mem_hooks", (PyCFunction)remove_mem_hooks, METH_NOARGS,
+     PyDoc_STR("Remove memory hooks.")},
     {"no_docstring",
         (PyCFunction)test_with_docstring, METH_NOARGS},
     {"docstring_empty",
@@ -4733,6 +4862,61 @@ static PyTypeObject awaitType = {
 };
 
 
+static int recurse_infinitely_error_init(PyObject *, PyObject *, PyObject *);
+
+static PyTypeObject PyRecursingInfinitelyError_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "RecursingInfinitelyError",   /* tp_name */
+    sizeof(PyBaseExceptionObject), /* tp_basicsize */
+    0,                          /* tp_itemsize */
+    0,                          /* tp_dealloc */
+    0,                          /* tp_print */
+    0,                          /* tp_getattr */
+    0,                          /* tp_setattr */
+    0,                          /* tp_reserved */
+    0,                          /* tp_repr */
+    0,                          /* tp_as_number */
+    0,                          /* tp_as_sequence */
+    0,                          /* tp_as_mapping */
+    0,                          /* tp_hash */
+    0,                          /* tp_call */
+    0,                          /* tp_str */
+    0,                          /* tp_getattro */
+    0,                          /* tp_setattro */
+    0,                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    "Instantiating this exception starts infinite recursion.", /* tp_doc */
+    0,                          /* tp_traverse */
+    0,                          /* tp_clear */
+    0,                          /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    0,                          /* tp_iter */
+    0,                          /* tp_iternext */
+    0,                          /* tp_methods */
+    0,                          /* tp_members */
+    0,                          /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    0,                          /* tp_dictoffset */
+    (initproc)recurse_infinitely_error_init, /* tp_init */
+    0,                          /* tp_alloc */
+    0,                          /* tp_new */
+};
+
+static int
+recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
+
+    /* Instantiating this exception starts infinite recursion. */
+    Py_INCREF(type);
+    PyErr_SetObject(type, NULL);
+    return -1;
+}
+
+
 static struct PyModuleDef _testcapimodule = {
     PyModuleDef_HEAD_INIT,
     "_testcapi",
@@ -4774,6 +4958,14 @@ PyInit__testcapi(void)
     Py_INCREF(&awaitType);
     PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType);
 
+    PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
+    if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
+        return NULL;
+    }
+    Py_INCREF(&PyRecursingInfinitelyError_Type);
+    PyModule_AddObject(m, "RecursingInfinitelyError",
+                       (PyObject *)&PyRecursingInfinitelyError_Type);
+
     PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
     PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
     PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));
index 02195596093771f24e989c014f62f65468fae9d4..47e84b9e916d9928b28c89fd81d9b327d72cee68 100644 (file)
@@ -111,7 +111,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds,
 
     if (timeout_obj
         && _PyTime_FromSecondsObject(timeout,
-                                     timeout_obj, _PyTime_ROUND_CEILING) < 0)
+                                     timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
         return -1;
 
     if (!blocking && *timeout != unset_timeout ) {
@@ -129,7 +129,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds,
     else if (*timeout != unset_timeout) {
         _PyTime_t microseconds;
 
-        microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_CEILING);
+        microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
         if (microseconds >= PY_TIMEOUT_MAX) {
             PyErr_SetString(PyExc_OverflowError,
                             "timeout value is too large");
index 4a1324cb7e621bdbb3418b98b0514aa2d0448b25..68ee26e790ccaf1feece5f1b2643fe0753a503e5 100644 (file)
@@ -1668,7 +1668,7 @@ _tkinter_tkapp_record_impl(TkappObject *self, const char *script)
 }
 
 /*[clinic input]
-_tkinter.tkapp.adderrinfo
+_tkinter.tkapp.adderrorinfo
 
     msg: str
     /
@@ -1676,8 +1676,8 @@ _tkinter.tkapp.adderrinfo
 [clinic start generated code]*/
 
 static PyObject *
-_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg)
-/*[clinic end generated code: output=0e222ee2050eb357 input=4971399317d4c136]*/
+_tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg)
+/*[clinic end generated code: output=52162eaca2ee53cb input=f4b37aec7c7e8c77]*/
 {
     CHECK_STRING_LENGTH(msg);
     CHECK_TCL_APPARTMENT;
@@ -2291,7 +2291,11 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg)
     if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list))
         return NULL;
 
-    CHECK_STRING_LENGTH(list);
+    if (strlen(list) >= INT_MAX) {
+        PyErr_SetString(PyExc_OverflowError, "string is too long");
+        PyMem_Free(list);
+        return NULL;
+    }
     if (Tcl_SplitList(Tkapp_Interp(self), list,
                       &argc, &argv) == TCL_ERROR)  {
         PyMem_Free(list);
@@ -2362,7 +2366,11 @@ _tkinter_tkapp_split(TkappObject *self, PyObject *arg)
 
     if (!PyArg_Parse(arg, "et:split", "utf-8", &list))
         return NULL;
-    CHECK_STRING_LENGTH(list);
+    if (strlen(list) >= INT_MAX) {
+        PyErr_SetString(PyExc_OverflowError, "string is too long");
+        PyMem_Free(list);
+        return NULL;
+    }
     v = Split(list);
     PyMem_Free(list);
     return v;
@@ -3304,7 +3312,7 @@ static PyMethodDef Tkapp_methods[] =
     _TKINTER_TKAPP_EVAL_METHODDEF
     _TKINTER_TKAPP_EVALFILE_METHODDEF
     _TKINTER_TKAPP_RECORD_METHODDEF
-    _TKINTER_TKAPP_ADDERRINFO_METHODDEF
+    _TKINTER_TKAPP_ADDERRORINFO_METHODDEF
     {"setvar",                 Tkapp_SetVar, METH_VARARGS},
     {"globalsetvar",       Tkapp_GlobalSetVar, METH_VARARGS},
     {"getvar",       Tkapp_GetVar, METH_VARARGS},
index 64e0f172fd7d821305911d15b9825a05adc7e134..9254af59a6a2d61fcfdde92df7ba3ccf3a45bc33 100644 (file)
@@ -1885,8 +1885,10 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
         return NULL;
 
     new_args = PyTuple_New(2);
-    if (new_args == NULL)
+    if (new_args == NULL) {
+        Py_DECREF(typecode_obj);
         return NULL;
+    }
     Py_INCREF(items);
     PyTuple_SET_ITEM(new_args, 0, typecode_obj);
     PyTuple_SET_ITEM(new_args, 1, items);
index edd53800058dab55336ec39ccaf63bcbb13108ea..c407f17da4cb84de494c4fbe96dee827bb7216b7 100644 (file)
@@ -80,27 +80,27 @@ exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_tkinter_tkapp_adderrinfo__doc__,
-"adderrinfo($self, msg, /)\n"
+PyDoc_STRVAR(_tkinter_tkapp_adderrorinfo__doc__,
+"adderrorinfo($self, msg, /)\n"
 "--\n"
 "\n");
 
-#define _TKINTER_TKAPP_ADDERRINFO_METHODDEF    \
-    {"adderrinfo", (PyCFunction)_tkinter_tkapp_adderrinfo, METH_O, _tkinter_tkapp_adderrinfo__doc__},
+#define _TKINTER_TKAPP_ADDERRORINFO_METHODDEF    \
+    {"adderrorinfo", (PyCFunction)_tkinter_tkapp_adderrorinfo, METH_O, _tkinter_tkapp_adderrorinfo__doc__},
 
 static PyObject *
-_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg);
+_tkinter_tkapp_adderrorinfo_impl(TkappObject *self, const char *msg);
 
 static PyObject *
-_tkinter_tkapp_adderrinfo(TkappObject *self, PyObject *arg)
+_tkinter_tkapp_adderrorinfo(TkappObject *self, PyObject *arg)
 {
     PyObject *return_value = NULL;
     const char *msg;
 
-    if (!PyArg_Parse(arg, "s:adderrinfo", &msg)) {
+    if (!PyArg_Parse(arg, "s:adderrorinfo", &msg)) {
         goto exit;
     }
-    return_value = _tkinter_tkapp_adderrinfo_impl(self, msg);
+    return_value = _tkinter_tkapp_adderrorinfo_impl(self, msg);
 
 exit:
     return return_value;
@@ -638,4 +638,4 @@ exit:
 #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
     #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF
 #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */
-/*[clinic end generated code: output=836c578b71d69097 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b0be55aacff2be9b input=a9049054013a1b77]*/
index fda392a9cde38f169e97f152cb47a7f701623a59..7339596d22fd92ac2c6add1082f71bc8ed0c1813 100644 (file)
@@ -467,4 +467,8 @@ exit:
 #ifndef ZLIB_COMPRESS_COPY_METHODDEF
     #define ZLIB_COMPRESS_COPY_METHODDEF
 #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */
-/*[clinic end generated code: output=3a4e2bfe750423a3 input=a9049054013a1b77]*/
+
+#ifndef ZLIB_DECOMPRESS_COPY_METHODDEF
+    #define ZLIB_DECOMPRESS_COPY_METHODDEF
+#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */
+/*[clinic end generated code: output=497dad1132c962e2 input=a9049054013a1b77]*/
index 2efa998ff89aac1a06946c0d1ddb9266356d9bd6..d5194cad610080af26e990fe16205482affb3ca0 100644 (file)
@@ -366,6 +366,23 @@ faulthandler_fatal_error(int signum)
 }
 
 #ifdef MS_WINDOWS
+static int
+faulthandler_ignore_exception(DWORD code)
+{
+    /* bpo-30557: ignore exceptions which are not errors */
+    if (!(code & 0x80000000)) {
+        return 1;
+    }
+    /* bpo-31701: ignore MSC and COM exceptions
+       E0000000 + code */
+    if (code == 0xE06D7363 /* MSC exception ("Emsc") */
+        || code == 0xE0434352 /* COM Callable Runtime exception ("ECCR") */) {
+        return 1;
+    }
+    /* Interesting exception: log it with the Python traceback */
+    return 0;
+}
+
 static LONG WINAPI
 faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
 {
@@ -373,9 +390,8 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
     DWORD code = exc_info->ExceptionRecord->ExceptionCode;
     DWORD flags = exc_info->ExceptionRecord->ExceptionFlags;
 
-    /* bpo-30557: only log fatal exceptions */
-    if (!(code & 0x80000000)) {
-        /* call the next exception handler */
+    if (faulthandler_ignore_exception(code)) {
+        /* ignore the exception: call the next exception handler */
         return EXCEPTION_CONTINUE_SEARCH;
     }
 
index 0f916436c515d6f53c24a0308887a08dadc70181..dd3387a9d77f98c79de5f750d92a3be2fe6bff39 100644 (file)
@@ -735,7 +735,7 @@ calculate_path(void)
     bufsz += wcslen(zip_path) + 1;
     bufsz += wcslen(exec_prefix) + 1;
 
-    buf = PyMem_New(wchar_t, bufsz);
+    buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
     if (buf == NULL) {
         Py_FatalError(
             "Not enough memory for dynamic PYTHONPATH");
index 8e22ec9c4b7cc19b53666116164e41138e45bd4b..3ff597b0a357742c92b21a4840ae5132b4113aad 100644 (file)
@@ -72,10 +72,37 @@ groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
     return 0;
 }
 
+Py_LOCAL_INLINE(int)
+groupby_step(groupbyobject *gbo)
+{
+    PyObject *newvalue, *newkey, *oldvalue;
+
+    newvalue = PyIter_Next(gbo->it);
+    if (newvalue == NULL)
+        return -1;
+
+    if (gbo->keyfunc == Py_None) {
+        newkey = newvalue;
+        Py_INCREF(newvalue);
+    } else {
+        newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);
+        if (newkey == NULL) {
+            Py_DECREF(newvalue);
+            return -1;
+        }
+    }
+
+    oldvalue = gbo->currvalue;
+    gbo->currvalue = newvalue;
+    Py_XSETREF(gbo->currkey, newkey);
+    Py_XDECREF(oldvalue);
+    return 0;
+}
+
 static PyObject *
 groupby_next(groupbyobject *gbo)
 {
-    PyObject *newvalue, *newkey, *r, *grouper;
+    PyObject *r, *grouper;
 
     /* skip to next iteration group */
     for (;;) {
@@ -93,25 +120,9 @@ groupby_next(groupbyobject *gbo)
                 break;
         }
 
-        newvalue = PyIter_Next(gbo->it);
-        if (newvalue == NULL)
+        if (groupby_step(gbo) < 0)
             return NULL;
-
-        if (gbo->keyfunc == Py_None) {
-            newkey = newvalue;
-            Py_INCREF(newvalue);
-        } else {
-            newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);
-            if (newkey == NULL) {
-                Py_DECREF(newvalue);
-                return NULL;
-            }
-        }
-
-        Py_XSETREF(gbo->currkey, newkey);
-        Py_XSETREF(gbo->currvalue, newvalue);
     }
-
     Py_INCREF(gbo->currkey);
     Py_XSETREF(gbo->tgtkey, gbo->currkey);
 
@@ -174,8 +185,9 @@ static PyMethodDef groupby_methods[] = {
 };
 
 PyDoc_STRVAR(groupby_doc,
-"groupby(iterable[, keyfunc]) -> create an iterator which returns\n\
-(key, sub-iterator) grouped by each value of key(value).\n");
+"groupby(iterable, key=None) -> make an iterator that returns consecutive\n\
+keys and groups from the iterable.  If the key function is not specified or\n\
+is None, the element itself is used for grouping.\n");
 
 static PyTypeObject groupby_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
@@ -281,28 +293,12 @@ static PyObject *
 _grouper_next(_grouperobject *igo)
 {
     groupbyobject *gbo = (groupbyobject *)igo->parent;
-    PyObject *newvalue, *newkey, *r;
+    PyObject *r;
     int rcmp;
 
     if (gbo->currvalue == NULL) {
-        newvalue = PyIter_Next(gbo->it);
-        if (newvalue == NULL)
+        if (groupby_step(gbo) < 0)
             return NULL;
-
-        if (gbo->keyfunc == Py_None) {
-            newkey = newvalue;
-            Py_INCREF(newvalue);
-        } else {
-            newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);
-            if (newkey == NULL) {
-                Py_DECREF(newvalue);
-                return NULL;
-            }
-        }
-
-        assert(gbo->currkey == NULL);
-        gbo->currkey = newkey;
-        gbo->currvalue = newvalue;
     }
 
     assert(gbo->currkey != NULL);
index 475a2fdc36db9bb7da97f34398983a133d98c284..b0fb78f887a58016f544c98af05e4da7b62fdc86 100644 (file)
@@ -20,9 +20,9 @@
 #endif
 
 #if defined(MS_WINDOWS)
-#define PYTHONHOMEHELP "<prefix>\\lib"
+#define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
 #else
-#define PYTHONHOMEHELP "<prefix>/pythonX.X"
+#define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
 #endif
 
 #include "pygetopt.h"
@@ -71,9 +71,9 @@ static const char usage_2[] = "\
 -S     : don't imply 'import site' on initialization\n\
 ";
 static const char usage_3[] = "\
--u     : unbuffered binary stdout and stderr, stdin always buffered;\n\
+-u     : force the binary I/O layers of stdout and stderr to be unbuffered;\n\
+         stdin is always buffered; text I/O layer will be line-buffered;\n\
          also PYTHONUNBUFFERED=x\n\
-         see man page for details on internal buffering relating to '-u'\n\
 -v     : verbose (trace import statements); also PYTHONVERBOSE=x\n\
          can be supplied multiple times to increase verbosity\n\
 -V     : print the Python version number and exit (also --version)\n\
index 07a20c85d76dab5e5b7bc8fb970150fca77fcaac..7e81f1904c0a6f7e6a35d88d0d357519a86ba93d 100644 (file)
@@ -213,7 +213,7 @@ select_select(PyObject *self, PyObject *args)
         tvp = (struct timeval *)NULL;
     else {
         if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
-                                      _PyTime_ROUND_CEILING) < 0) {
+                                      _PyTime_ROUND_TIMEOUT) < 0) {
             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "timeout must be a float or None");
@@ -221,7 +221,7 @@ select_select(PyObject *self, PyObject *args)
             return NULL;
         }
 
-        if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -1)
+        if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_TIMEOUT) == -1)
             return NULL;
         if (tv.tv_sec < 0) {
             PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
@@ -528,22 +528,16 @@ poll_poll(pollObject *self, PyObject *args)
     PyObject *result_list = NULL, *timeout_obj = NULL;
     int poll_result, i, j;
     PyObject *value = NULL, *num = NULL;
-    _PyTime_t timeout, ms, deadline;
+    _PyTime_t timeout = -1, ms = -1, deadline = 0;
     int async_err = 0;
 
     if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) {
         return NULL;
     }
 
-    /* Check values for timeout */
-    if (timeout_obj == NULL || timeout_obj == Py_None) {
-        timeout = -1;
-        ms = -1;
-        deadline = 0;   /* initialize to prevent gcc warning */
-    }
-    else {
+    if (timeout_obj != NULL && timeout_obj != Py_None) {
         if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
-                                           _PyTime_ROUND_CEILING) < 0) {
+                                           _PyTime_ROUND_TIMEOUT) < 0) {
             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "timeout must be an integer or None");
@@ -551,13 +545,26 @@ poll_poll(pollObject *self, PyObject *args)
             return NULL;
         }
 
-        ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
+        ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
         if (ms < INT_MIN || ms > INT_MAX) {
             PyErr_SetString(PyExc_OverflowError, "timeout is too large");
             return NULL;
         }
 
-        deadline = _PyTime_GetMonotonicClock() + timeout;
+        if (timeout >= 0) {
+            deadline = _PyTime_GetMonotonicClock() + timeout;
+        }
+    }
+
+    /* On some OSes, typically BSD-based ones, the timeout parameter of the
+       poll() syscall, when negative, must be exactly INFTIM, where defined,
+       or -1. See issue 31334. */
+    if (ms < 0) {
+#ifdef INFTIM
+        ms = INFTIM;
+#else
+        ms = -1;
+#endif
     }
 
     /* Avoid concurrent poll() invocation, issue 8865 */
@@ -899,7 +906,7 @@ devpoll_poll(devpollObject *self, PyObject *args)
     }
     else {
         if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj,
-                                           _PyTime_ROUND_CEILING) < 0) {
+                                           _PyTime_ROUND_TIMEOUT) < 0) {
             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "timeout must be an integer or None");
@@ -907,7 +914,7 @@ devpoll_poll(devpollObject *self, PyObject *args)
             return NULL;
         }
 
-        ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING);
+        ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_TIMEOUT);
         if (ms < -1 || ms > INT_MAX) {
             PyErr_SetString(PyExc_OverflowError, "timeout is too large");
             return NULL;
@@ -1514,7 +1521,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
         /* epoll_wait() has a resolution of 1 millisecond, round towards
            infinity to wait at least timeout seconds. */
         if (_PyTime_FromSecondsObject(&timeout, timeout_obj,
-                                      _PyTime_ROUND_CEILING) < 0) {
+                                      _PyTime_ROUND_TIMEOUT) < 0) {
             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "timeout must be an integer or None");
@@ -1773,40 +1780,73 @@ static PyTypeObject kqueue_queue_Type;
 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
 #   define T_UINTPTRT         T_ULONGLONG
 #   define T_INTPTRT          T_LONGLONG
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
 #   define UINTPTRT_FMT_UNIT  "K"
 #   define INTPTRT_FMT_UNIT   "L"
 #elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
 #   define T_UINTPTRT         T_ULONG
 #   define T_INTPTRT          T_LONG
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
 #   define UINTPTRT_FMT_UNIT  "k"
 #   define INTPTRT_FMT_UNIT   "l"
 #elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
 #   define T_UINTPTRT         T_UINT
 #   define T_INTPTRT          T_INT
-#   define PyLong_AsUintptr_t PyLong_AsUnsignedLong
 #   define UINTPTRT_FMT_UNIT  "I"
 #   define INTPTRT_FMT_UNIT   "i"
 #else
 #   error uintptr_t does not match int, long, or long long!
 #endif
 
+#if SIZEOF_LONG_LONG == 8
+#   define T_INT64          T_LONGLONG
+#   define INT64_FMT_UNIT   "L"
+#elif SIZEOF_LONG == 8
+#   define T_INT64          T_LONG
+#   define INT64_FMT_UNIT   "l"
+#elif SIZEOF_INT == 8
+#   define T_INT64          T_INT
+#   define INT64_FMT_UNIT   "i"
+#else
+#   define INT64_FMT_UNIT   "_"
+#endif
+
+#if SIZEOF_LONG_LONG == 4
+#   define T_UINT32         T_ULONGLONG
+#   define UINT32_FMT_UNIT  "K"
+#elif SIZEOF_LONG == 4
+#   define T_UINT32         T_ULONG
+#   define UINT32_FMT_UNIT  "k"
+#elif SIZEOF_INT == 4
+#   define T_UINT32         T_UINT
+#   define UINT32_FMT_UNIT  "I"
+#else
+#   define UINT32_FMT_UNIT  "_"
+#endif
+
 /*
  * kevent is not standard and its members vary across BSDs.
  */
-#if !defined(__OpenBSD__)
-#   define IDENT_TYPE  T_UINTPTRT
-#   define IDENT_CAST  intptr_t
-#   define DATA_TYPE   T_INTPTRT
-#   define DATA_FMT_UNIT INTPTRT_FMT_UNIT
-#   define IDENT_AsType PyLong_AsUintptr_t
+#ifdef __NetBSD__
+#   define FILTER_TYPE      T_UINT32
+#   define FILTER_FMT_UNIT  UINT32_FMT_UNIT
+#   define FLAGS_TYPE       T_UINT32
+#   define FLAGS_FMT_UNIT   UINT32_FMT_UNIT
+#   define FFLAGS_TYPE      T_UINT32
+#   define FFLAGS_FMT_UNIT  UINT32_FMT_UNIT
+#else
+#   define FILTER_TYPE      T_SHORT
+#   define FILTER_FMT_UNIT  "h"
+#   define FLAGS_TYPE       T_USHORT
+#   define FLAGS_FMT_UNIT   "H"
+#   define FFLAGS_TYPE      T_UINT
+#   define FFLAGS_FMT_UNIT  "I"
+#endif
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+#   define DATA_TYPE        T_INT64
+#   define DATA_FMT_UNIT    INT64_FMT_UNIT
 #else
-#   define IDENT_TYPE  T_UINT
-#   define IDENT_CAST  int
-#   define DATA_TYPE   T_INT
-#   define DATA_FMT_UNIT "i"
-#   define IDENT_AsType PyLong_AsUnsignedLong
+#   define DATA_TYPE        T_INTPTRT
+#   define DATA_FMT_UNIT    INTPTRT_FMT_UNIT
 #endif
 
 /* Unfortunately, we can't store python objects in udata, because
@@ -1816,9 +1856,9 @@ static PyTypeObject kqueue_queue_Type;
 
 #define KQ_OFF(x) offsetof(kqueue_event_Object, x)
 static struct PyMemberDef kqueue_event_members[] = {
-    {"ident",           IDENT_TYPE,     KQ_OFF(e.ident)},
-    {"filter",          T_SHORT,        KQ_OFF(e.filter)},
-    {"flags",           T_USHORT,       KQ_OFF(e.flags)},
+    {"ident",           T_UINTPTRT,     KQ_OFF(e.ident)},
+    {"filter",          FILTER_TYPE,    KQ_OFF(e.filter)},
+    {"flags",           FLAGS_TYPE,     KQ_OFF(e.flags)},
     {"fflags",          T_UINT,         KQ_OFF(e.fflags)},
     {"data",            DATA_TYPE,      KQ_OFF(e.data)},
     {"udata",           T_UINTPTRT,     KQ_OFF(e.udata)},
@@ -1834,9 +1874,9 @@ kqueue_event_repr(kqueue_event_Object *s)
     PyOS_snprintf(
         buf, sizeof(buf),
         "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
-        "data=0x%zd udata=%p>",
-        (size_t)(s->e.ident), s->e.filter, s->e.flags,
-        s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
+        "data=0x%llx udata=%p>",
+        (size_t)(s->e.ident), (int)s->e.filter, (unsigned int)s->e.flags,
+        (unsigned int)s->e.fflags, (long long)(s->e.data), (void *)s->e.udata);
     return PyUnicode_FromString(buf);
 }
 
@@ -1846,7 +1886,9 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
     PyObject *pfd;
     static char *kwlist[] = {"ident", "filter", "flags", "fflags",
                              "data", "udata", NULL};
-    static const char fmt[] = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
+    static const char fmt[] = "O|"
+                FILTER_FMT_UNIT FLAGS_FMT_UNIT FFLAGS_FMT_UNIT DATA_FMT_UNIT
+                UINTPTRT_FMT_UNIT ":kevent";
 
     EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
 
@@ -1856,12 +1898,8 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
         return -1;
     }
 
-    if (PyLong_Check(pfd)
-#if IDENT_TYPE == T_UINT
-        && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
-#endif
-    ) {
-        self->e.ident = IDENT_AsType(pfd);
+    if (PyLong_Check(pfd)) {
+        self->e.ident = PyLong_AsSize_t(pfd);
     }
     else {
         self->e.ident = PyObject_AsFileDescriptor(pfd);
@@ -1876,29 +1914,22 @@ static PyObject *
 kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
                          int op)
 {
-    intptr_t result = 0;
+    int result;
 
     if (!kqueue_event_Check(o)) {
-        if (op == Py_EQ || op == Py_NE) {
-            PyObject *res = op == Py_EQ ? Py_False : Py_True;
-            Py_INCREF(res);
-            return res;
-        }
-        PyErr_Format(PyExc_TypeError,
-            "can't compare %.200s to %.200s",
-            Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
-        return NULL;
-    }
-    if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
-        ((result = s->e.filter - o->e.filter) == 0) &&
-        ((result = s->e.flags - o->e.flags) == 0) &&
-        ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
-        ((result = s->e.data - o->e.data) == 0) &&
-        ((result = s->e.udata - o->e.udata) == 0)
-       ) {
-        result = 0;
+        Py_RETURN_NOTIMPLEMENTED;
     }
 
+#define CMP(a, b) ((a) != (b)) ? ((a) < (b) ? -1 : 1)
+    result = CMP(s->e.ident, o->e.ident)
+           : CMP(s->e.filter, o->e.filter)
+           : CMP(s->e.flags, o->e.flags)
+           : CMP(s->e.fflags, o->e.fflags)
+           : CMP(s->e.data, o->e.data)
+           : CMP((intptr_t)s->e.udata, (intptr_t)o->e.udata)
+           : 0;
+#undef CMP
+
     switch (op) {
     case Py_EQ:
         result = (result == 0);
@@ -2103,7 +2134,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
     int i = 0;
     PyObject *otimeout = NULL;
     PyObject *ch = NULL;
-    PyObject *it = NULL, *ei = NULL;
+    PyObject *seq = NULL, *ei = NULL;
     PyObject *result = NULL;
     struct kevent *evl = NULL;
     struct kevent *chl = NULL;
@@ -2129,7 +2160,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
     }
     else {
         if (_PyTime_FromSecondsObject(&timeout,
-                                      otimeout, _PyTime_ROUND_CEILING) < 0) {
+                                      otimeout, _PyTime_ROUND_TIMEOUT) < 0) {
             PyErr_Format(PyExc_TypeError,
                 "timeout argument must be a number "
                 "or None, got %.200s",
@@ -2149,37 +2180,34 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
     }
 
     if (ch != NULL && ch != Py_None) {
-        it = PyObject_GetIter(ch);
-        if (it == NULL) {
-            PyErr_SetString(PyExc_TypeError,
-                            "changelist is not iterable");
+        seq = PySequence_Fast(ch, "changelist is not iterable");
+        if (seq == NULL) {
             return NULL;
         }
-        nchanges = PyObject_Size(ch);
-        if (nchanges < 0) {
+        if (PySequence_Fast_GET_SIZE(seq) > INT_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "changelist is too long");
             goto error;
         }
+        nchanges = (int)PySequence_Fast_GET_SIZE(seq);
 
         chl = PyMem_New(struct kevent, nchanges);
         if (chl == NULL) {
             PyErr_NoMemory();
             goto error;
         }
-        i = 0;
-        while ((ei = PyIter_Next(it)) != NULL) {
+        for (i = 0; i < nchanges; ++i) {
+            ei = PySequence_Fast_GET_ITEM(seq, i);
             if (!kqueue_event_Check(ei)) {
-                Py_DECREF(ei);
                 PyErr_SetString(PyExc_TypeError,
                     "changelist must be an iterable of "
                     "select.kevent objects");
                 goto error;
-            } else {
-                chl[i++] = ((kqueue_event_Object *)ei)->e;
             }
-            Py_DECREF(ei);
+            chl[i] = ((kqueue_event_Object *)ei)->e;
         }
+        Py_CLEAR(seq);
     }
-    Py_CLEAR(it);
 
     /* event list */
     if (nevents) {
@@ -2247,7 +2275,7 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
     PyMem_Free(chl);
     PyMem_Free(evl);
     Py_XDECREF(result);
-    Py_XDECREF(it);
+    Py_XDECREF(seq);
     return NULL;
 }
 
@@ -2255,7 +2283,7 @@ PyDoc_STRVAR(kqueue_queue_control_doc,
 "control(changelist, max_events[, timeout=None]) -> eventlist\n\
 \n\
 Calls the kernel kevent function.\n\
-- changelist must be a list of kevent objects describing the changes\n\
+- changelist must be an iterable of kevent objects describing the changes\n\
   to be made to the kernel's watch list or None.\n\
 - max_events lets you specify the maximum number of events that the\n\
   kernel will return.\n\
index 0e6099fd361cb5cbbdbb9a4ac4bd06cc4b024f8d..0b9e8f1c23a95eb7f2eb085333cf4453b5a33a3a 100644 (file)
@@ -462,12 +462,15 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
     }
     else
         func = signal_handler;
+    /* Check for pending signals before changing signal handler */
+    if (PyErr_CheckSignals()) {
+        return NULL;
+    }
     if (PyOS_setsig(signalnum, func) == SIG_ERR) {
         PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     old_handler = Handlers[signalnum].func;
-    _Py_atomic_store_relaxed(&Handlers[signalnum].tripped, 0);
     Py_INCREF(handler);
     Handlers[signalnum].func = handler;
     if (old_handler != NULL)
index a351faa7f9fabfffd30b1f0116d8198c68bbbb93..968dad07cd84e4ffca157be23401b96c80411d4c 100644 (file)
@@ -240,7 +240,7 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82&
 # include <ctype.h>
 #endif
 
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__NetBSD__)
 # include <sys/ioctl.h>
 #endif
 
@@ -1250,7 +1250,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
         }
         return ret;
     }
-#endif
+#endif /* ENABLE_IPV6 */
 
 #ifdef USE_BLUETOOTH
     case AF_BLUETOOTH:
@@ -1289,11 +1289,11 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
             struct sockaddr_hci *a = (struct sockaddr_hci *) addr;
 #if defined(__NetBSD__) || defined(__DragonFly__)
             return makebdaddr(&_BT_HCI_MEMB(a, bdaddr));
-#else
+#else /* __NetBSD__ || __DragonFly__ */
             PyObject *ret = NULL;
             ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev));
             return ret;
-#endif
+#endif /* !(__NetBSD__ || __DragonFly__) */
         }
 
 #if !defined(__FreeBSD__)
@@ -1302,20 +1302,20 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
             struct sockaddr_sco *a = (struct sockaddr_sco *) addr;
             return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
         }
-#endif
+#endif /* !__FreeBSD__ */
 
         default:
             PyErr_SetString(PyExc_ValueError,
                             "Unknown Bluetooth protocol");
             return NULL;
         }
-#endif
+#endif /* USE_BLUETOOTH */
 
 #if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFNAME)
     case AF_PACKET:
     {
         struct sockaddr_ll *a = (struct sockaddr_ll *)addr;
-        char *ifname = "";
+        const char *ifname = "";
         struct ifreq ifr;
         /* need to look up interface name give index */
         if (a->sll_ifindex) {
@@ -1331,7 +1331,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
                              a->sll_addr,
                              a->sll_halen);
     }
-#endif
+#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFNAME */
 
 #ifdef HAVE_LINUX_TIPC_H
     case AF_TIPC:
@@ -1364,13 +1364,13 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
             return NULL;
         }
     }
-#endif
+#endif /* HAVE_LINUX_TIPC_H */
 
-#ifdef AF_CAN
+#if defined(AF_CAN) && defined(SIOCGIFNAME)
     case AF_CAN:
     {
         struct sockaddr_can *a = (struct sockaddr_can *)addr;
-        char *ifname = "";
+        const char *ifname = "";
         struct ifreq ifr;
         /* need to look up interface name given index */
         if (a->can_ifindex) {
@@ -1383,7 +1383,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
                                     ifname,
                                     a->can_family);
     }
-#endif
+#endif /* AF_CAN && SIOCGIFNAME */
 
 #ifdef PF_SYSTEM
     case PF_SYSTEM:
@@ -1394,13 +1394,13 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
             struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr;
             return Py_BuildValue("(II)", a->sc_id, a->sc_unit);
         }
-#endif
+#endif /* SYSPROTO_CONTROL */
         default:
             PyErr_SetString(PyExc_ValueError,
                             "Invalid address type");
             return 0;
         }
-#endif
+#endif /* PF_SYSTEM */
 
 #ifdef HAVE_SOCKADDR_ALG
     case AF_ALG:
@@ -1416,7 +1416,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
             a->salg_feat,
             a->salg_mask);
     }
-#endif
+#endif /* HAVE_SOCKADDR_ALG */
 
     /* More cases here... */
 
@@ -1582,12 +1582,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         *len_ret = sizeof(*addr);
         return 1;
     }
-#endif
+#endif /* AF_NETLINK */
 
 #ifdef AF_RDS
     case AF_RDS:
         /* RDS sockets use sockaddr_in: fall-through */
-#endif
+#endif /* AF_RDS */
 
     case AF_INET:
     {
@@ -1669,7 +1669,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         *len_ret = sizeof *addr;
         return 1;
     }
-#endif
+#endif /* ENABLE_IPV6 */
 
 #ifdef USE_BLUETOOTH
     case AF_BLUETOOTH:
@@ -1678,7 +1678,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         case BTPROTO_L2CAP:
         {
             struct sockaddr_l2 *addr;
-            char *straddr;
+            const char *straddr;
 
             addr = (struct sockaddr_l2 *)addr_ret;
             memset(addr, 0, sizeof(struct sockaddr_l2));
@@ -1698,7 +1698,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         case BTPROTO_RFCOMM:
         {
             struct sockaddr_rc *addr;
-            char *straddr;
+            const char *straddr;
 
             addr = (struct sockaddr_rc *)addr_ret;
             _BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
@@ -1718,24 +1718,24 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         {
             struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret;
 #if defined(__NetBSD__) || defined(__DragonFly__)
-                        char *straddr = PyBytes_AS_STRING(args);
-
-                        _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
-            if (straddr == NULL) {
+            const char *straddr;
+            _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
+            if (!PyBytes_Check(args)) {
                 PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                     "wrong format");
                 return 0;
             }
+            straddr = PyBytes_AS_STRING(args);
             if (setbdaddr(straddr, &_BT_HCI_MEMB(addr, bdaddr)) < 0)
                 return 0;
-#else
+#else  /* __NetBSD__ || __DragonFly__ */
             _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
             if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) {
                 PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                                 "wrong format");
                 return 0;
             }
-#endif
+#endif /* !(__NetBSD__ || __DragonFly__) */
             *len_ret = sizeof *addr;
             return 1;
         }
@@ -1743,7 +1743,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         case BTPROTO_SCO:
         {
             struct sockaddr_sco *addr;
-            char *straddr;
+            const char *straddr;
 
             addr = (struct sockaddr_sco *)addr_ret;
             _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
@@ -1759,20 +1759,20 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
             *len_ret = sizeof *addr;
             return 1;
         }
-#endif
+#endif /* !__FreeBSD__ */
         default:
             PyErr_SetString(PyExc_OSError, "getsockaddrarg: unknown Bluetooth protocol");
             return 0;
         }
     }
-#endif
+#endif /* USE_BLUETOOTH */
 
 #if defined(HAVE_NETPACKET_PACKET_H) && defined(SIOCGIFINDEX)
     case AF_PACKET:
     {
         struct sockaddr_ll* addr;
         struct ifreq ifr;
-        char *interfaceName;
+        const char *interfaceName;
         int protoNumber;
         int hatype = 0;
         int pkttype = 0;
@@ -1826,7 +1826,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         PyBuffer_Release(&haddr);
         return 1;
     }
-#endif
+#endif /* HAVE_NETPACKET_PACKET_H && SIOCGIFINDEX */
 
 #ifdef HAVE_LINUX_TIPC_H
     case AF_TIPC:
@@ -1876,9 +1876,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
 
         return 1;
     }
-#endif
+#endif /* HAVE_LINUX_TIPC_H */
 
-#if defined(AF_CAN) && defined(CAN_RAW) && defined(CAN_BCM)
+#if defined(AF_CAN) && defined(CAN_RAW) && defined(CAN_BCM) && defined(SIOCGIFINDEX)
     case AF_CAN:
         switch (s->sock_proto) {
         case CAN_RAW:
@@ -1927,7 +1927,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
                             "getsockaddrarg: unsupported CAN protocol");
             return 0;
         }
-#endif
+#endif /* AF_CAN && CAN_RAW && CAN_BCM && SIOCGIFINDEX */
 
 #ifdef PF_SYSTEM
     case PF_SYSTEM:
@@ -1979,19 +1979,19 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
             *len_ret = sizeof(*addr);
             return 1;
         }
-#endif
+#endif /* SYSPROTO_CONTROL */
         default:
             PyErr_SetString(PyExc_OSError,
                             "getsockaddrarg: unsupported PF_SYSTEM protocol");
             return 0;
         }
-#endif
+#endif /* PF_SYSTEM */
 #ifdef HAVE_SOCKADDR_ALG
     case AF_ALG:
     {
         struct sockaddr_alg *sa;
-        char *type;
-        char *name;
+        const char *type;
+        const char *name;
         sa = (struct sockaddr_alg *)addr_ret;
 
         memset(sa, 0, sizeof(*sa));
@@ -2015,7 +2015,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
         *len_ret = sizeof(*sa);
         return 1;
     }
-#endif
+#endif /* HAVE_SOCKADDR_ALG */
 
     /* More cases here... */
 
@@ -2050,12 +2050,12 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         *len_ret = sizeof (struct sockaddr_nl);
         return 1;
     }
-#endif
+#endif /* AF_NETLINK */
 
 #ifdef AF_RDS
     case AF_RDS:
         /* RDS sockets use sockaddr_in: fall-through */
-#endif
+#endif /* AF_RDS */
 
     case AF_INET:
     {
@@ -2069,7 +2069,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         *len_ret = sizeof (struct sockaddr_in6);
         return 1;
     }
-#endif
+#endif /* ENABLE_IPV6 */
 
 #ifdef USE_BLUETOOTH
     case AF_BLUETOOTH:
@@ -2090,7 +2090,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         case BTPROTO_SCO:
             *len_ret = sizeof (struct sockaddr_sco);
             return 1;
-#endif
+#endif /* !__FreeBSD__ */
         default:
             PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
                             "unknown BT protocol");
@@ -2098,7 +2098,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
 
         }
     }
-#endif
+#endif /* USE_BLUETOOTH */
 
 #ifdef HAVE_NETPACKET_PACKET_H
     case AF_PACKET:
@@ -2106,7 +2106,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         *len_ret = sizeof (struct sockaddr_ll);
         return 1;
     }
-#endif
+#endif /* HAVE_NETPACKET_PACKET_H */
 
 #ifdef HAVE_LINUX_TIPC_H
     case AF_TIPC:
@@ -2114,7 +2114,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         *len_ret = sizeof (struct sockaddr_tipc);
         return 1;
     }
-#endif
+#endif /* HAVE_LINUX_TIPC_H */
 
 #ifdef AF_CAN
     case AF_CAN:
@@ -2122,7 +2122,7 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         *len_ret = sizeof (struct sockaddr_can);
         return 1;
     }
-#endif
+#endif /* AF_CAN */
 
 #ifdef PF_SYSTEM
     case PF_SYSTEM:
@@ -2131,20 +2131,20 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
         case SYSPROTO_CONTROL:
             *len_ret = sizeof (struct sockaddr_ctl);
             return 1;
-#endif
+#endif /* SYSPROTO_CONTROL */
         default:
             PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
                             "unknown PF_SYSTEM protocol");
             return 0;
         }
-#endif
+#endif /* PF_SYSTEM */
 #ifdef HAVE_SOCKADDR_ALG
     case AF_ALG:
     {
         *len_ret = sizeof (struct sockaddr_alg);
         return 1;
     }
-#endif
+#endif /* HAVE_SOCKADDR_ALG */
 
     /* More cases here... */
 
@@ -2454,7 +2454,7 @@ socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj)
     }
 
     if (_PyTime_FromSecondsObject(timeout,
-                                  timeout_obj, _PyTime_ROUND_CEILING) < 0)
+                                  timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
         return -1;
 
     if (*timeout < 0) {
@@ -2463,10 +2463,10 @@ socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj)
     }
 
 #ifdef MS_WINDOWS
-    overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_CEILING) < 0);
+    overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_TIMEOUT) < 0);
 #endif
 #ifndef HAVE_POLL
-    ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_CEILING);
+    ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_TIMEOUT);
     overflow |= (ms > INT_MAX);
 #endif
     if (overflow) {
@@ -5178,7 +5178,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
     int result;
 #endif
 #endif /* HAVE_GETHOSTBYNAME_R */
-    char *ap;
+    const char *ap;
     int al;
     int af;
 
@@ -5250,7 +5250,7 @@ for a host.  The host argument is a string giving a host name or IP number.");
 static PyObject *
 socket_getservbyname(PyObject *self, PyObject *args)
 {
-    char *name, *proto=NULL;
+    const char *name, *proto=NULL;
     struct servent *sp;
     if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto))
         return NULL;
@@ -5281,7 +5281,7 @@ static PyObject *
 socket_getservbyport(PyObject *self, PyObject *args)
 {
     int port;
-    char *proto=NULL;
+    const char *proto=NULL;
     struct servent *sp;
     if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto))
         return NULL;
@@ -5316,7 +5316,7 @@ otherwise any protocol will match.");
 static PyObject *
 socket_getprotobyname(PyObject *self, PyObject *args)
 {
-    char *name;
+    const char *name;
     struct protoent *sp;
     if (!PyArg_ParseTuple(args, "s:getprotobyname", &name))
         return NULL;
@@ -5614,7 +5614,7 @@ socket_inet_aton(PyObject *self, PyObject *args)
     /* Have to use inet_addr() instead */
     unsigned int packed_addr;
 #endif
-    char *ip_addr;
+    const char *ip_addr;
 
     if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr))
         return NULL;
@@ -5709,7 +5709,7 @@ static PyObject *
 socket_inet_pton(PyObject *self, PyObject *args)
 {
     int af;
-    char* ip;
+    const char* ip;
     int retval;
 #ifdef ENABLE_IPV6
     char packed[Py_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
@@ -6046,7 +6046,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
 {
     PyObject *sa = (PyObject *)NULL;
     int flags;
-    char *hostp;
+    const char *hostp;
     int port;
     unsigned int flowinfo, scope_id;
     char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
index 03f982b91083f3d7220c2c754ba99a23fd02445d..af7c36a71104bb9af469e9b9d76c81c7718bc67b 100644 (file)
@@ -80,7 +80,10 @@ typedef int socklen_t;
 #endif
 
 #ifdef HAVE_LINUX_CAN_H
-#include <linux/can.h>
+# include <linux/can.h>
+#else
+# undef AF_CAN
+# undef PF_CAN
 #endif
 
 #ifdef HAVE_LINUX_CAN_RAW_H
index d6c34b9225c1b9dabe728159f6caa99bafa75909..dba3d0452acbb0c92878ad6afdb8601da0bb85a9 100644 (file)
@@ -225,7 +225,7 @@ static PyObject *
 time_sleep(PyObject *self, PyObject *obj)
 {
     _PyTime_t secs;
-    if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_CEILING))
+    if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT))
         return NULL;
     if (secs < 0) {
         PyErr_SetString(PyExc_ValueError,
@@ -1316,28 +1316,7 @@ The tuple items are:\n\
   DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
 If the DST flag is 0, the time is given in the regular time zone;\n\
 if it is 1, the time is given in the DST time zone;\n\
-if it is -1, mktime() should guess based on the date and time.\n\
-\n\
-Variables:\n\
-\n\
-timezone -- difference in seconds between UTC and local standard time\n\
-altzone -- difference in  seconds between UTC and local DST time\n\
-daylight -- whether local time should reflect DST\n\
-tzname -- tuple of (standard time zone name, DST time zone name)\n\
-\n\
-Functions:\n\
-\n\
-time() -- return current time in seconds since the Epoch as a float\n\
-clock() -- return CPU time since process start as a float\n\
-sleep() -- delay for a number of seconds given as a float\n\
-gmtime() -- convert seconds since Epoch to UTC tuple\n\
-localtime() -- convert seconds since Epoch to local time tuple\n\
-asctime() -- convert time tuple to string\n\
-ctime() -- convert time in seconds to string\n\
-mktime() -- convert local time tuple to seconds since Epoch\n\
-strftime() -- convert time tuple to string according to format specification\n\
-strptime() -- parse string to time tuple according to format specification\n\
-tzset() -- change the local timezone");
+if it is -1, mktime() should guess based on the date and time.\n");
 
 
 
index cfe7f88dc540ecb1edb4aa6b145af5075efa7dce..29f55bdb19c6d5a92bd291d1a6137434f55867a4 100644 (file)
@@ -1149,9 +1149,7 @@ static PyMethodDef comp_methods[] =
 {
     ZLIB_COMPRESS_COMPRESS_METHODDEF
     ZLIB_COMPRESS_FLUSH_METHODDEF
-#ifdef HAVE_ZLIB_COPY
     ZLIB_COMPRESS_COPY_METHODDEF
-#endif
     {NULL, NULL}
 };
 
@@ -1159,9 +1157,7 @@ static PyMethodDef Decomp_methods[] =
 {
     ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF
     ZLIB_DECOMPRESS_FLUSH_METHODDEF
-#ifdef HAVE_ZLIB_COPY
     ZLIB_DECOMPRESS_COPY_METHODDEF
-#endif
     {NULL, NULL}
 };
 
index a9c8ca6f1f35a83703fd17c60a244c65753833c0..15524572929c6aef5be81ea9a589fd6e419c989a 100644 (file)
@@ -102,6 +102,26 @@ PyByteArray_FromObject(PyObject *input)
                                         input, NULL);
 }
 
+static PyObject *
+_PyByteArray_FromBufferObject(PyObject *obj)
+{
+    PyObject *result;
+    Py_buffer view;
+
+    if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
+        return NULL;
+    }
+    result = PyByteArray_FromStringAndSize(NULL, view.len);
+    if (result != NULL &&
+        PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
+                              &view, view.len, 'C') < 0)
+    {
+        Py_CLEAR(result);
+    }
+    PyBuffer_Release(&view);
+    return result;
+}
+
 PyObject *
 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
 {
@@ -224,7 +244,7 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
             return -1;
         }
         memcpy(sval, PyByteArray_AS_STRING(self),
-               Py_MIN(requested_size, Py_SIZE(self)));
+               Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
         PyObject_Free(obj->ob_bytes);
     }
     else {
@@ -534,7 +554,8 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
     if (values == (PyObject *)self) {
         /* Make a copy and call this function recursively */
         int err;
-        values = PyByteArray_FromObject(values);
+        values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
+                                               PyByteArray_GET_SIZE(values));
         if (values == NULL)
             return -1;
         err = bytearray_setslice(self, lo, hi, values);
@@ -1381,19 +1402,19 @@ Partition the bytearray into three parts using the given separator.
 
 This will search for the separator sep in the bytearray. If the separator is
 found, returns a 3-tuple containing the part before the separator, the
-separator itself, and the part after it.
+separator itself, and the part after it as new bytearray objects.
 
-If the separator is not found, returns a 3-tuple containing the original
-bytearray object and two empty bytearray objects.
+If the separator is not found, returns a 3-tuple containing the copy of the
+original bytearray object and two empty bytearray objects.
 [clinic start generated code]*/
 
 static PyObject *
 bytearray_partition(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=45d2525ddd35f957 input=86f89223892b70b5]*/
+/*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
 {
     PyObject *bytesep, *result;
 
-    bytesep = PyByteArray_FromObject(sep);
+    bytesep = _PyByteArray_FromBufferObject(sep);
     if (! bytesep)
         return NULL;
 
@@ -1414,23 +1435,24 @@ bytearray.rpartition
     sep: object
     /
 
-Partition the bytes into three parts using the given separator.
+Partition the bytearray into three parts using the given separator.
 
-This will search for the separator sep in the bytearray, starting and the end.
+This will search for the separator sep in the bytearray, starting at the end.
 If the separator is found, returns a 3-tuple containing the part before the
-separator, the separator itself, and the part after it.
+separator, the separator itself, and the part after it as new bytearray
+objects.
 
 If the separator is not found, returns a 3-tuple containing two empty bytearray
-objects and the original bytearray object.
+objects and the copy of the original bytearray object.
 [clinic start generated code]*/
 
 static PyObject *
 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=440de3c9426115e8 input=5f4094f2de87c8f3]*/
+/*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
 {
     PyObject *bytesep, *result;
 
-    bytesep = PyByteArray_FromObject(sep);
+    bytesep = _PyByteArray_FromBufferObject(sep);
     if (! bytesep)
         return NULL;
 
index 4c55294d9d8c8a1e6c56396f760bcaf84b5dca13..4950d01a6e4907349ede0a70ad137c5635b6f5b3 100644 (file)
@@ -1255,7 +1255,7 @@ PyObject *PyBytes_DecodeEscape(const char *s,
     if (first_invalid_escape != NULL) {
         if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                              "invalid escape sequence '\\%c'",
-                             *first_invalid_escape) < 0) {
+                             (unsigned char)*first_invalid_escape) < 0) {
             Py_DECREF(result);
             return NULL;
         }
@@ -1832,7 +1832,7 @@ bytes.rpartition
 
 Partition the bytes into three parts using the given separator.
 
-This will search for the separator sep in the bytes, starting and the end. If
+This will search for the separator sep in the bytes, starting at the end. If
 the separator is found, returns a 3-tuple containing the part before the
 separator, the separator itself, and the part after it.
 
@@ -1842,7 +1842,7 @@ objects and the original bytes object.
 
 static PyObject *
 bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep)
-/*[clinic end generated code: output=191b114cbb028e50 input=67f689e63a62d478]*/
+/*[clinic end generated code: output=191b114cbb028e50 input=d78db010c8cfdbe1]*/
 {
     return stringlib_rpartition(
         (PyObject*) self,
index c75acb75cf8225fad8f62c8c2e44a3564ebc348c..c164c79f626f572027a833ab40239af9f23bf118 100644 (file)
@@ -214,10 +214,10 @@ PyDoc_STRVAR(bytearray_partition__doc__,
 "\n"
 "This will search for the separator sep in the bytearray. If the separator is\n"
 "found, returns a 3-tuple containing the part before the separator, the\n"
-"separator itself, and the part after it.\n"
+"separator itself, and the part after it as new bytearray objects.\n"
 "\n"
-"If the separator is not found, returns a 3-tuple containing the original\n"
-"bytearray object and two empty bytearray objects.");
+"If the separator is not found, returns a 3-tuple containing the copy of the\n"
+"original bytearray object and two empty bytearray objects.");
 
 #define BYTEARRAY_PARTITION_METHODDEF    \
     {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
@@ -226,14 +226,15 @@ PyDoc_STRVAR(bytearray_rpartition__doc__,
 "rpartition($self, sep, /)\n"
 "--\n"
 "\n"
-"Partition the bytes into three parts using the given separator.\n"
+"Partition the bytearray into three parts using the given separator.\n"
 "\n"
-"This will search for the separator sep in the bytearray, starting and the end.\n"
+"This will search for the separator sep in the bytearray, starting at the end.\n"
 "If the separator is found, returns a 3-tuple containing the part before the\n"
-"separator, the separator itself, and the part after it.\n"
+"separator, the separator itself, and the part after it as new bytearray\n"
+"objects.\n"
 "\n"
 "If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
-"objects and the original bytearray object.");
+"objects and the copy of the original bytearray object.");
 
 #define BYTEARRAY_RPARTITION_METHODDEF    \
     {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
@@ -711,4 +712,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
 {
     return bytearray_sizeof_impl(self);
 }
-/*[clinic end generated code: output=225342a680391b9c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8f022100f059226c input=a9049054013a1b77]*/
index a11ebd277496371fa94259b33e608fcadbf102ff..191de20f517b001355767fccde50952beadd0109 100644 (file)
@@ -86,7 +86,7 @@ PyDoc_STRVAR(bytes_rpartition__doc__,
 "\n"
 "Partition the bytes into three parts using the given separator.\n"
 "\n"
-"This will search for the separator sep in the bytes, starting and the end. If\n"
+"This will search for the separator sep in the bytes, starting at the end. If\n"
 "the separator is found, returns a 3-tuple containing the part before the\n"
 "separator, the separator itself, and the part after it.\n"
 "\n"
@@ -499,4 +499,4 @@ bytes_fromhex(PyTypeObject *type, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=2dc3c93cfd2dc440 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4ac7e35150d47467 input=a9049054013a1b77]*/
index d45be4c96796e6de7547cbfffdb8a61f7b10a018..d1c3abf486158a0ee3d8b9e5f53437257dce7e53 100644 (file)
@@ -136,12 +136,20 @@ PyCode_New(int argcount, int kwonlyargcount,
     if (PyUnicode_READY(filename) < 0)
         return NULL;
 
-    n_cellvars = PyTuple_GET_SIZE(cellvars);
     intern_strings(names);
     intern_strings(varnames);
     intern_strings(freevars);
     intern_strings(cellvars);
     intern_string_constants(consts);
+
+    /* Check for any inner or outer closure references */
+    n_cellvars = PyTuple_GET_SIZE(cellvars);
+    if (!n_cellvars && !PyTuple_GET_SIZE(freevars)) {
+        flags |= CO_NOFREE;
+    } else {
+        flags &= ~CO_NOFREE;
+    }
+
     /* Create mapping between cells and arguments if needed. */
     if (n_cellvars) {
         Py_ssize_t total_args = argcount + kwonlyargcount +
index dae166d5adf4687f1b68de68280ad0b9748fccf2..b92b8987fbb0cdc690847b20e868f9e813b5020d 100644 (file)
@@ -87,19 +87,25 @@ enum_next_long(enumobject *en, PyObject* next_item)
 
     if (en->en_longindex == NULL) {
         en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
-        if (en->en_longindex == NULL)
+        if (en->en_longindex == NULL) {
+            Py_DECREF(next_item);
             return NULL;
+        }
     }
     if (one == NULL) {
         one = PyLong_FromLong(1);
-        if (one == NULL)
+        if (one == NULL) {
+            Py_DECREF(next_item);
             return NULL;
+        }
     }
     next_index = en->en_longindex;
     assert(next_index != NULL);
     stepped_up = PyNumber_Add(next_index, one);
-    if (stepped_up == NULL)
+    if (stepped_up == NULL) {
+        Py_DECREF(next_item);
         return NULL;
+    }
     en->en_longindex = stepped_up;
 
     if (result->ob_refcnt == 1) {
index 271e293e325e885a6a6def4c77b4a239daec3583..df4899372a560b7cc5963f62be3ad24a4ebbaec4 100644 (file)
@@ -2430,12 +2430,6 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
 
 
 
-/* Pre-computed RecursionError instance for when recursion depth is reached.
-   Meant to be used when normalizing the exception for exceeding the recursion
-   depth will cause its own infinite recursion.
-*/
-PyObject *PyExc_RecursionErrorInst = NULL;
-
 #define PRE_INIT(TYPE) \
     if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
         if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
@@ -2697,37 +2691,11 @@ _PyExc_Init(PyObject *bltinmod)
     ADD_ERRNO(TimeoutError, ETIMEDOUT);
 
     preallocate_memerrors();
-
-    if (!PyExc_RecursionErrorInst) {
-        PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RecursionError, NULL, NULL);
-        if (!PyExc_RecursionErrorInst)
-            Py_FatalError("Cannot pre-allocate RecursionError instance for "
-                            "recursion errors");
-        else {
-            PyBaseExceptionObject *err_inst =
-                (PyBaseExceptionObject *)PyExc_RecursionErrorInst;
-            PyObject *args_tuple;
-            PyObject *exc_message;
-            exc_message = PyUnicode_FromString("maximum recursion depth exceeded");
-            if (!exc_message)
-                Py_FatalError("cannot allocate argument for RecursionError "
-                                "pre-allocation");
-            args_tuple = PyTuple_Pack(1, exc_message);
-            if (!args_tuple)
-                Py_FatalError("cannot allocate tuple for RecursionError "
-                                "pre-allocation");
-            Py_DECREF(exc_message);
-            if (BaseException_init(err_inst, args_tuple, NULL))
-                Py_FatalError("init of pre-allocated RecursionError failed");
-            Py_DECREF(args_tuple);
-        }
-    }
 }
 
 void
 _PyExc_Fini(void)
 {
-    Py_CLEAR(PyExc_RecursionErrorInst);
     free_preallocated_memerrors();
     Py_CLEAR(errnomap);
 }
index ad239ce84e237ab4b0a2adee3b1368ec2b542978..c3c0949189d85106d29aa581ce9a1a733f3a8158 100644 (file)
@@ -2016,7 +2016,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res)
     const char *p = *str;
     const char *start = p;
     char prev = 0;
-    int digits = 0;
+    Py_ssize_t digits = 0;
     int bits_per_char;
     Py_ssize_t n;
     PyLongObject *z;
@@ -2049,15 +2049,15 @@ long_from_binary_base(const char **str, int base, PyLongObject **res)
     }
 
     *str = p;
-    /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
-    n = digits * bits_per_char + PyLong_SHIFT - 1;
-    if (n / bits_per_char < p - start) {
+    /* n <- the number of Python digits needed,
+            = ceiling((digits * bits_per_char) / PyLong_SHIFT). */
+    if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) {
         PyErr_SetString(PyExc_ValueError,
                         "int string too large to convert");
         *res = NULL;
         return 0;
     }
-    n = n / PyLong_SHIFT;
+    n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT;
     z = _PyLong_New(n);
     if (z == NULL) {
         *res = NULL;
@@ -2259,8 +2259,9 @@ just 1 digit at the start, so that the copying code was exercised for every
 digit beyond the first.
 ***/
         twodigits c;           /* current input character */
+        double fsize_z;
         Py_ssize_t size_z;
-        int digits = 0;
+        Py_ssize_t digits = 0;
         int i;
         int convwidth;
         twodigits convmultmax, convmult;
@@ -2322,7 +2323,14 @@ digit beyond the first.
          * need to initialize z->ob_digit -- no slot is read up before
          * being stored into.
          */
-        size_z = (Py_ssize_t)(digits * log_base_BASE[base]) + 1;
+        fsize_z = digits * log_base_BASE[base] + 1;
+        if (fsize_z > MAX_LONG_DIGITS) {
+            /* The same exception as in _PyLong_New(). */
+            PyErr_SetString(PyExc_OverflowError,
+                            "too many digits in integer");
+            return NULL;
+        }
+        size_z = (Py_ssize_t)fsize_z;
         /* Uncomment next line to test exceedingly rare copy code */
         /* size_z = 1; */
         assert(size_z > 0);
@@ -4820,7 +4828,7 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return NULL;
     if ((base != 0 && base < 2) || base > 36) {
         PyErr_SetString(PyExc_ValueError,
-                        "int() base must be >= 2 and <= 36");
+                        "int() base must be >= 2 and <= 36, or 0");
         return NULL;
     }
 
index 79be51a806b707233aed5d98ddef675feb38d05b..f357af2b2118f65b03eabb35881fc4decb057689 100644 (file)
@@ -667,14 +667,11 @@ module_getattro(PyModuleObject *m, PyObject *name)
     if (m->md_dict) {
         _Py_IDENTIFIER(__name__);
         mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__);
-        if (mod_name) {
+        if (mod_name && PyUnicode_Check(mod_name)) {
             PyErr_Format(PyExc_AttributeError,
                         "module '%U' has no attribute '%U'", mod_name, name);
             return NULL;
         }
-        else if (PyErr_Occurred()) {
-            PyErr_Clear();
-        }
     }
     PyErr_Format(PyExc_AttributeError,
                 "module has no attribute '%U'", name);
index 0bb30638445a93b96b30f9865fb5979b0a0fcd88..d28c9133b4b700b56fb1a03d4a03d085e473eb9d 100644 (file)
@@ -50,8 +50,12 @@ namespace_init(_PyNamespaceObject *ns, PyObject *args, PyObject *kwds)
             return -1;
         }
     }
-    if (kwds == NULL)
+    if (kwds == NULL) {
         return 0;
+    }
+    if (!PyArg_ValidateKeywordArguments(kwds)) {
+        return -1;
+    }
     return PyDict_Update(ns->ns_dict, kwds);
 }
 
index 32e7ecbe1e0436867cca5262abd3e12c8f72f23a..38f267e347fcd3b9fee2271cf65b1dabcf95707b 100644 (file)
@@ -1914,7 +1914,7 @@ static void *
 _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
 {
     debug_alloc_api_t *api = (debug_alloc_api_t *)ctx;
-    uint8_t *q = (uint8_t *)p, *oldq;
+    uint8_t *q = (uint8_t *)p;
     uint8_t *tail;
     size_t total;       /* nbytes + 4*SST */
     size_t original_nbytes;
@@ -1931,20 +1931,11 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
         /* overflow:  can't represent total as a Py_ssize_t */
         return NULL;
 
-    /* Resize and add decorations. We may get a new pointer here, in which
-     * case we didn't get the chance to mark the old memory with DEADBYTE,
-     * but we live with that.
-     */
-    oldq = q;
+    /* Resize and add decorations. */
     q = (uint8_t *)api->alloc.realloc(api->alloc.ctx, q - 2*SST, total);
     if (q == NULL)
         return NULL;
 
-    if (q == oldq && nbytes < original_nbytes) {
-        /* shrinking:  mark old extra memory dead */
-        memset(q + nbytes, DEADBYTE, original_nbytes - nbytes);
-    }
-
     write_size_t(q, nbytes);
     assert(q[SST] == (uint8_t)api->api_id);
     for (i = 1; i < SST; ++i)
index e9fc6580383dde518807a30f3e342850e633bd36..64905e84b149c9d1c393afa99c8a049d960d14bf 100644 (file)
@@ -6174,7 +6174,7 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
     if (first_invalid_escape != NULL) {
         if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                              "invalid escape sequence '\\%c'",
-                             *first_invalid_escape) < 0) {
+                             (unsigned char)*first_invalid_escape) < 0) {
             Py_DECREF(result);
             return NULL;
         }
index 15aa7d8fecf32455abbb55129ab1925e66532c5e..a7c8fa3d092a6437a1d0c760c7b503c548ca226b 100644 (file)
--- a/PC/_msi.c
+++ b/PC/_msi.c
@@ -284,6 +284,7 @@ msiobj_dealloc(msiobj* msidb)
 {
     MsiCloseHandle(msidb->h);
     msidb->h = 0;
+    PyObject_Del(msidb);
 }
 
 static PyObject*
@@ -324,6 +325,12 @@ msierror(int status)
         case ERROR_INVALID_PARAMETER:
             PyErr_SetString(MSIError, "invalid parameter");
             return NULL;
+        case ERROR_OPEN_FAILED:
+            PyErr_SetString(MSIError, "open failed");
+            return NULL;
+        case ERROR_CREATE_FAILED:
+            PyErr_SetString(MSIError, "create failed");
+            return NULL;
         default:
             PyErr_Format(MSIError, "unknown error %x", status);
             return NULL;
@@ -571,6 +578,8 @@ summary_getproperty(msiobj* si, PyObject *args)
             if (sval != sbuf)
                 free(sval);
             return result;
+        case VT_EMPTY:
+            Py_RETURN_NONE;
     }
     PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
     return NULL;
@@ -728,8 +737,12 @@ view_fetch(msiobj *view, PyObject*args)
     int status;
     MSIHANDLE result;
 
-    if ((status = MsiViewFetch(view->h, &result)) != ERROR_SUCCESS)
+    status = MsiViewFetch(view->h, &result);
+    if (status == ERROR_NO_MORE_ITEMS) {
+        Py_RETURN_NONE;
+    } else if (status != ERROR_SUCCESS) {
         return msierror(status);
+    }
 
     return record_new(result);
 }
index 1c93679e43542269422556bebc1d8b0a5b987fbf..23d1286ed4f49805da6325c93110af64dbe4d4b8 100644 (file)
@@ -46,7 +46,7 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file,
 /*[clinic end generated code: output=48f9563db34aedb3 input=4c774f2d05770bc6]*/
 {
     INPUT_RECORD *rec = NULL;
-    
+
     if (!PyWindowsConsoleIO_Check(file)) {
         PyErr_SetString(PyExc_TypeError, "expected raw console object");
         return NULL;
@@ -59,7 +59,7 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file,
     if (!rec)
         goto error;
     memset(rec, 0, sizeof(INPUT_RECORD) * size);
-    
+
     INPUT_RECORD *prec = rec;
     for (DWORD i = 0; i < size; ++i, ++p, ++prec) {
         prec->EventType = KEY_EVENT;
@@ -80,7 +80,7 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file,
     }
 
     PyMem_Free((void*)rec);
-    
+
     Py_RETURN_NONE;
 error:
     if (rec)
index 4797cdc2c05325595d6c8395886182f23581f251..b1bf28b1edb12dda8fa12832f5c4fc0a57d83fde 100644 (file)
@@ -353,7 +353,7 @@ msvcrt_ungetch_impl(PyObject *module, char char_value)
 /*[clinic end generated code: output=c6942a0efa119000 input=22f07ee9001bbf0f]*/
 {
     int res;
-    
+
     _Py_BEGIN_SUPPRESS_IPH
     res = _ungetch(char_value);
     _Py_END_SUPPRESS_IPH
index ff70718fc3755f0b5bbcd9cd888d30cd13e9094c..4fc4a6814ee1ad9f463c5ce1bdb05279b0c9ef66 100644 (file)
@@ -224,7 +224,6 @@ EXPORTS
   PyExc_PermissionError=python36.PyExc_PermissionError DATA
   PyExc_ProcessLookupError=python36.PyExc_ProcessLookupError DATA
   PyExc_RecursionError=python36.PyExc_RecursionError DATA
-  PyExc_RecursionErrorInst=python36.PyExc_RecursionErrorInst DATA
   PyExc_ReferenceError=python36.PyExc_ReferenceError DATA
   PyExc_ResourceWarning=python36.PyExc_ResourceWarning DATA
   PyExc_RuntimeError=python36.PyExc_RuntimeError DATA
index 78517d225f9f449680a4e5724dfdc57407912678..6c0a1a0f04dfdbbe880b0c221772835df441e202 100644 (file)
@@ -2,4 +2,4 @@
 rem A batch program to clean a particular configuration,\r
 rem just for convenience.\r
 \r
-call %~dp0build.bat -t Clean %*\r
+call "%~dp0build.bat" -t Clean %*\r
index 8fde64dd53c0524a6bea4729ab83700a5904472b..664243647d0f84c73a6069e7bb0f4b25d9c737b4 100644 (file)
@@ -42,7 +42,7 @@ echo.Fetching external libraries...
 set libraries=\r
 set libraries=%libraries%                                    bzip2-1.0.6\r
 if NOT "%IncludeSSL%"=="false" set libraries=%libraries%     openssl-1.0.2k\r
-set libraries=%libraries%                                    sqlite-3.14.2.0\r
+set libraries=%libraries%                                    sqlite-3.21.0.0\r
 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.6.0\r
 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.6.0\r
 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tix-8.4.3.6\r
index fdd82028d0f7673d1c10205b73ec18b6539d2207..20538c19111f84ec644d961a82b37fbe5411dbc0 100644 (file)
@@ -6,7 +6,8 @@
     <OutDir>$(BuildPath)</OutDir>\r
     <OutDir Condition="!HasTrailingSlash($(OutDir))">$(OutDir)\</OutDir>\r
     <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(MSBuildThisFileDirectory)obj\</Py_IntDir>\r
-    <IntDir>$(Py_IntDir)\$(ArchName)_$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir>\r
     <TargetName Condition="'$(TargetName)' == ''">$(ProjectName)</TargetName>\r
     <TargetName>$(TargetName)$(PyDebugExt)</TargetName>\r
     <GenerateManifest>false</GenerateManifest>\r
index 2beb5968c12106740abe8ef69b283b3e7a00529a..3251b180569f364117ec6ff82cf41aa9ced7f16a 100644 (file)
@@ -44,7 +44,7 @@
     \r
     <!-- Directories of external projects. tcltk is handled in tcltk.props -->\r
     <ExternalsDir>$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals\`))</ExternalsDir>\r
-    <sqlite3Dir>$(ExternalsDir)sqlite-3.14.2.0\</sqlite3Dir>\r
+    <sqlite3Dir>$(ExternalsDir)sqlite-3.21.0.0\</sqlite3Dir>\r
     <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>\r
     <lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>\r
     <opensslDir>$(ExternalsDir)openssl-1.0.2k\</opensslDir>\r
     possible version). Since we limit WINVER to Windows 7 anyway, it doesn't really\r
     matter which WinSDK version we use.\r
     -->\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.15063'">10.0.15063.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.15063'">10.0.15063.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.14393'">10.0.14393.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.14393'">10.0.14393.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.10586'">10.0.10586.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.10586'">10.0.10586.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.10240'">10.0.10240.0</DefaultWindowsSDKVersion>\r
-    <DefaultWindowsSDKVersion Condition="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion) == '10.0.10240'">10.0.10240.0</DefaultWindowsSDKVersion>\r
+    <_RegistryVersion>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion>\r
+    <_RegistryVersion Condition="$(_RegistryVersion) == ''">$(Registry:HKEY_LOCAL_MACHINE\WOW6432Node\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion>\r
+    <DefaultWindowsSDKVersion>10.0.15063.0</DefaultWindowsSDKVersion>\r
+    <DefaultWindowsSDKVersion Condition="$(_RegistryVersion) == '10.0.14393'">10.0.14393.0</DefaultWindowsSDKVersion>\r
+    <DefaultWindowsSDKVersion Condition="$(_RegistryVersion) == '10.0.10586'">10.0.10586.0</DefaultWindowsSDKVersion>\r
+    <DefaultWindowsSDKVersion Condition="$(_RegistryVersion) == '10.0.10240'">10.0.10240.0</DefaultWindowsSDKVersion>\r
   </PropertyGroup>\r
 \r
   <PropertyGroup Condition="'$(OverrideVersion)' == ''">\r
index b873ce09bb5c4f3df3d4cc783a790791ef551d1e..5fed7aa4545a900e42a33005855a2a06d239348a 100644 (file)
@@ -32,13 +32,20 @@ Visual Studio Premium 2015
     Required for building Release configuration builds that make use of\r
     Profile Guided Optimization (PGO), on either platform.\r
 \r
-All you need to do to build is open the solution "pcbuild.sln" in Visual\r
-Studio, select the desired combination of configuration and platform,\r
+To build modules that depend on external libraries, you need to download\r
+(and, for some of them, build) those first. It's thus recommended to build\r
+from the command line once as specified below under "Getting External Sources"\r
+as that does this automatically.\r
+\r
+Then, to continue development, you can open the solution "pcbuild.sln" in\r
+Visual Studio, select the desired combination of configuration and platform,\r
 then build with "Build Solution".  You can also build from the command\r
 line using the "build.bat" script in this directory; see below for\r
 details.  The solution is configured to build the projects in the correct\r
 order.\r
 \r
+To build an installer package, refer to the README in the Tools/msi folder.\r
+\r
 The solution currently supports two platforms.  The Win32 platform is\r
 used to build standard x86-compatible 32-bit binaries, output into the\r
 win32 sub-directory.  The x64 platform is used for building 64-bit AMD64\r
@@ -205,7 +212,7 @@ _ssl
     functionality to _ssl or _hashlib. They will not clean up their output\r
     with the normal Clean target; CleanAll should be used instead.\r
 _sqlite3\r
-    Wraps SQLite 3.14.2.0, which is itself built by sqlite3.vcxproj\r
+    Wraps SQLite 3.21.0.0, which is itself built by sqlite3.vcxproj\r
     Homepage:\r
         http://www.sqlite.org/\r
 _tkinter\r
index 1e5f4d9a2a59188c92fd5ad56b5981464c3b5557..6302af6fa3e3378a32b67c82875e842ed025681a 100644 (file)
@@ -1281,59 +1281,55 @@ def main(srcfile, dump_module=False):
         print(mod)
     if not asdl.check(mod):
         sys.exit(1)
-    if INC_DIR:
-        p = "%s/%s-ast.h" % (INC_DIR, mod.name)
-        f = open(p, "w")
-        f.write(auto_gen_msg)
-        f.write('#include "asdl.h"\n\n')
-        c = ChainOfVisitors(TypeDefVisitor(f),
-                            StructVisitor(f),
-                            PrototypeVisitor(f),
-                            )
-        c.visit(mod)
-        f.write("PyObject* PyAST_mod2obj(mod_ty t);\n")
-        f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n")
-        f.write("int PyAST_Check(PyObject* obj);\n")
-        f.close()
-
-    if SRC_DIR:
-        p = os.path.join(SRC_DIR, str(mod.name) + "-ast.c")
-        f = open(p, "w")
-        f.write(auto_gen_msg)
-        f.write('#include <stddef.h>\n')
-        f.write('\n')
-        f.write('#include "Python.h"\n')
-        f.write('#include "%s-ast.h"\n' % mod.name)
-        f.write('\n')
-        f.write("static PyTypeObject AST_type;\n")
-        v = ChainOfVisitors(
-            PyTypesDeclareVisitor(f),
-            PyTypesVisitor(f),
-            Obj2ModPrototypeVisitor(f),
-            FunctionVisitor(f),
-            ObjVisitor(f),
-            Obj2ModVisitor(f),
-            ASTModuleVisitor(f),
-            PartingShots(f),
-            )
-        v.visit(mod)
-        f.close()
+    if H_FILE:
+        with open(H_FILE, "w") as f:
+            f.write(auto_gen_msg)
+            f.write('#include "asdl.h"\n\n')
+            c = ChainOfVisitors(TypeDefVisitor(f),
+                                StructVisitor(f),
+                                PrototypeVisitor(f),
+                                )
+            c.visit(mod)
+            f.write("PyObject* PyAST_mod2obj(mod_ty t);\n")
+            f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n")
+            f.write("int PyAST_Check(PyObject* obj);\n")
+
+    if C_FILE:
+        with open(C_FILE, "w") as f:
+            f.write(auto_gen_msg)
+            f.write('#include <stddef.h>\n')
+            f.write('\n')
+            f.write('#include "Python.h"\n')
+            f.write('#include "%s-ast.h"\n' % mod.name)
+            f.write('\n')
+            f.write("static PyTypeObject AST_type;\n")
+            v = ChainOfVisitors(
+                PyTypesDeclareVisitor(f),
+                PyTypesVisitor(f),
+                Obj2ModPrototypeVisitor(f),
+                FunctionVisitor(f),
+                ObjVisitor(f),
+                Obj2ModVisitor(f),
+                ASTModuleVisitor(f),
+                PartingShots(f),
+                )
+            v.visit(mod)
 
 if __name__ == "__main__":
     import getopt
 
-    INC_DIR = ''
-    SRC_DIR = ''
+    H_FILE = ''
+    C_FILE = ''
     dump_module = False
     opts, args = getopt.getopt(sys.argv[1:], "dh:c:")
     for o, v in opts:
         if o == '-h':
-            INC_DIR = v
+            H_FILE = v
         if o == '-c':
-            SRC_DIR = v
+            C_FILE = v
         if o == '-d':
             dump_module = True
-    if INC_DIR and SRC_DIR:
+    if H_FILE and C_FILE:
         print('Must specify exactly one output file')
         sys.exit(1)
     elif len(args) != 1:
index ff65f2a735903c2d6d90391ac772b4ce881d60f0..ab72f6145f28795ed6160603f8b58d1582ec793b 100644 (file)
@@ -1563,6 +1563,9 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
                 /* The current token is 'async'.
                    Look ahead one token.*/
 
+                int async_def_prev = tok->async_def;
+                tok->async_def = 2;
+
                 struct tok_state ahead_tok;
                 char *ahead_tok_start = NULL, *ahead_tok_end = NULL;
                 int ahead_tok_kind;
@@ -1581,6 +1584,9 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
                     tok->async_def = 1;
                     return ASYNC;
                 }
+                else{
+                    tok->async_def = async_def_prev;
+                }
             }
         }
 
@@ -1844,6 +1850,10 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
     /* Line continuation */
     if (c == '\\') {
         c = tok_nextc(tok);
+        if (tok->async_def == 2) {
+            tok->done = E_SYNTAX;
+            return ERRORTOKEN;
+        }
         if (c != '\n') {
             tok->done = E_LINECONT;
             tok->cur = tok->inp;
index 39683993ea06ef25135bc7e84f6b275203cd6a3d..b0f9087115b9adc33b6243f9aa4567ab301bfe2d 100644 (file)
@@ -1,4 +1,5 @@
 #include <Python.h>
+#include "pythread.h"
 #include <stdio.h>
 
 /*********************************************************
@@ -33,7 +34,7 @@ static void print_subinterp(void)
     );
 }
 
-static void test_repeated_init_and_subinterpreters(void)
+static int test_repeated_init_and_subinterpreters(void)
 {
     PyThreadState *mainstate, *substate;
 #ifdef WITH_THREAD
@@ -70,6 +71,7 @@ static void test_repeated_init_and_subinterpreters(void)
         PyEval_RestoreThread(mainstate);
         Py_Finalize();
     }
+    return 0;
 }
 
 /*****************************************************
@@ -103,7 +105,7 @@ static void check_stdio_details(const char *encoding, const char * errors)
     Py_Finalize();
 }
 
-static void test_forced_io_encoding(void)
+static int test_forced_io_encoding(void)
 {
     /* Check various combinations */
     printf("--- Use defaults ---\n");
@@ -122,19 +124,123 @@ static void test_forced_io_encoding(void)
         printf("Unexpected success calling Py_SetStandardStreamEncoding");
     }
     Py_Finalize();
+    return 0;
 }
 
-/* Different embedding tests */
-int main(int argc, char *argv[])
+
+/*********************************************************
+ * Test parts of the C-API that work before initialization
+ *********************************************************/
+
+static int test_pre_initialization_api(void)
 {
+    /* Leading "./" ensures getpath.c can still find the standard library */
+    wchar_t *program = Py_DecodeLocale("./spam", NULL);
+    if (program == NULL) {
+        fprintf(stderr, "Fatal error: cannot decode program name\n");
+        return 1;
+    }
+    Py_SetProgramName(program);
 
-    /* TODO: Check the argument string to allow for more test cases */
-    if (argc > 1) {
-        /* For now: assume "forced_io_encoding */
-        test_forced_io_encoding();
-    } else {
-        /* Run the original embedding test case by default */
-        test_repeated_init_and_subinterpreters();
+    Py_Initialize();
+    Py_Finalize();
+
+    PyMem_RawFree(program);
+    return 0;
+}
+
+static void bpo20891_thread(void *lockp)
+{
+    PyThread_type_lock lock = *((PyThread_type_lock*)lockp);
+
+    PyGILState_STATE state = PyGILState_Ensure();
+    if (!PyGILState_Check()) {
+        fprintf(stderr, "PyGILState_Check failed!");
+        abort();
+    }
+
+    PyGILState_Release(state);
+
+    PyThread_release_lock(lock);
+
+    PyThread_exit_thread();
+}
+
+static int test_bpo20891(void)
+{
+    /* bpo-20891: Calling PyGILState_Ensure in a non-Python thread before
+       calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must
+       call PyEval_InitThreads() for us in this case. */
+    PyThread_type_lock lock = PyThread_allocate_lock();
+    if (!lock) {
+        fprintf(stderr, "PyThread_allocate_lock failed!");
+        return 1;
+    }
+
+    _testembed_Py_Initialize();
+
+    long thrd = PyThread_start_new_thread(bpo20891_thread, &lock);
+    if (thrd == -1) {
+        fprintf(stderr, "PyThread_start_new_thread failed!");
+        return 1;
     }
+    PyThread_acquire_lock(lock, WAIT_LOCK);
+
+    Py_BEGIN_ALLOW_THREADS
+    /* wait until the thread exit */
+    PyThread_acquire_lock(lock, WAIT_LOCK);
+    Py_END_ALLOW_THREADS
+
+    PyThread_free_lock(lock);
+
     return 0;
 }
+
+
+/* *********************************************************
+ * List of test cases and the function that implements it.
+ *
+ * Names are compared case-sensitively with the first
+ * argument. If no match is found, or no first argument was
+ * provided, the names of all test cases are printed and
+ * the exit code will be -1.
+ *
+ * The int returned from test functions is used as the exit
+ * code, and test_capi treats all non-zero exit codes as a
+ * failed test.
+ *********************************************************/
+struct TestCase
+{
+    const char *name;
+    int (*func)(void);
+};
+
+static struct TestCase TestCases[] = {
+    { "forced_io_encoding", test_forced_io_encoding },
+    { "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters },
+    { "pre_initialization_api", test_pre_initialization_api },
+    { "bpo20891", test_bpo20891 },
+    { NULL, NULL }
+};
+
+int main(int argc, char *argv[])
+{
+    if (argc > 1) {
+        for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
+            if (strcmp(argv[1], tc->name) == 0)
+                return (*tc->func)();
+        }
+    }
+
+    /* No match found, or no test name provided, so display usage */
+    printf("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n"
+           "Normally executed via 'EmbeddingTests' in Lib/test/test_capi.py\n\n"
+           "Usage: %s TESTNAME\n\nAll available tests:\n", argv[0]);
+    for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
+        printf("  %s\n", tc->name);
+    }
+
+    /* Non-zero exit code will cause test_capi.py tests to fail.
+       This is intentional. */
+    return -1;
+}
index 7270d2c2ecb15c1f14421bd5aa2aaedf9f7debb4..0077b9b1c3d0c4bed8adfa16685642a80b050d33 100644 (file)
@@ -694,13 +694,14 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
 
     /* Setup module. */
     *module = PyDict_GetItemString(globals, "__name__");
-    if (*module == NULL) {
+    if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) {
+        Py_INCREF(*module);
+    }
+    else {
         *module = PyUnicode_FromString("<string>");
         if (*module == NULL)
             goto handle_error;
     }
-    else
-        Py_INCREF(*module);
 
     /* Setup filename. */
     *filename = PyDict_GetItemString(globals, "__file__");
@@ -864,7 +865,6 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
 
     if (module_globals) {
         _Py_IDENTIFIER(get_source);
-        _Py_IDENTIFIER(splitlines);
         PyObject *tmp;
         PyObject *loader;
         PyObject *module_name;
@@ -875,8 +875,6 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
 
         if ((tmp = _PyUnicode_FromId(&PyId_get_source)) == NULL)
             return NULL;
-        if ((tmp = _PyUnicode_FromId(&PyId_splitlines)) == NULL)
-            return NULL;
 
         /* Check/get the requisite pieces needed for the loader. */
         loader = PyDict_GetItemString(module_globals, "__loader__");
@@ -899,9 +897,7 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
         }
 
         /* Split the source into lines. */
-        source_list = PyObject_CallMethodObjArgs(source,
-                                                 PyId_splitlines.object,
-                                                 NULL);
+        source_list = PyUnicode_Splitlines(source, 0);
         Py_DECREF(source);
         if (!source_list)
             return NULL;
index aa4acc9b2610a7886b806908403b38488b78b7d2..ede7f4fd990ca73e2cd24e88a39ede3a2450e03c 100644 (file)
@@ -589,7 +589,6 @@ struct compiling {
     PyArena *c_arena; /* Arena for allocating memory. */
     PyObject *c_filename; /* filename */
     PyObject *c_normalize; /* Normalization function from unicodedata. */
-    PyObject *c_normalize_args; /* Normalization argument tuple. */
 };
 
 static asdl_seq *seq_for_testlist(struct compiling *, const node *);
@@ -624,12 +623,6 @@ init_normalization(struct compiling *c)
     Py_DECREF(m);
     if (!c->c_normalize)
         return 0;
-    c->c_normalize_args = Py_BuildValue("(sN)", "NFKC", Py_None);
-    if (!c->c_normalize_args) {
-        Py_CLEAR(c->c_normalize);
-        return 0;
-    }
-    PyTuple_SET_ITEM(c->c_normalize_args, 1, NULL);
     return 1;
 }
 
@@ -645,15 +638,29 @@ new_identifier(const char *n, struct compiling *c)
        identifier; if so, normalize to NFKC. */
     if (!PyUnicode_IS_ASCII(id)) {
         PyObject *id2;
+        _Py_IDENTIFIER(NFKC);
         if (!c->c_normalize && !init_normalization(c)) {
             Py_DECREF(id);
             return NULL;
         }
-        PyTuple_SET_ITEM(c->c_normalize_args, 1, id);
-        id2 = PyObject_Call(c->c_normalize, c->c_normalize_args, NULL);
+        PyObject *form = _PyUnicode_FromId(&PyId_NFKC);
+        if (form == NULL) {
+            Py_DECREF(id);
+            return NULL;
+        }
+        PyObject *args[2] = {form, id};
+        id2 = _PyObject_FastCall(c->c_normalize, args, 2);
         Py_DECREF(id);
         if (!id2)
             return NULL;
+        if (!PyUnicode_Check(id2)) {
+            PyErr_Format(PyExc_TypeError,
+                         "unicodedata.normalize() must return a string, not "
+                         "%.200s",
+                         Py_TYPE(id2)->tp_name);
+            Py_DECREF(id2);
+            return NULL;
+        }
         id = id2;
     }
     PyUnicode_InternInPlace(&id);
@@ -773,7 +780,6 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
     /* borrowed reference */
     c.c_filename = filename;
     c.c_normalize = NULL;
-    c.c_normalize_args = NULL;
 
     if (TYPE(n) == encoding_decl)
         n = CHILD(n, 0);
@@ -866,8 +872,6 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
  out:
     if (c.c_normalize) {
         Py_DECREF(c.c_normalize);
-        PyTuple_SET_ITEM(c.c_normalize_args, 1, NULL);
-        Py_DECREF(c.c_normalize_args);
     }
     return res;
 }
@@ -4123,7 +4127,7 @@ decode_utf8(struct compiling *c, const char **sPtr, const char *end)
 
 static int
 warn_invalid_escape_sequence(struct compiling *c, const node *n,
-                             char first_invalid_escape_char)
+                             unsigned char first_invalid_escape_char)
 {
     PyObject *msg = PyUnicode_FromFormat("invalid escape sequence \\%c",
                                          first_invalid_escape_char);
@@ -4132,18 +4136,19 @@ warn_invalid_escape_sequence(struct compiling *c, const node *n,
     }
     if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
                                    c->c_filename, LINENO(n),
-                                   NULL, NULL) < 0 &&
-        PyErr_ExceptionMatches(PyExc_DeprecationWarning))
+                                   NULL, NULL) < 0)
     {
-        const char *s;
+        if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
+            const char *s;
 
-        /* Replace the DeprecationWarning exception with a SyntaxError
-           to get a more accurate error report */
-        PyErr_Clear();
+            /* Replace the DeprecationWarning exception with a SyntaxError
+               to get a more accurate error report */
+            PyErr_Clear();
 
-        s = PyUnicode_AsUTF8(msg);
-        if (s != NULL) {
-            ast_error(c, n, s);
+            s = PyUnicode_AsUTF8(msg);
+            if (s != NULL) {
+                ast_error(c, n, s);
+            }
         }
         Py_DECREF(msg);
         return -1;
index 911e2ba79ef7304a23b613299e03ec6057c2ff00..1960a095b8d3ff9ae8d90d794e94d4a09bf3b259 100644 (file)
@@ -167,6 +167,13 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
         Py_DECREF(bases);
         return NULL;
     }
+    if (!PyMapping_Check(ns)) {
+        PyErr_Format(PyExc_TypeError,
+                     "%.200s.__prepare__() must return a mapping, not %.200s",
+                     isclass ? ((PyTypeObject *)meta)->tp_name : "<metaclass>",
+                     Py_TYPE(ns)->tp_name);
+        goto error;
+    }
     cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
                              NULL, 0, NULL, 0, NULL, 0, NULL,
                              PyFunction_GET_CLOSURE(func));
index b6ad444e70be2254b68ba592638571ae61482412..9ad582b15c572f8e30716214d6477db990cdfc8b 100644 (file)
@@ -5254,6 +5254,10 @@ import_from(PyObject *v, PyObject *name)
     if (pkgname == NULL) {
         goto error;
     }
+    if (!PyUnicode_Check(pkgname)) {
+        Py_CLEAR(pkgname);
+        goto error;
+    }
     fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name);
     Py_DECREF(pkgname);
     if (fullmodname == NULL) {
index 797a1840e6a7f23e3a9c076c684aec8a2d8239aa..4d525a02c817744e4d1332df94ba73e33aadde94 100644 (file)
@@ -5190,18 +5190,6 @@ compute_code_flags(struct compiler *c)
     /* (Only) inherit compilerflags in PyCF_MASK */
     flags |= (c->c_flags->cf_flags & PyCF_MASK);
 
-    n = PyDict_Size(c->u->u_freevars);
-    if (n < 0)
-        return -1;
-    if (n == 0) {
-        n = PyDict_Size(c->u->u_cellvars);
-        if (n < 0)
-            return -1;
-        if (n == 0) {
-            flags |= CO_NOFREE;
-        }
-    }
-
     return flags;
 }
 
index 2f39f9d473db2050b21cac33c6d6c44beeceb9f3..78c0524a1d8a2ad7dbdd8a555ba2d1356ba49a89 100644 (file)
@@ -217,20 +217,24 @@ PyErr_ExceptionMatches(PyObject *exc)
 }
 
 
+#ifndef Py_NORMALIZE_RECURSION_LIMIT
+#define Py_NORMALIZE_RECURSION_LIMIT 32
+#endif
+
 /* Used in many places to normalize a raised exception, including in
    eval_code2(), do_raise(), and PyErr_Print()
 
    XXX: should PyErr_NormalizeException() also call
             PyException_SetTraceback() with the resulting value and tb?
 */
-void
-PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
+static void
+PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
+                           PyObject **tb, int recursion_depth)
 {
     PyObject *type = *exc;
     PyObject *value = *val;
     PyObject *inclass = NULL;
     PyObject *initial_tb = NULL;
-    PyThreadState *tstate = NULL;
 
     if (type == NULL) {
         /* There was no exception, so nothing to do. */
@@ -292,6 +296,10 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
 finally:
     Py_DECREF(type);
     Py_DECREF(value);
+    if (recursion_depth + 1 == Py_NORMALIZE_RECURSION_LIMIT) {
+        PyErr_SetString(PyExc_RecursionError, "maximum recursion depth "
+                        "exceeded while normalizing an exception");
+    }
     /* If the new exception doesn't set a traceback and the old
        exception had a traceback, use the old traceback for the
        new exception.  It's better than nothing.
@@ -304,20 +312,26 @@ finally:
         else
             Py_DECREF(initial_tb);
     }
-    /* normalize recursively */
-    tstate = PyThreadState_GET();
-    if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
-        --tstate->recursion_depth;
-        /* throw away the old exception and use the recursion error instead */
-        Py_INCREF(PyExc_RecursionError);
-        Py_SETREF(*exc, PyExc_RecursionError);
-        Py_INCREF(PyExc_RecursionErrorInst);
-        Py_SETREF(*val, PyExc_RecursionErrorInst);
-        /* just keeping the old traceback */
-        return;
+    /* Normalize recursively.
+     * Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded and the
+     * corresponding RecursionError could not be normalized.*/
+    if (++recursion_depth > Py_NORMALIZE_RECURSION_LIMIT) {
+        if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
+            Py_FatalError("Cannot recover from MemoryErrors "
+                          "while normalizing exceptions.");
+        }
+        else {
+            Py_FatalError("Cannot recover from the recursive normalization "
+                          "of an exception.");
+        }
     }
-    PyErr_NormalizeException(exc, val, tb);
-    --tstate->recursion_depth;
+    PyErr_NormalizeExceptionEx(exc, val, tb, recursion_depth);
+}
+
+void
+PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
+{
+    PyErr_NormalizeExceptionEx(exc, val, tb, 0);
 }
 
 
index 9192bfd6a670fbc30fa7cfa68551f58ad3e7b3fa..d2be76f1e1a815ed03684184cc00ee129c36f386 100644 (file)
@@ -32,11 +32,11 @@ invalid_comma_type(Py_UCS4 presentation_type)
 {
     if (presentation_type > 32 && presentation_type < 128)
         PyErr_Format(PyExc_ValueError,
-                     "Cannot specify ',' or '_' with '%c'.",
+                     "Cannot specify ',' with '%c'.",
                      (char)presentation_type);
     else
         PyErr_Format(PyExc_ValueError,
-                     "Cannot specify ',' or '_' with '\\x%x'.",
+                     "Cannot specify ',' with '\\x%x'.",
                      (unsigned int)presentation_type);
 }
 
index 0f441deb84d0b22af5a48dbf60c97cad6e9ff292..9d9c33ac2de6d43f4ac3f2523fae1bb275a75019 100644 (file)
@@ -24,5 +24,5 @@
 const char *
 Py_GetCompiler(void)
 {
-       return COMPILER;
+    return COMPILER;
 }
index f56fa94cc427f72077697ef8e479d57f0b8dbe2f..326b26fd06e9eb5e4779938998a0d20ef716cd97 100644 (file)
@@ -103,6 +103,11 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
     if (name_unicode == NULL) {
         return NULL;
     }
+    if (!PyUnicode_Check(name_unicode)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "spec.name must be a string");
+        goto error;
+    }
 
     name = get_encoded_name(name_unicode, &hook_prefix);
     if (name == NULL) {
index 18eb1e1225dfb4890e145c415b89a63665a02f10..191197b83852ce99514a987905d35829c06642df 100644 (file)
@@ -1,7 +1,7 @@
 /* Auto-generated by Programs/_freeze_importlib.c */
 const unsigned char _Py_M__importlib[] = {
     99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
-    0,64,0,0,0,115,202,1,0,0,100,0,90,0,100,1,
+    0,64,0,0,0,115,208,1,0,0,100,0,90,0,100,1,
     97,1,100,2,100,3,132,0,90,2,100,4,100,5,132,0,
     90,3,105,0,90,4,105,0,90,5,71,0,100,6,100,7,
     132,0,100,7,101,6,131,3,90,7,71,0,100,8,100,9,
@@ -14,7 +14,7 @@ const unsigned char _Py_M__importlib[] = {
     90,17,100,30,100,31,132,0,90,18,71,0,100,32,100,33,
     132,0,100,33,131,2,90,19,71,0,100,34,100,35,132,0,
     100,35,131,2,90,20,100,1,100,1,100,36,156,2,100,37,
-    100,38,132,2,90,21,100,92,100,39,100,40,132,1,90,22,
+    100,38,132,2,90,21,100,93,100,39,100,40,132,1,90,22,
     100,41,100,42,156,1,100,43,100,44,132,2,90,23,100,45,
     100,46,132,0,90,24,100,47,100,48,132,0,90,25,100,49,
     100,50,132,0,90,26,100,51,100,52,132,0,90,27,100,53,
@@ -22,1788 +22,1801 @@ const unsigned char _Py_M__importlib[] = {
     100,57,100,58,132,0,100,58,131,2,90,30,71,0,100,59,
     100,60,132,0,100,60,131,2,90,31,71,0,100,61,100,62,
     132,0,100,62,131,2,90,32,100,63,100,64,132,0,90,33,
-    100,65,100,66,132,0,90,34,100,93,100,67,100,68,132,1,
+    100,65,100,66,132,0,90,34,100,94,100,67,100,68,132,1,
     90,35,100,69,100,70,132,0,90,36,100,71,90,37,101,37,
     100,72,23,0,90,38,100,73,100,74,132,0,90,39,101,40,
-    131,0,90,41,100,75,100,76,132,0,90,42,100,94,100,78,
-    100,79,132,1,90,43,100,80,100,81,132,0,90,44,100,82,
-    100,83,132,0,90,45,100,1,100,1,102,0,100,77,102,4,
-    100,84,100,85,132,1,90,46,100,86,100,87,132,0,90,47,
-    100,88,100,89,132,0,90,48,100,90,100,91,132,0,90,49,
-    100,1,83,0,41,95,97,83,1,0,0,67,111,114,101,32,
-    105,109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,
-    102,32,105,109,112,111,114,116,46,10,10,84,104,105,115,32,
-    109,111,100,117,108,101,32,105,115,32,78,79,84,32,109,101,
-    97,110,116,32,116,111,32,98,101,32,100,105,114,101,99,116,
-    108,121,32,105,109,112,111,114,116,101,100,33,32,73,116,32,
-    104,97,115,32,98,101,101,110,32,100,101,115,105,103,110,101,
-    100,32,115,117,99,104,10,116,104,97,116,32,105,116,32,99,
-    97,110,32,98,101,32,98,111,111,116,115,116,114,97,112,112,
-    101,100,32,105,110,116,111,32,80,121,116,104,111,110,32,97,
-    115,32,116,104,101,32,105,109,112,108,101,109,101,110,116,97,
-    116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,32,
-    65,115,10,115,117,99,104,32,105,116,32,114,101,113,117,105,
-    114,101,115,32,116,104,101,32,105,110,106,101,99,116,105,111,
-    110,32,111,102,32,115,112,101,99,105,102,105,99,32,109,111,
-    100,117,108,101,115,32,97,110,100,32,97,116,116,114,105,98,
-    117,116,101,115,32,105,110,32,111,114,100,101,114,32,116,111,
-    10,119,111,114,107,46,32,79,110,101,32,115,104,111,117,108,
-    100,32,117,115,101,32,105,109,112,111,114,116,108,105,98,32,
-    97,115,32,116,104,101,32,112,117,98,108,105,99,45,102,97,
-    99,105,110,103,32,118,101,114,115,105,111,110,32,111,102,32,
-    116,104,105,115,32,109,111,100,117,108,101,46,10,10,78,99,
-    2,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0,
-    67,0,0,0,115,60,0,0,0,120,40,100,6,68,0,93,
-    32,125,2,116,0,124,1,124,2,131,2,114,6,116,1,124,
-    0,124,2,116,2,124,1,124,2,131,2,131,3,1,0,113,
-    6,87,0,124,0,106,3,106,4,124,1,106,3,131,1,1,
-    0,100,5,83,0,41,7,122,47,83,105,109,112,108,101,32,
-    115,117,98,115,116,105,116,117,116,101,32,102,111,114,32,102,
-    117,110,99,116,111,111,108,115,46,117,112,100,97,116,101,95,
-    119,114,97,112,112,101,114,46,218,10,95,95,109,111,100,117,
-    108,101,95,95,218,8,95,95,110,97,109,101,95,95,218,12,
-    95,95,113,117,97,108,110,97,109,101,95,95,218,7,95,95,
-    100,111,99,95,95,78,41,4,114,0,0,0,0,114,1,0,
-    0,0,114,2,0,0,0,114,3,0,0,0,41,5,218,7,
-    104,97,115,97,116,116,114,218,7,115,101,116,97,116,116,114,
-    218,7,103,101,116,97,116,116,114,218,8,95,95,100,105,99,
-    116,95,95,218,6,117,112,100,97,116,101,41,3,90,3,110,
-    101,119,90,3,111,108,100,218,7,114,101,112,108,97,99,101,
-    169,0,114,10,0,0,0,250,29,60,102,114,111,122,101,110,
-    32,105,109,112,111,114,116,108,105,98,46,95,98,111,111,116,
-    115,116,114,97,112,62,218,5,95,119,114,97,112,27,0,0,
-    0,115,8,0,0,0,0,2,10,1,10,1,22,1,114,12,
-    0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0,
-    2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,116,
-    1,131,1,124,0,131,1,83,0,41,1,78,41,2,218,4,
-    116,121,112,101,218,3,115,121,115,41,1,218,4,110,97,109,
-    101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,11,95,110,101,119,95,109,111,100,117,108,101,35,0,0,
-    0,115,2,0,0,0,0,1,114,16,0,0,0,99,0,0,
-    0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0,
-    0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100,
-    1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107,
-    69,114,114,111,114,78,41,3,114,1,0,0,0,114,0,0,
-    0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,114,17,0,0,0,
-    48,0,0,0,115,2,0,0,0,8,1,114,17,0,0,0,
-    99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
-    0,64,0,0,0,115,56,0,0,0,101,0,90,1,100,0,
-    90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,
-    100,5,132,0,90,5,100,6,100,7,132,0,90,6,100,8,
-    100,9,132,0,90,7,100,10,100,11,132,0,90,8,100,12,
-    83,0,41,13,218,11,95,77,111,100,117,108,101,76,111,99,
-    107,122,169,65,32,114,101,99,117,114,115,105,118,101,32,108,
-    111,99,107,32,105,109,112,108,101,109,101,110,116,97,116,105,
-    111,110,32,119,104,105,99,104,32,105,115,32,97,98,108,101,
-    32,116,111,32,100,101,116,101,99,116,32,100,101,97,100,108,
-    111,99,107,115,10,32,32,32,32,40,101,46,103,46,32,116,
-    104,114,101,97,100,32,49,32,116,114,121,105,110,103,32,116,
-    111,32,116,97,107,101,32,108,111,99,107,115,32,65,32,116,
-    104,101,110,32,66,44,32,97,110,100,32,116,104,114,101,97,
-    100,32,50,32,116,114,121,105,110,103,32,116,111,10,32,32,
-    32,32,116,97,107,101,32,108,111,99,107,115,32,66,32,116,
-    104,101,110,32,65,41,46,10,32,32,32,32,99,2,0,0,
-    0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,
-    0,115,48,0,0,0,116,0,106,1,131,0,124,0,95,2,
-    116,0,106,1,131,0,124,0,95,3,124,1,124,0,95,4,
-    100,0,124,0,95,5,100,1,124,0,95,6,100,1,124,0,
-    95,7,100,0,83,0,41,2,78,233,0,0,0,0,41,8,
-    218,7,95,116,104,114,101,97,100,90,13,97,108,108,111,99,
-    97,116,101,95,108,111,99,107,218,4,108,111,99,107,218,6,
-    119,97,107,101,117,112,114,15,0,0,0,218,5,111,119,110,
-    101,114,218,5,99,111,117,110,116,218,7,119,97,105,116,101,
-    114,115,41,2,218,4,115,101,108,102,114,15,0,0,0,114,
-    10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8,
-    95,95,105,110,105,116,95,95,58,0,0,0,115,12,0,0,
-    0,0,1,10,1,10,1,6,1,6,1,6,1,122,20,95,
-    77,111,100,117,108,101,76,111,99,107,46,95,95,105,110,105,
-    116,95,95,99,1,0,0,0,0,0,0,0,4,0,0,0,
-    2,0,0,0,67,0,0,0,115,64,0,0,0,116,0,106,
-    1,131,0,125,1,124,0,106,2,125,2,120,44,116,3,106,
-    4,124,2,131,1,125,3,124,3,100,0,107,8,114,38,100,
-    1,83,0,124,3,106,2,125,2,124,2,124,1,107,2,114,
-    16,100,2,83,0,113,16,87,0,100,0,83,0,41,3,78,
-    70,84,41,5,114,20,0,0,0,218,9,103,101,116,95,105,
-    100,101,110,116,114,23,0,0,0,218,12,95,98,108,111,99,
-    107,105,110,103,95,111,110,218,3,103,101,116,41,4,114,26,
-    0,0,0,90,2,109,101,218,3,116,105,100,114,21,0,0,
-    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,12,104,97,115,95,100,101,97,100,108,111,99,107,66,0,
-    0,0,115,18,0,0,0,0,2,8,1,6,1,2,1,10,
-    1,8,1,4,1,6,1,8,1,122,24,95,77,111,100,117,
-    108,101,76,111,99,107,46,104,97,115,95,100,101,97,100,108,
-    111,99,107,99,1,0,0,0,0,0,0,0,2,0,0,0,
-    16,0,0,0,67,0,0,0,115,168,0,0,0,116,0,106,
-    1,131,0,125,1,124,0,116,2,124,1,60,0,122,138,120,
-    132,124,0,106,3,143,96,1,0,124,0,106,4,100,1,107,
-    2,115,48,124,0,106,5,124,1,107,2,114,72,124,1,124,
-    0,95,5,124,0,4,0,106,4,100,2,55,0,2,0,95,
-    4,100,3,83,0,124,0,106,6,131,0,114,92,116,7,100,
-    4,124,0,22,0,131,1,130,1,124,0,106,8,106,9,100,
-    5,131,1,114,118,124,0,4,0,106,10,100,2,55,0,2,
-    0,95,10,87,0,100,6,81,0,82,0,88,0,124,0,106,
-    8,106,9,131,0,1,0,124,0,106,8,106,11,131,0,1,
-    0,113,20,87,0,87,0,100,6,116,2,124,1,61,0,88,
-    0,100,6,83,0,41,7,122,185,10,32,32,32,32,32,32,
-    32,32,65,99,113,117,105,114,101,32,116,104,101,32,109,111,
-    100,117,108,101,32,108,111,99,107,46,32,32,73,102,32,97,
-    32,112,111,116,101,110,116,105,97,108,32,100,101,97,100,108,
-    111,99,107,32,105,115,32,100,101,116,101,99,116,101,100,44,
-    10,32,32,32,32,32,32,32,32,97,32,95,68,101,97,100,
-    108,111,99,107,69,114,114,111,114,32,105,115,32,114,97,105,
-    115,101,100,46,10,32,32,32,32,32,32,32,32,79,116,104,
-    101,114,119,105,115,101,44,32,116,104,101,32,108,111,99,107,
-    32,105,115,32,97,108,119,97,121,115,32,97,99,113,117,105,
-    114,101,100,32,97,110,100,32,84,114,117,101,32,105,115,32,
-    114,101,116,117,114,110,101,100,46,10,32,32,32,32,32,32,
-    32,32,114,19,0,0,0,233,1,0,0,0,84,122,23,100,
-    101,97,100,108,111,99,107,32,100,101,116,101,99,116,101,100,
-    32,98,121,32,37,114,70,78,41,12,114,20,0,0,0,114,
-    28,0,0,0,114,29,0,0,0,114,21,0,0,0,114,24,
-    0,0,0,114,23,0,0,0,114,32,0,0,0,114,17,0,
-    0,0,114,22,0,0,0,218,7,97,99,113,117,105,114,101,
-    114,25,0,0,0,218,7,114,101,108,101,97,115,101,41,2,
-    114,26,0,0,0,114,31,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,34,0,0,0,78,0,
-    0,0,115,32,0,0,0,0,6,8,1,8,1,2,1,2,
-    1,8,1,20,1,6,1,14,1,4,1,8,1,12,1,12,
-    1,24,2,10,1,18,2,122,19,95,77,111,100,117,108,101,
-    76,111,99,107,46,97,99,113,117,105,114,101,99,1,0,0,
-    0,0,0,0,0,2,0,0,0,10,0,0,0,67,0,0,
-    0,115,122,0,0,0,116,0,106,1,131,0,125,1,124,0,
-    106,2,143,98,1,0,124,0,106,3,124,1,107,3,114,34,
-    116,4,100,1,131,1,130,1,124,0,106,5,100,2,107,4,
-    115,48,116,6,130,1,124,0,4,0,106,5,100,3,56,0,
-    2,0,95,5,124,0,106,5,100,2,107,2,114,108,100,0,
-    124,0,95,3,124,0,106,7,114,108,124,0,4,0,106,7,
-    100,3,56,0,2,0,95,7,124,0,106,8,106,9,131,0,
-    1,0,87,0,100,0,81,0,82,0,88,0,100,0,83,0,
-    41,4,78,122,31,99,97,110,110,111,116,32,114,101,108,101,
-    97,115,101,32,117,110,45,97,99,113,117,105,114,101,100,32,
-    108,111,99,107,114,19,0,0,0,114,33,0,0,0,41,10,
-    114,20,0,0,0,114,28,0,0,0,114,21,0,0,0,114,
-    23,0,0,0,218,12,82,117,110,116,105,109,101,69,114,114,
-    111,114,114,24,0,0,0,218,14,65,115,115,101,114,116,105,
-    111,110,69,114,114,111,114,114,25,0,0,0,114,22,0,0,
-    0,114,35,0,0,0,41,2,114,26,0,0,0,114,31,0,
+    131,0,90,41,100,75,100,76,132,0,90,42,100,95,100,78,
+    100,79,132,1,90,43,100,41,100,80,156,1,100,81,100,82,
+    132,2,90,44,100,83,100,84,132,0,90,45,100,1,100,1,
+    102,0,100,77,102,4,100,85,100,86,132,1,90,46,100,87,
+    100,88,132,0,90,47,100,89,100,90,132,0,90,48,100,91,
+    100,92,132,0,90,49,100,1,83,0,41,96,97,83,1,0,
+    0,67,111,114,101,32,105,109,112,108,101,109,101,110,116,97,
+    116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,10,
+    10,84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,
+    78,79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,
+    100,105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,
+    100,33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,
+    101,115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,
+    116,32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,
+    115,116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,
+    116,104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,
+    101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,
+    112,111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,
+    32,114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,
+    106,101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,
+    102,105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,
+    97,116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,
+    100,101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,
+    32,115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,
+    114,116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,
+    108,105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,
+    111,110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,
+    101,46,10,10,78,99,2,0,0,0,0,0,0,0,3,0,
+    0,0,7,0,0,0,67,0,0,0,115,60,0,0,0,120,
+    40,100,6,68,0,93,32,125,2,116,0,124,1,124,2,131,
+    2,114,6,116,1,124,0,124,2,116,2,124,1,124,2,131,
+    2,131,3,1,0,113,6,87,0,124,0,106,3,106,4,124,
+    1,106,3,131,1,1,0,100,5,83,0,41,7,122,47,83,
+    105,109,112,108,101,32,115,117,98,115,116,105,116,117,116,101,
+    32,102,111,114,32,102,117,110,99,116,111,111,108,115,46,117,
+    112,100,97,116,101,95,119,114,97,112,112,101,114,46,218,10,
+    95,95,109,111,100,117,108,101,95,95,218,8,95,95,110,97,
+    109,101,95,95,218,12,95,95,113,117,97,108,110,97,109,101,
+    95,95,218,7,95,95,100,111,99,95,95,78,41,4,114,0,
+    0,0,0,114,1,0,0,0,114,2,0,0,0,114,3,0,
+    0,0,41,5,218,7,104,97,115,97,116,116,114,218,7,115,
+    101,116,97,116,116,114,218,7,103,101,116,97,116,116,114,218,
+    8,95,95,100,105,99,116,95,95,218,6,117,112,100,97,116,
+    101,41,3,90,3,110,101,119,90,3,111,108,100,218,7,114,
+    101,112,108,97,99,101,169,0,114,10,0,0,0,250,29,60,
+    102,114,111,122,101,110,32,105,109,112,111,114,116,108,105,98,
+    46,95,98,111,111,116,115,116,114,97,112,62,218,5,95,119,
+    114,97,112,27,0,0,0,115,8,0,0,0,0,2,10,1,
+    10,1,22,1,114,12,0,0,0,99,1,0,0,0,0,0,
+    0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,12,
+    0,0,0,116,0,116,1,131,1,124,0,131,1,83,0,41,
+    1,78,41,2,218,4,116,121,112,101,218,3,115,121,115,41,
+    1,218,4,110,97,109,101,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,11,95,110,101,119,95,109,111,100,
+    117,108,101,35,0,0,0,115,2,0,0,0,0,1,114,16,
+    0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,
+    1,0,0,0,64,0,0,0,115,12,0,0,0,101,0,90,
+    1,100,0,90,2,100,1,83,0,41,2,218,14,95,68,101,
+    97,100,108,111,99,107,69,114,114,111,114,78,41,3,114,1,
+    0,0,0,114,0,0,0,0,114,2,0,0,0,114,10,0,
     0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,35,0,0,0,103,0,0,0,115,22,0,0,0,0,
-    1,8,1,8,1,10,1,8,1,14,1,14,1,10,1,6,
-    1,6,1,14,1,122,19,95,77,111,100,117,108,101,76,111,
-    99,107,46,114,101,108,101,97,115,101,99,1,0,0,0,0,
-    0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,
-    18,0,0,0,100,1,106,0,124,0,106,1,116,2,124,0,
-    131,1,131,2,83,0,41,2,78,122,23,95,77,111,100,117,
-    108,101,76,111,99,107,40,123,33,114,125,41,32,97,116,32,
-    123,125,41,3,218,6,102,111,114,109,97,116,114,15,0,0,
-    0,218,2,105,100,41,1,114,26,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,218,8,95,95,114,
-    101,112,114,95,95,116,0,0,0,115,2,0,0,0,0,1,
-    122,20,95,77,111,100,117,108,101,76,111,99,107,46,95,95,
-    114,101,112,114,95,95,78,41,9,114,1,0,0,0,114,0,
-    0,0,0,114,2,0,0,0,114,3,0,0,0,114,27,0,
-    0,0,114,32,0,0,0,114,34,0,0,0,114,35,0,0,
-    0,114,40,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,18,0,0,0,52,
-    0,0,0,115,12,0,0,0,8,4,4,2,8,8,8,12,
-    8,25,8,13,114,18,0,0,0,99,0,0,0,0,0,0,
-    0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,48,
-    0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,
-    2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,
-    6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,
-    10,83,0,41,11,218,16,95,68,117,109,109,121,77,111,100,
-    117,108,101,76,111,99,107,122,86,65,32,115,105,109,112,108,
-    101,32,95,77,111,100,117,108,101,76,111,99,107,32,101,113,
-    117,105,118,97,108,101,110,116,32,102,111,114,32,80,121,116,
-    104,111,110,32,98,117,105,108,100,115,32,119,105,116,104,111,
-    117,116,10,32,32,32,32,109,117,108,116,105,45,116,104,114,
-    101,97,100,105,110,103,32,115,117,112,112,111,114,116,46,99,
-    2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,
-    67,0,0,0,115,16,0,0,0,124,1,124,0,95,0,100,
-    1,124,0,95,1,100,0,83,0,41,2,78,114,19,0,0,
-    0,41,2,114,15,0,0,0,114,24,0,0,0,41,2,114,
-    26,0,0,0,114,15,0,0,0,114,10,0,0,0,114,10,
-    0,0,0,114,11,0,0,0,114,27,0,0,0,124,0,0,
-    0,115,4,0,0,0,0,1,6,1,122,25,95,68,117,109,
-    109,121,77,111,100,117,108,101,76,111,99,107,46,95,95,105,
-    110,105,116,95,95,99,1,0,0,0,0,0,0,0,1,0,
-    0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,124,
-    0,4,0,106,0,100,1,55,0,2,0,95,0,100,2,83,
-    0,41,3,78,114,33,0,0,0,84,41,1,114,24,0,0,
-    0,41,1,114,26,0,0,0,114,10,0,0,0,114,10,0,
-    0,0,114,11,0,0,0,114,34,0,0,0,128,0,0,0,
-    115,4,0,0,0,0,1,14,1,122,24,95,68,117,109,109,
-    121,77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,
-    105,114,101,99,1,0,0,0,0,0,0,0,1,0,0,0,
-    3,0,0,0,67,0,0,0,115,36,0,0,0,124,0,106,
-    0,100,1,107,2,114,18,116,1,100,2,131,1,130,1,124,
-    0,4,0,106,0,100,3,56,0,2,0,95,0,100,0,83,
-    0,41,4,78,114,19,0,0,0,122,31,99,97,110,110,111,
+    0,114,17,0,0,0,48,0,0,0,115,2,0,0,0,8,
+    1,114,17,0,0,0,99,0,0,0,0,0,0,0,0,0,
+    0,0,0,2,0,0,0,64,0,0,0,115,56,0,0,0,
+    101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,
+    132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,
+    132,0,90,6,100,8,100,9,132,0,90,7,100,10,100,11,
+    132,0,90,8,100,12,83,0,41,13,218,11,95,77,111,100,
+    117,108,101,76,111,99,107,122,169,65,32,114,101,99,117,114,
+    115,105,118,101,32,108,111,99,107,32,105,109,112,108,101,109,
+    101,110,116,97,116,105,111,110,32,119,104,105,99,104,32,105,
+    115,32,97,98,108,101,32,116,111,32,100,101,116,101,99,116,
+    32,100,101,97,100,108,111,99,107,115,10,32,32,32,32,40,
+    101,46,103,46,32,116,104,114,101,97,100,32,49,32,116,114,
+    121,105,110,103,32,116,111,32,116,97,107,101,32,108,111,99,
+    107,115,32,65,32,116,104,101,110,32,66,44,32,97,110,100,
+    32,116,104,114,101,97,100,32,50,32,116,114,121,105,110,103,
+    32,116,111,10,32,32,32,32,116,97,107,101,32,108,111,99,
+    107,115,32,66,32,116,104,101,110,32,65,41,46,10,32,32,
+    32,32,99,2,0,0,0,0,0,0,0,2,0,0,0,2,
+    0,0,0,67,0,0,0,115,48,0,0,0,116,0,106,1,
+    131,0,124,0,95,2,116,0,106,1,131,0,124,0,95,3,
+    124,1,124,0,95,4,100,0,124,0,95,5,100,1,124,0,
+    95,6,100,1,124,0,95,7,100,0,83,0,41,2,78,233,
+    0,0,0,0,41,8,218,7,95,116,104,114,101,97,100,90,
+    13,97,108,108,111,99,97,116,101,95,108,111,99,107,218,4,
+    108,111,99,107,218,6,119,97,107,101,117,112,114,15,0,0,
+    0,218,5,111,119,110,101,114,218,5,99,111,117,110,116,218,
+    7,119,97,105,116,101,114,115,41,2,218,4,115,101,108,102,
+    114,15,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+    11,0,0,0,218,8,95,95,105,110,105,116,95,95,58,0,
+    0,0,115,12,0,0,0,0,1,10,1,10,1,6,1,6,
+    1,6,1,122,20,95,77,111,100,117,108,101,76,111,99,107,
+    46,95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,
+    0,0,4,0,0,0,2,0,0,0,67,0,0,0,115,64,
+    0,0,0,116,0,106,1,131,0,125,1,124,0,106,2,125,
+    2,120,44,116,3,106,4,124,2,131,1,125,3,124,3,100,
+    0,107,8,114,38,100,1,83,0,124,3,106,2,125,2,124,
+    2,124,1,107,2,114,16,100,2,83,0,113,16,87,0,100,
+    0,83,0,41,3,78,70,84,41,5,114,20,0,0,0,218,
+    9,103,101,116,95,105,100,101,110,116,114,23,0,0,0,218,
+    12,95,98,108,111,99,107,105,110,103,95,111,110,218,3,103,
+    101,116,41,4,114,26,0,0,0,90,2,109,101,218,3,116,
+    105,100,114,21,0,0,0,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,12,104,97,115,95,100,101,97,100,
+    108,111,99,107,66,0,0,0,115,18,0,0,0,0,2,8,
+    1,6,1,2,1,10,1,8,1,4,1,6,1,8,1,122,
+    24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115,
+    95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0,
+    0,0,2,0,0,0,16,0,0,0,67,0,0,0,115,168,
+    0,0,0,116,0,106,1,131,0,125,1,124,0,116,2,124,
+    1,60,0,122,138,120,132,124,0,106,3,143,96,1,0,124,
+    0,106,4,100,1,107,2,115,48,124,0,106,5,124,1,107,
+    2,114,72,124,1,124,0,95,5,124,0,4,0,106,4,100,
+    2,55,0,2,0,95,4,100,3,83,0,124,0,106,6,131,
+    0,114,92,116,7,100,4,124,0,22,0,131,1,130,1,124,
+    0,106,8,106,9,100,5,131,1,114,118,124,0,4,0,106,
+    10,100,2,55,0,2,0,95,10,87,0,100,6,81,0,82,
+    0,88,0,124,0,106,8,106,9,131,0,1,0,124,0,106,
+    8,106,11,131,0,1,0,113,20,87,0,87,0,100,6,116,
+    2,124,1,61,0,88,0,100,6,83,0,41,7,122,185,10,
+    32,32,32,32,32,32,32,32,65,99,113,117,105,114,101,32,
+    116,104,101,32,109,111,100,117,108,101,32,108,111,99,107,46,
+    32,32,73,102,32,97,32,112,111,116,101,110,116,105,97,108,
+    32,100,101,97,100,108,111,99,107,32,105,115,32,100,101,116,
+    101,99,116,101,100,44,10,32,32,32,32,32,32,32,32,97,
+    32,95,68,101,97,100,108,111,99,107,69,114,114,111,114,32,
+    105,115,32,114,97,105,115,101,100,46,10,32,32,32,32,32,
+    32,32,32,79,116,104,101,114,119,105,115,101,44,32,116,104,
+    101,32,108,111,99,107,32,105,115,32,97,108,119,97,121,115,
+    32,97,99,113,117,105,114,101,100,32,97,110,100,32,84,114,
+    117,101,32,105,115,32,114,101,116,117,114,110,101,100,46,10,
+    32,32,32,32,32,32,32,32,114,19,0,0,0,233,1,0,
+    0,0,84,122,23,100,101,97,100,108,111,99,107,32,100,101,
+    116,101,99,116,101,100,32,98,121,32,37,114,70,78,41,12,
+    114,20,0,0,0,114,28,0,0,0,114,29,0,0,0,114,
+    21,0,0,0,114,24,0,0,0,114,23,0,0,0,114,32,
+    0,0,0,114,17,0,0,0,114,22,0,0,0,218,7,97,
+    99,113,117,105,114,101,114,25,0,0,0,218,7,114,101,108,
+    101,97,115,101,41,2,114,26,0,0,0,114,31,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    34,0,0,0,78,0,0,0,115,32,0,0,0,0,6,8,
+    1,8,1,2,1,2,1,8,1,20,1,6,1,14,1,4,
+    1,8,1,12,1,12,1,24,2,10,1,18,2,122,19,95,
+    77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,105,
+    114,101,99,1,0,0,0,0,0,0,0,2,0,0,0,10,
+    0,0,0,67,0,0,0,115,122,0,0,0,116,0,106,1,
+    131,0,125,1,124,0,106,2,143,98,1,0,124,0,106,3,
+    124,1,107,3,114,34,116,4,100,1,131,1,130,1,124,0,
+    106,5,100,2,107,4,115,48,116,6,130,1,124,0,4,0,
+    106,5,100,3,56,0,2,0,95,5,124,0,106,5,100,2,
+    107,2,114,108,100,0,124,0,95,3,124,0,106,7,114,108,
+    124,0,4,0,106,7,100,3,56,0,2,0,95,7,124,0,
+    106,8,106,9,131,0,1,0,87,0,100,0,81,0,82,0,
+    88,0,100,0,83,0,41,4,78,122,31,99,97,110,110,111,
     116,32,114,101,108,101,97,115,101,32,117,110,45,97,99,113,
-    117,105,114,101,100,32,108,111,99,107,114,33,0,0,0,41,
-    2,114,24,0,0,0,114,36,0,0,0,41,1,114,26,0,
-    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,35,0,0,0,132,0,0,0,115,6,0,0,0,0,
-    1,10,1,8,1,122,24,95,68,117,109,109,121,77,111,100,
-    117,108,101,76,111,99,107,46,114,101,108,101,97,115,101,99,
-    1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,
-    67,0,0,0,115,18,0,0,0,100,1,106,0,124,0,106,
-    1,116,2,124,0,131,1,131,2,83,0,41,2,78,122,28,
-    95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107,
-    40,123,33,114,125,41,32,97,116,32,123,125,41,3,114,38,
-    0,0,0,114,15,0,0,0,114,39,0,0,0,41,1,114,
-    26,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
-    0,0,0,114,40,0,0,0,137,0,0,0,115,2,0,0,
-    0,0,1,122,25,95,68,117,109,109,121,77,111,100,117,108,
-    101,76,111,99,107,46,95,95,114,101,112,114,95,95,78,41,
-    8,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,
-    114,3,0,0,0,114,27,0,0,0,114,34,0,0,0,114,
-    35,0,0,0,114,40,0,0,0,114,10,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,114,41,0,
-    0,0,120,0,0,0,115,10,0,0,0,8,2,4,2,8,
-    4,8,4,8,5,114,41,0,0,0,99,0,0,0,0,0,
-    0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,
-    36,0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,
-    132,0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,
-    132,0,90,5,100,7,83,0,41,8,218,18,95,77,111,100,
-    117,108,101,76,111,99,107,77,97,110,97,103,101,114,99,2,
-    0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,
-    0,0,0,115,16,0,0,0,124,1,124,0,95,0,100,0,
-    124,0,95,1,100,0,83,0,41,1,78,41,2,218,5,95,
-    110,97,109,101,218,5,95,108,111,99,107,41,2,114,26,0,
-    0,0,114,15,0,0,0,114,10,0,0,0,114,10,0,0,
-    0,114,11,0,0,0,114,27,0,0,0,143,0,0,0,115,
-    4,0,0,0,0,1,6,1,122,27,95,77,111,100,117,108,
-    101,76,111,99,107,77,97,110,97,103,101,114,46,95,95,105,
-    110,105,116,95,95,99,1,0,0,0,0,0,0,0,1,0,
-    0,0,2,0,0,0,67,0,0,0,115,26,0,0,0,116,
-    0,124,0,106,1,131,1,124,0,95,2,124,0,106,2,106,
-    3,131,0,1,0,100,0,83,0,41,1,78,41,4,218,16,
-    95,103,101,116,95,109,111,100,117,108,101,95,108,111,99,107,
-    114,43,0,0,0,114,44,0,0,0,114,34,0,0,0,41,
-    1,114,26,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,11,0,0,0,218,9,95,95,101,110,116,101,114,95,95,
-    147,0,0,0,115,4,0,0,0,0,1,12,1,122,28,95,
-    77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101,
-    114,46,95,95,101,110,116,101,114,95,95,99,1,0,0,0,
-    0,0,0,0,3,0,0,0,1,0,0,0,79,0,0,0,
-    115,14,0,0,0,124,0,106,0,106,1,131,0,1,0,100,
-    0,83,0,41,1,78,41,2,114,44,0,0,0,114,35,0,
-    0,0,41,3,114,26,0,0,0,218,4,97,114,103,115,90,
-    6,107,119,97,114,103,115,114,10,0,0,0,114,10,0,0,
-    0,114,11,0,0,0,218,8,95,95,101,120,105,116,95,95,
-    151,0,0,0,115,2,0,0,0,0,1,122,27,95,77,111,
-    100,117,108,101,76,111,99,107,77,97,110,97,103,101,114,46,
-    95,95,101,120,105,116,95,95,78,41,6,114,1,0,0,0,
-    114,0,0,0,0,114,2,0,0,0,114,27,0,0,0,114,
-    46,0,0,0,114,48,0,0,0,114,10,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,114,42,0,
-    0,0,141,0,0,0,115,6,0,0,0,8,2,8,4,8,
-    4,114,42,0,0,0,99,1,0,0,0,0,0,0,0,3,
-    0,0,0,17,0,0,0,67,0,0,0,115,130,0,0,0,
-    116,0,106,1,131,0,1,0,122,106,121,14,116,2,124,0,
-    25,0,131,0,125,1,87,0,110,24,4,0,116,3,107,10,
-    114,48,1,0,1,0,1,0,100,1,125,1,89,0,110,2,
-    88,0,124,1,100,1,107,8,114,112,116,4,100,1,107,8,
-    114,76,116,5,124,0,131,1,125,1,110,8,116,6,124,0,
-    131,1,125,1,124,0,102,1,100,2,100,3,132,1,125,2,
-    116,7,106,8,124,1,124,2,131,2,116,2,124,0,60,0,
-    87,0,100,1,116,0,106,9,131,0,1,0,88,0,124,1,
-    83,0,41,4,122,139,71,101,116,32,111,114,32,99,114,101,
-    97,116,101,32,116,104,101,32,109,111,100,117,108,101,32,108,
-    111,99,107,32,102,111,114,32,97,32,103,105,118,101,110,32,
-    109,111,100,117,108,101,32,110,97,109,101,46,10,10,32,32,
-    32,32,65,99,113,117,105,114,101,47,114,101,108,101,97,115,
-    101,32,105,110,116,101,114,110,97,108,108,121,32,116,104,101,
-    32,103,108,111,98,97,108,32,105,109,112,111,114,116,32,108,
-    111,99,107,32,116,111,32,112,114,111,116,101,99,116,10,32,
-    32,32,32,95,109,111,100,117,108,101,95,108,111,99,107,115,
-    46,78,99,2,0,0,0,0,0,0,0,2,0,0,0,10,
-    0,0,0,83,0,0,0,115,48,0,0,0,116,0,106,1,
-    131,0,1,0,122,24,116,2,106,3,124,1,131,1,124,0,
-    107,8,114,30,116,2,124,1,61,0,87,0,100,0,116,0,
-    106,4,131,0,1,0,88,0,100,0,83,0,41,1,78,41,
-    5,218,4,95,105,109,112,218,12,97,99,113,117,105,114,101,
-    95,108,111,99,107,218,13,95,109,111,100,117,108,101,95,108,
-    111,99,107,115,114,30,0,0,0,218,12,114,101,108,101,97,
-    115,101,95,108,111,99,107,41,2,218,3,114,101,102,114,15,
-    0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,218,2,99,98,176,0,0,0,115,10,0,0,0,0,
-    1,8,1,2,4,14,1,10,2,122,28,95,103,101,116,95,
-    109,111,100,117,108,101,95,108,111,99,107,46,60,108,111,99,
-    97,108,115,62,46,99,98,41,10,114,49,0,0,0,114,50,
-    0,0,0,114,51,0,0,0,218,8,75,101,121,69,114,114,
-    111,114,114,20,0,0,0,114,41,0,0,0,114,18,0,0,
-    0,218,8,95,119,101,97,107,114,101,102,114,53,0,0,0,
-    114,52,0,0,0,41,3,114,15,0,0,0,114,21,0,0,
-    0,114,54,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,11,0,0,0,114,45,0,0,0,157,0,0,0,115,28,
-    0,0,0,0,6,8,1,2,1,2,1,14,1,14,1,10,
-    2,8,1,8,1,10,2,8,2,12,11,20,2,10,2,114,
-    45,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0,
-    0,11,0,0,0,67,0,0,0,115,54,0,0,0,116,0,
-    124,0,131,1,125,1,121,12,124,1,106,1,131,0,1,0,
-    87,0,110,20,4,0,116,2,107,10,114,40,1,0,1,0,
-    1,0,89,0,110,10,88,0,124,1,106,3,131,0,1,0,
-    100,1,83,0,41,2,122,189,65,99,113,117,105,114,101,115,
-    32,116,104,101,110,32,114,101,108,101,97,115,101,115,32,116,
-    104,101,32,109,111,100,117,108,101,32,108,111,99,107,32,102,
-    111,114,32,97,32,103,105,118,101,110,32,109,111,100,117,108,
-    101,32,110,97,109,101,46,10,10,32,32,32,32,84,104,105,
-    115,32,105,115,32,117,115,101,100,32,116,111,32,101,110,115,
-    117,114,101,32,97,32,109,111,100,117,108,101,32,105,115,32,
-    99,111,109,112,108,101,116,101,108,121,32,105,110,105,116,105,
-    97,108,105,122,101,100,44,32,105,110,32,116,104,101,10,32,
-    32,32,32,101,118,101,110,116,32,105,116,32,105,115,32,98,
-    101,105,110,103,32,105,109,112,111,114,116,101,100,32,98,121,
-    32,97,110,111,116,104,101,114,32,116,104,114,101,97,100,46,
-    10,32,32,32,32,78,41,4,114,45,0,0,0,114,34,0,
-    0,0,114,17,0,0,0,114,35,0,0,0,41,2,114,15,
-    0,0,0,114,21,0,0,0,114,10,0,0,0,114,10,0,
-    0,0,114,11,0,0,0,218,19,95,108,111,99,107,95,117,
-    110,108,111,99,107,95,109,111,100,117,108,101,194,0,0,0,
-    115,12,0,0,0,0,6,8,1,2,1,12,1,14,3,6,
-    2,114,57,0,0,0,99,1,0,0,0,0,0,0,0,3,
-    0,0,0,3,0,0,0,79,0,0,0,115,10,0,0,0,
-    124,0,124,1,124,2,142,1,83,0,41,1,97,46,1,0,
-    0,114,101,109,111,118,101,95,105,109,112,111,114,116,108,105,
-    98,95,102,114,97,109,101,115,32,105,110,32,105,109,112,111,
-    114,116,46,99,32,119,105,108,108,32,97,108,119,97,121,115,
-    32,114,101,109,111,118,101,32,115,101,113,117,101,110,99,101,
-    115,10,32,32,32,32,111,102,32,105,109,112,111,114,116,108,
-    105,98,32,102,114,97,109,101,115,32,116,104,97,116,32,101,
-    110,100,32,119,105,116,104,32,97,32,99,97,108,108,32,116,
-    111,32,116,104,105,115,32,102,117,110,99,116,105,111,110,10,
-    10,32,32,32,32,85,115,101,32,105,116,32,105,110,115,116,
-    101,97,100,32,111,102,32,97,32,110,111,114,109,97,108,32,
-    99,97,108,108,32,105,110,32,112,108,97,99,101,115,32,119,
-    104,101,114,101,32,105,110,99,108,117,100,105,110,103,32,116,
-    104,101,32,105,109,112,111,114,116,108,105,98,10,32,32,32,
-    32,102,114,97,109,101,115,32,105,110,116,114,111,100,117,99,
-    101,115,32,117,110,119,97,110,116,101,100,32,110,111,105,115,
-    101,32,105,110,116,111,32,116,104,101,32,116,114,97,99,101,
-    98,97,99,107,32,40,101,46,103,46,32,119,104,101,110,32,
-    101,120,101,99,117,116,105,110,103,10,32,32,32,32,109,111,
-    100,117,108,101,32,99,111,100,101,41,10,32,32,32,32,114,
-    10,0,0,0,41,3,218,1,102,114,47,0,0,0,90,4,
-    107,119,100,115,114,10,0,0,0,114,10,0,0,0,114,11,
-    0,0,0,218,25,95,99,97,108,108,95,119,105,116,104,95,
-    102,114,97,109,101,115,95,114,101,109,111,118,101,100,211,0,
-    0,0,115,2,0,0,0,0,8,114,59,0,0,0,114,33,
-    0,0,0,41,1,218,9,118,101,114,98,111,115,105,116,121,
-    99,1,0,0,0,1,0,0,0,3,0,0,0,4,0,0,
-    0,71,0,0,0,115,54,0,0,0,116,0,106,1,106,2,
-    124,1,107,5,114,50,124,0,106,3,100,6,131,1,115,30,
-    100,3,124,0,23,0,125,0,116,4,124,0,106,5,124,2,
-    142,0,116,0,106,6,100,4,141,2,1,0,100,5,83,0,
-    41,7,122,61,80,114,105,110,116,32,116,104,101,32,109,101,
-    115,115,97,103,101,32,116,111,32,115,116,100,101,114,114,32,
-    105,102,32,45,118,47,80,89,84,72,79,78,86,69,82,66,
-    79,83,69,32,105,115,32,116,117,114,110,101,100,32,111,110,
-    46,250,1,35,250,7,105,109,112,111,114,116,32,122,2,35,
-    32,41,1,90,4,102,105,108,101,78,41,2,114,61,0,0,
-    0,114,62,0,0,0,41,7,114,14,0,0,0,218,5,102,
-    108,97,103,115,218,7,118,101,114,98,111,115,101,218,10,115,
-    116,97,114,116,115,119,105,116,104,218,5,112,114,105,110,116,
-    114,38,0,0,0,218,6,115,116,100,101,114,114,41,3,218,
-    7,109,101,115,115,97,103,101,114,60,0,0,0,114,47,0,
+    117,105,114,101,100,32,108,111,99,107,114,19,0,0,0,114,
+    33,0,0,0,41,10,114,20,0,0,0,114,28,0,0,0,
+    114,21,0,0,0,114,23,0,0,0,218,12,82,117,110,116,
+    105,109,101,69,114,114,111,114,114,24,0,0,0,218,14,65,
+    115,115,101,114,116,105,111,110,69,114,114,111,114,114,25,0,
+    0,0,114,22,0,0,0,114,35,0,0,0,41,2,114,26,
+    0,0,0,114,31,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,35,0,0,0,103,0,0,0,
+    115,22,0,0,0,0,1,8,1,8,1,10,1,8,1,14,
+    1,14,1,10,1,6,1,6,1,14,1,122,19,95,77,111,
+    100,117,108,101,76,111,99,107,46,114,101,108,101,97,115,101,
+    99,1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,
+    0,67,0,0,0,115,18,0,0,0,100,1,106,0,124,0,
+    106,1,116,2,124,0,131,1,131,2,83,0,41,2,78,122,
+    23,95,77,111,100,117,108,101,76,111,99,107,40,123,33,114,
+    125,41,32,97,116,32,123,125,41,3,218,6,102,111,114,109,
+    97,116,114,15,0,0,0,218,2,105,100,41,1,114,26,0,
     0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,218,16,95,118,101,114,98,111,115,101,95,109,101,115,115,
-    97,103,101,222,0,0,0,115,8,0,0,0,0,2,12,1,
-    10,1,8,1,114,69,0,0,0,99,1,0,0,0,0,0,
-    0,0,2,0,0,0,3,0,0,0,3,0,0,0,115,26,
-    0,0,0,135,0,102,1,100,1,100,2,132,8,125,1,116,
-    0,124,1,136,0,131,2,1,0,124,1,83,0,41,3,122,
-    49,68,101,99,111,114,97,116,111,114,32,116,111,32,118,101,
-    114,105,102,121,32,116,104,101,32,110,97,109,101,100,32,109,
-    111,100,117,108,101,32,105,115,32,98,117,105,108,116,45,105,
-    110,46,99,2,0,0,0,0,0,0,0,2,0,0,0,4,
-    0,0,0,19,0,0,0,115,38,0,0,0,124,1,116,0,
-    106,1,107,7,114,28,116,2,100,1,106,3,124,1,131,1,
-    124,1,100,2,141,2,130,1,136,0,124,0,124,1,131,2,
-    83,0,41,3,78,122,29,123,33,114,125,32,105,115,32,110,
-    111,116,32,97,32,98,117,105,108,116,45,105,110,32,109,111,
-    100,117,108,101,41,1,114,15,0,0,0,41,4,114,14,0,
-    0,0,218,20,98,117,105,108,116,105,110,95,109,111,100,117,
-    108,101,95,110,97,109,101,115,218,11,73,109,112,111,114,116,
-    69,114,114,111,114,114,38,0,0,0,41,2,114,26,0,0,
-    0,218,8,102,117,108,108,110,97,109,101,41,1,218,3,102,
-    120,110,114,10,0,0,0,114,11,0,0,0,218,25,95,114,
-    101,113,117,105,114,101,115,95,98,117,105,108,116,105,110,95,
-    119,114,97,112,112,101,114,232,0,0,0,115,8,0,0,0,
-    0,1,10,1,10,1,8,1,122,52,95,114,101,113,117,105,
-    114,101,115,95,98,117,105,108,116,105,110,46,60,108,111,99,
-    97,108,115,62,46,95,114,101,113,117,105,114,101,115,95,98,
-    117,105,108,116,105,110,95,119,114,97,112,112,101,114,41,1,
-    114,12,0,0,0,41,2,114,73,0,0,0,114,74,0,0,
-    0,114,10,0,0,0,41,1,114,73,0,0,0,114,11,0,
-    0,0,218,17,95,114,101,113,117,105,114,101,115,95,98,117,
-    105,108,116,105,110,230,0,0,0,115,6,0,0,0,0,2,
-    12,5,10,1,114,75,0,0,0,99,1,0,0,0,0,0,
-    0,0,2,0,0,0,3,0,0,0,3,0,0,0,115,26,
-    0,0,0,135,0,102,1,100,1,100,2,132,8,125,1,116,
-    0,124,1,136,0,131,2,1,0,124,1,83,0,41,3,122,
-    47,68,101,99,111,114,97,116,111,114,32,116,111,32,118,101,
-    114,105,102,121,32,116,104,101,32,110,97,109,101,100,32,109,
-    111,100,117,108,101,32,105,115,32,102,114,111,122,101,110,46,
-    99,2,0,0,0,0,0,0,0,2,0,0,0,4,0,0,
-    0,19,0,0,0,115,38,0,0,0,116,0,106,1,124,1,
-    131,1,115,28,116,2,100,1,106,3,124,1,131,1,124,1,
-    100,2,141,2,130,1,136,0,124,0,124,1,131,2,83,0,
-    41,3,78,122,27,123,33,114,125,32,105,115,32,110,111,116,
-    32,97,32,102,114,111,122,101,110,32,109,111,100,117,108,101,
-    41,1,114,15,0,0,0,41,4,114,49,0,0,0,218,9,
-    105,115,95,102,114,111,122,101,110,114,71,0,0,0,114,38,
-    0,0,0,41,2,114,26,0,0,0,114,72,0,0,0,41,
-    1,114,73,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,24,95,114,101,113,117,105,114,101,115,95,102,114,111,122,
-    101,110,95,119,114,97,112,112,101,114,243,0,0,0,115,8,
-    0,0,0,0,1,10,1,10,1,8,1,122,50,95,114,101,
-    113,117,105,114,101,115,95,102,114,111,122,101,110,46,60,108,
-    111,99,97,108,115,62,46,95,114,101,113,117,105,114,101,115,
-    95,102,114,111,122,101,110,95,119,114,97,112,112,101,114,41,
-    1,114,12,0,0,0,41,2,114,73,0,0,0,114,77,0,
-    0,0,114,10,0,0,0,41,1,114,73,0,0,0,114,11,
-    0,0,0,218,16,95,114,101,113,117,105,114,101,115,95,102,
-    114,111,122,101,110,241,0,0,0,115,6,0,0,0,0,2,
-    12,5,10,1,114,78,0,0,0,99,2,0,0,0,0,0,
-    0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,62,
-    0,0,0,116,0,124,1,124,0,131,2,125,2,124,1,116,
-    1,106,2,107,6,114,50,116,1,106,2,124,1,25,0,125,
-    3,116,3,124,2,124,3,131,2,1,0,116,1,106,2,124,
-    1,25,0,83,0,116,4,124,2,131,1,83,0,100,1,83,
-    0,41,2,122,128,76,111,97,100,32,116,104,101,32,115,112,
-    101,99,105,102,105,101,100,32,109,111,100,117,108,101,32,105,
-    110,116,111,32,115,121,115,46,109,111,100,117,108,101,115,32,
-    97,110,100,32,114,101,116,117,114,110,32,105,116,46,10,10,
-    32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32,
-    105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32,
-    85,115,101,32,108,111,97,100,101,114,46,101,120,101,99,95,
-    109,111,100,117,108,101,32,105,110,115,116,101,97,100,46,10,
-    10,32,32,32,32,78,41,5,218,16,115,112,101,99,95,102,
-    114,111,109,95,108,111,97,100,101,114,114,14,0,0,0,218,
-    7,109,111,100,117,108,101,115,218,5,95,101,120,101,99,218,
-    5,95,108,111,97,100,41,4,114,26,0,0,0,114,72,0,
-    0,0,218,4,115,112,101,99,218,6,109,111,100,117,108,101,
-    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
-    17,95,108,111,97,100,95,109,111,100,117,108,101,95,115,104,
-    105,109,253,0,0,0,115,12,0,0,0,0,6,10,1,10,
-    1,10,1,10,1,10,2,114,85,0,0,0,99,1,0,0,
-    0,0,0,0,0,5,0,0,0,35,0,0,0,67,0,0,
-    0,115,216,0,0,0,116,0,124,0,100,1,100,0,131,3,
-    125,1,116,1,124,1,100,2,131,2,114,54,121,10,124,1,
-    106,2,124,0,131,1,83,0,4,0,116,3,107,10,114,52,
-    1,0,1,0,1,0,89,0,110,2,88,0,121,10,124,0,
-    106,4,125,2,87,0,110,20,4,0,116,5,107,10,114,84,
-    1,0,1,0,1,0,89,0,110,18,88,0,124,2,100,0,
-    107,9,114,102,116,6,124,2,131,1,83,0,121,10,124,0,
-    106,7,125,3,87,0,110,24,4,0,116,5,107,10,114,136,
-    1,0,1,0,1,0,100,3,125,3,89,0,110,2,88,0,
-    121,10,124,0,106,8,125,4,87,0,110,50,4,0,116,5,
-    107,10,114,198,1,0,1,0,1,0,124,1,100,0,107,8,
-    114,182,100,4,106,9,124,3,131,1,83,0,100,5,106,9,
-    124,3,124,1,131,2,83,0,89,0,110,14,88,0,100,6,
-    106,9,124,3,124,4,131,2,83,0,100,0,83,0,41,7,
-    78,218,10,95,95,108,111,97,100,101,114,95,95,218,11,109,
-    111,100,117,108,101,95,114,101,112,114,250,1,63,122,13,60,
-    109,111,100,117,108,101,32,123,33,114,125,62,122,20,60,109,
-    111,100,117,108,101,32,123,33,114,125,32,40,123,33,114,125,
-    41,62,122,23,60,109,111,100,117,108,101,32,123,33,114,125,
-    32,102,114,111,109,32,123,33,114,125,62,41,10,114,6,0,
-    0,0,114,4,0,0,0,114,87,0,0,0,218,9,69,120,
-    99,101,112,116,105,111,110,218,8,95,95,115,112,101,99,95,
-    95,218,14,65,116,116,114,105,98,117,116,101,69,114,114,111,
-    114,218,22,95,109,111,100,117,108,101,95,114,101,112,114,95,
-    102,114,111,109,95,115,112,101,99,114,1,0,0,0,218,8,
-    95,95,102,105,108,101,95,95,114,38,0,0,0,41,5,114,
-    84,0,0,0,218,6,108,111,97,100,101,114,114,83,0,0,
-    0,114,15,0,0,0,218,8,102,105,108,101,110,97,109,101,
-    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
-    12,95,109,111,100,117,108,101,95,114,101,112,114,13,1,0,
-    0,115,46,0,0,0,0,2,12,1,10,4,2,1,10,1,
-    14,1,6,1,2,1,10,1,14,1,6,2,8,1,8,4,
-    2,1,10,1,14,1,10,1,2,1,10,1,14,1,8,1,
-    10,2,18,2,114,96,0,0,0,99,0,0,0,0,0,0,
-    0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,36,
-    0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132,
-    0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,
-    0,90,5,100,7,83,0,41,8,218,17,95,105,110,115,116,
-    97,108,108,101,100,95,115,97,102,101,108,121,99,2,0,0,
-    0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,
-    0,115,18,0,0,0,124,1,124,0,95,0,124,1,106,1,
-    124,0,95,2,100,0,83,0,41,1,78,41,3,218,7,95,
-    109,111,100,117,108,101,114,90,0,0,0,218,5,95,115,112,
-    101,99,41,2,114,26,0,0,0,114,84,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,114,27,0,
-    0,0,51,1,0,0,115,4,0,0,0,0,1,6,1,122,
-    26,95,105,110,115,116,97,108,108,101,100,95,115,97,102,101,
-    108,121,46,95,95,105,110,105,116,95,95,99,1,0,0,0,
+    0,218,8,95,95,114,101,112,114,95,95,116,0,0,0,115,
+    2,0,0,0,0,1,122,20,95,77,111,100,117,108,101,76,
+    111,99,107,46,95,95,114,101,112,114,95,95,78,41,9,114,
+    1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,
+    0,0,0,114,27,0,0,0,114,32,0,0,0,114,34,0,
+    0,0,114,35,0,0,0,114,40,0,0,0,114,10,0,0,
+    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    114,18,0,0,0,52,0,0,0,115,12,0,0,0,8,4,
+    4,2,8,8,8,12,8,25,8,13,114,18,0,0,0,99,
+    0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+    64,0,0,0,115,48,0,0,0,101,0,90,1,100,0,90,
+    2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,
+    5,132,0,90,5,100,6,100,7,132,0,90,6,100,8,100,
+    9,132,0,90,7,100,10,83,0,41,11,218,16,95,68,117,
+    109,109,121,77,111,100,117,108,101,76,111,99,107,122,86,65,
+    32,115,105,109,112,108,101,32,95,77,111,100,117,108,101,76,
+    111,99,107,32,101,113,117,105,118,97,108,101,110,116,32,102,
+    111,114,32,80,121,116,104,111,110,32,98,117,105,108,100,115,
+    32,119,105,116,104,111,117,116,10,32,32,32,32,109,117,108,
+    116,105,45,116,104,114,101,97,100,105,110,103,32,115,117,112,
+    112,111,114,116,46,99,2,0,0,0,0,0,0,0,2,0,
+    0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124,
+    1,124,0,95,0,100,1,124,0,95,1,100,0,83,0,41,
+    2,78,114,19,0,0,0,41,2,114,15,0,0,0,114,24,
+    0,0,0,41,2,114,26,0,0,0,114,15,0,0,0,114,
+    10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,27,
+    0,0,0,124,0,0,0,115,4,0,0,0,0,1,6,1,
+    122,25,95,68,117,109,109,121,77,111,100,117,108,101,76,111,
+    99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0,
     0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,
-    115,28,0,0,0,100,1,124,0,106,0,95,1,124,0,106,
-    2,116,3,106,4,124,0,106,0,106,5,60,0,100,0,83,
-    0,41,2,78,84,41,6,114,99,0,0,0,218,13,95,105,
-    110,105,116,105,97,108,105,122,105,110,103,114,98,0,0,0,
-    114,14,0,0,0,114,80,0,0,0,114,15,0,0,0,41,
-    1,114,26,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,11,0,0,0,114,46,0,0,0,55,1,0,0,115,4,
-    0,0,0,0,4,8,1,122,27,95,105,110,115,116,97,108,
-    108,101,100,95,115,97,102,101,108,121,46,95,95,101,110,116,
-    101,114,95,95,99,1,0,0,0,0,0,0,0,3,0,0,
-    0,17,0,0,0,71,0,0,0,115,98,0,0,0,122,82,
-    124,0,106,0,125,2,116,1,100,1,100,2,132,0,124,1,
-    68,0,131,1,131,1,114,64,121,14,116,2,106,3,124,2,
-    106,4,61,0,87,0,113,80,4,0,116,5,107,10,114,60,
-    1,0,1,0,1,0,89,0,113,80,88,0,110,16,116,6,
-    100,3,124,2,106,4,124,2,106,7,131,3,1,0,87,0,
-    100,0,100,4,124,0,106,0,95,8,88,0,100,0,83,0,
-    41,5,78,99,1,0,0,0,0,0,0,0,2,0,0,0,
-    3,0,0,0,115,0,0,0,115,22,0,0,0,124,0,93,
-    14,125,1,124,1,100,0,107,9,86,0,1,0,113,2,100,
-    0,83,0,41,1,78,114,10,0,0,0,41,2,90,2,46,
-    48,90,3,97,114,103,114,10,0,0,0,114,10,0,0,0,
-    114,11,0,0,0,250,9,60,103,101,110,101,120,112,114,62,
-    65,1,0,0,115,2,0,0,0,4,0,122,45,95,105,110,
-    115,116,97,108,108,101,100,95,115,97,102,101,108,121,46,95,
-    95,101,120,105,116,95,95,46,60,108,111,99,97,108,115,62,
-    46,60,103,101,110,101,120,112,114,62,122,18,105,109,112,111,
-    114,116,32,123,33,114,125,32,35,32,123,33,114,125,70,41,
-    9,114,99,0,0,0,218,3,97,110,121,114,14,0,0,0,
-    114,80,0,0,0,114,15,0,0,0,114,55,0,0,0,114,
-    69,0,0,0,114,94,0,0,0,114,100,0,0,0,41,3,
-    114,26,0,0,0,114,47,0,0,0,114,83,0,0,0,114,
-    10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,48,
-    0,0,0,62,1,0,0,115,18,0,0,0,0,1,2,1,
-    6,1,18,1,2,1,14,1,14,1,8,2,20,2,122,26,
-    95,105,110,115,116,97,108,108,101,100,95,115,97,102,101,108,
-    121,46,95,95,101,120,105,116,95,95,78,41,6,114,1,0,
-    0,0,114,0,0,0,0,114,2,0,0,0,114,27,0,0,
-    0,114,46,0,0,0,114,48,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
-    97,0,0,0,49,1,0,0,115,6,0,0,0,8,2,8,
-    4,8,7,114,97,0,0,0,99,0,0,0,0,0,0,0,
-    0,0,0,0,0,4,0,0,0,64,0,0,0,115,114,0,
-    0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,
-    100,2,100,2,100,3,156,3,100,4,100,5,132,2,90,4,
-    100,6,100,7,132,0,90,5,100,8,100,9,132,0,90,6,
-    101,7,100,10,100,11,132,0,131,1,90,8,101,8,106,9,
-    100,12,100,11,132,0,131,1,90,8,101,7,100,13,100,14,
-    132,0,131,1,90,10,101,7,100,15,100,16,132,0,131,1,
-    90,11,101,11,106,9,100,17,100,16,132,0,131,1,90,11,
-    100,2,83,0,41,18,218,10,77,111,100,117,108,101,83,112,
-    101,99,97,208,5,0,0,84,104,101,32,115,112,101,99,105,
-    102,105,99,97,116,105,111,110,32,102,111,114,32,97,32,109,
-    111,100,117,108,101,44,32,117,115,101,100,32,102,111,114,32,
-    108,111,97,100,105,110,103,46,10,10,32,32,32,32,65,32,
-    109,111,100,117,108,101,39,115,32,115,112,101,99,32,105,115,
-    32,116,104,101,32,115,111,117,114,99,101,32,102,111,114,32,
-    105,110,102,111,114,109,97,116,105,111,110,32,97,98,111,117,
-    116,32,116,104,101,32,109,111,100,117,108,101,46,32,32,70,
-    111,114,10,32,32,32,32,100,97,116,97,32,97,115,115,111,
-    99,105,97,116,101,100,32,119,105,116,104,32,116,104,101,32,
-    109,111,100,117,108,101,44,32,105,110,99,108,117,100,105,110,
-    103,32,115,111,117,114,99,101,44,32,117,115,101,32,116,104,
-    101,32,115,112,101,99,39,115,10,32,32,32,32,108,111,97,
-    100,101,114,46,10,10,32,32,32,32,96,110,97,109,101,96,
-    32,105,115,32,116,104,101,32,97,98,115,111,108,117,116,101,
-    32,110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,
-    117,108,101,46,32,32,96,108,111,97,100,101,114,96,32,105,
-    115,32,116,104,101,32,108,111,97,100,101,114,10,32,32,32,
-    32,116,111,32,117,115,101,32,119,104,101,110,32,108,111,97,
-    100,105,110,103,32,116,104,101,32,109,111,100,117,108,101,46,
-    32,32,96,112,97,114,101,110,116,96,32,105,115,32,116,104,
-    101,32,110,97,109,101,32,111,102,32,116,104,101,10,32,32,
-    32,32,112,97,99,107,97,103,101,32,116,104,101,32,109,111,
-    100,117,108,101,32,105,115,32,105,110,46,32,32,84,104,101,
-    32,112,97,114,101,110,116,32,105,115,32,100,101,114,105,118,
-    101,100,32,102,114,111,109,32,116,104,101,32,110,97,109,101,
-    46,10,10,32,32,32,32,96,105,115,95,112,97,99,107,97,
-    103,101,96,32,100,101,116,101,114,109,105,110,101,115,32,105,
-    102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32,
-    99,111,110,115,105,100,101,114,101,100,32,97,32,112,97,99,
-    107,97,103,101,32,111,114,10,32,32,32,32,110,111,116,46,
-    32,32,79,110,32,109,111,100,117,108,101,115,32,116,104,105,
-    115,32,105,115,32,114,101,102,108,101,99,116,101,100,32,98,
-    121,32,116,104,101,32,96,95,95,112,97,116,104,95,95,96,
-    32,97,116,116,114,105,98,117,116,101,46,10,10,32,32,32,
-    32,96,111,114,105,103,105,110,96,32,105,115,32,116,104,101,
-    32,115,112,101,99,105,102,105,99,32,108,111,99,97,116,105,
-    111,110,32,117,115,101,100,32,98,121,32,116,104,101,32,108,
-    111,97,100,101,114,32,102,114,111,109,32,119,104,105,99,104,
-    32,116,111,10,32,32,32,32,108,111,97,100,32,116,104,101,
-    32,109,111,100,117,108,101,44,32,105,102,32,116,104,97,116,
-    32,105,110,102,111,114,109,97,116,105,111,110,32,105,115,32,
-    97,118,97,105,108,97,98,108,101,46,32,32,87,104,101,110,
-    32,102,105,108,101,110,97,109,101,32,105,115,10,32,32,32,
-    32,115,101,116,44,32,111,114,105,103,105,110,32,119,105,108,
-    108,32,109,97,116,99,104,46,10,10,32,32,32,32,96,104,
-    97,115,95,108,111,99,97,116,105,111,110,96,32,105,110,100,
-    105,99,97,116,101,115,32,116,104,97,116,32,97,32,115,112,
-    101,99,39,115,32,34,111,114,105,103,105,110,34,32,114,101,
-    102,108,101,99,116,115,32,97,32,108,111,99,97,116,105,111,
-    110,46,10,32,32,32,32,87,104,101,110,32,116,104,105,115,
-    32,105,115,32,84,114,117,101,44,32,96,95,95,102,105,108,
-    101,95,95,96,32,97,116,116,114,105,98,117,116,101,32,111,
-    102,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32,
-    115,101,116,46,10,10,32,32,32,32,96,99,97,99,104,101,
-    100,96,32,105,115,32,116,104,101,32,108,111,99,97,116,105,
-    111,110,32,111,102,32,116,104,101,32,99,97,99,104,101,100,
-    32,98,121,116,101,99,111,100,101,32,102,105,108,101,44,32,
-    105,102,32,97,110,121,46,32,32,73,116,10,32,32,32,32,
-    99,111,114,114,101,115,112,111,110,100,115,32,116,111,32,116,
-    104,101,32,96,95,95,99,97,99,104,101,100,95,95,96,32,
-    97,116,116,114,105,98,117,116,101,46,10,10,32,32,32,32,
-    96,115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,
-    104,95,108,111,99,97,116,105,111,110,115,96,32,105,115,32,
-    116,104,101,32,115,101,113,117,101,110,99,101,32,111,102,32,
-    112,97,116,104,32,101,110,116,114,105,101,115,32,116,111,10,
-    32,32,32,32,115,101,97,114,99,104,32,119,104,101,110,32,
-    105,109,112,111,114,116,105,110,103,32,115,117,98,109,111,100,
-    117,108,101,115,46,32,32,73,102,32,115,101,116,44,32,105,
-    115,95,112,97,99,107,97,103,101,32,115,104,111,117,108,100,
-    32,98,101,10,32,32,32,32,84,114,117,101,45,45,97,110,
-    100,32,70,97,108,115,101,32,111,116,104,101,114,119,105,115,
-    101,46,10,10,32,32,32,32,80,97,99,107,97,103,101,115,
-    32,97,114,101,32,115,105,109,112,108,121,32,109,111,100,117,
-    108,101,115,32,116,104,97,116,32,40,109,97,121,41,32,104,
-    97,118,101,32,115,117,98,109,111,100,117,108,101,115,46,32,
-    32,73,102,32,97,32,115,112,101,99,10,32,32,32,32,104,
-    97,115,32,97,32,110,111,110,45,78,111,110,101,32,118,97,
-    108,117,101,32,105,110,32,96,115,117,98,109,111,100,117,108,
-    101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,
-    110,115,96,44,32,116,104,101,32,105,109,112,111,114,116,10,
-    32,32,32,32,115,121,115,116,101,109,32,119,105,108,108,32,
-    99,111,110,115,105,100,101,114,32,109,111,100,117,108,101,115,
-    32,108,111,97,100,101,100,32,102,114,111,109,32,116,104,101,
-    32,115,112,101,99,32,97,115,32,112,97,99,107,97,103,101,
-    115,46,10,10,32,32,32,32,79,110,108,121,32,102,105,110,
-    100,101,114,115,32,40,115,101,101,32,105,109,112,111,114,116,
-    108,105,98,46,97,98,99,46,77,101,116,97,80,97,116,104,
-    70,105,110,100,101,114,32,97,110,100,10,32,32,32,32,105,
-    109,112,111,114,116,108,105,98,46,97,98,99,46,80,97,116,
-    104,69,110,116,114,121,70,105,110,100,101,114,41,32,115,104,
-    111,117,108,100,32,109,111,100,105,102,121,32,77,111,100,117,
-    108,101,83,112,101,99,32,105,110,115,116,97,110,99,101,115,
-    46,10,10,32,32,32,32,78,41,3,218,6,111,114,105,103,
-    105,110,218,12,108,111,97,100,101,114,95,115,116,97,116,101,
-    218,10,105,115,95,112,97,99,107,97,103,101,99,3,0,0,
-    0,3,0,0,0,6,0,0,0,2,0,0,0,67,0,0,
-    0,115,54,0,0,0,124,1,124,0,95,0,124,2,124,0,
-    95,1,124,3,124,0,95,2,124,4,124,0,95,3,124,5,
-    114,32,103,0,110,2,100,0,124,0,95,4,100,1,124,0,
-    95,5,100,0,124,0,95,6,100,0,83,0,41,2,78,70,
-    41,7,114,15,0,0,0,114,94,0,0,0,114,104,0,0,
-    0,114,105,0,0,0,218,26,115,117,98,109,111,100,117,108,
-    101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,
-    110,115,218,13,95,115,101,116,95,102,105,108,101,97,116,116,
-    114,218,7,95,99,97,99,104,101,100,41,6,114,26,0,0,
-    0,114,15,0,0,0,114,94,0,0,0,114,104,0,0,0,
-    114,105,0,0,0,114,106,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,27,0,0,0,113,1,
-    0,0,115,14,0,0,0,0,2,6,1,6,1,6,1,6,
-    1,14,3,6,1,122,19,77,111,100,117,108,101,83,112,101,
-    99,46,95,95,105,110,105,116,95,95,99,1,0,0,0,0,
-    0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,
-    102,0,0,0,100,1,106,0,124,0,106,1,131,1,100,2,
-    106,0,124,0,106,2,131,1,103,2,125,1,124,0,106,3,
-    100,0,107,9,114,52,124,1,106,4,100,3,106,0,124,0,
-    106,3,131,1,131,1,1,0,124,0,106,5,100,0,107,9,
-    114,80,124,1,106,4,100,4,106,0,124,0,106,5,131,1,
-    131,1,1,0,100,5,106,0,124,0,106,6,106,7,100,6,
-    106,8,124,1,131,1,131,2,83,0,41,7,78,122,9,110,
-    97,109,101,61,123,33,114,125,122,11,108,111,97,100,101,114,
-    61,123,33,114,125,122,11,111,114,105,103,105,110,61,123,33,
-    114,125,122,29,115,117,98,109,111,100,117,108,101,95,115,101,
-    97,114,99,104,95,108,111,99,97,116,105,111,110,115,61,123,
-    125,122,6,123,125,40,123,125,41,122,2,44,32,41,9,114,
-    38,0,0,0,114,15,0,0,0,114,94,0,0,0,114,104,
-    0,0,0,218,6,97,112,112,101,110,100,114,107,0,0,0,
-    218,9,95,95,99,108,97,115,115,95,95,114,1,0,0,0,
-    218,4,106,111,105,110,41,2,114,26,0,0,0,114,47,0,
-    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,40,0,0,0,125,1,0,0,115,16,0,0,0,0,
-    1,10,1,14,1,10,1,18,1,10,1,8,1,10,1,122,
-    19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101,
-    112,114,95,95,99,2,0,0,0,0,0,0,0,3,0,0,
-    0,11,0,0,0,67,0,0,0,115,102,0,0,0,124,0,
-    106,0,125,2,121,70,124,0,106,1,124,1,106,1,107,2,
-    111,76,124,0,106,2,124,1,106,2,107,2,111,76,124,0,
-    106,3,124,1,106,3,107,2,111,76,124,2,124,1,106,0,
-    107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76,
-    124,0,106,5,124,1,106,5,107,2,83,0,4,0,116,6,
-    107,10,114,96,1,0,1,0,1,0,100,1,83,0,88,0,
-    100,0,83,0,41,2,78,70,41,7,114,107,0,0,0,114,
-    15,0,0,0,114,94,0,0,0,114,104,0,0,0,218,6,
-    99,97,99,104,101,100,218,12,104,97,115,95,108,111,99,97,
-    116,105,111,110,114,91,0,0,0,41,3,114,26,0,0,0,
-    90,5,111,116,104,101,114,90,4,115,109,115,108,114,10,0,
-    0,0,114,10,0,0,0,114,11,0,0,0,218,6,95,95,
-    101,113,95,95,135,1,0,0,115,20,0,0,0,0,1,6,
-    1,2,1,12,1,12,1,12,1,10,1,12,1,12,1,14,
-    1,122,17,77,111,100,117,108,101,83,112,101,99,46,95,95,
-    101,113,95,95,99,1,0,0,0,0,0,0,0,1,0,0,
-    0,2,0,0,0,67,0,0,0,115,58,0,0,0,124,0,
-    106,0,100,0,107,8,114,52,124,0,106,1,100,0,107,9,
-    114,52,124,0,106,2,114,52,116,3,100,0,107,8,114,38,
-    116,4,130,1,116,3,106,5,124,0,106,1,131,1,124,0,
-    95,0,124,0,106,0,83,0,41,1,78,41,6,114,109,0,
-    0,0,114,104,0,0,0,114,108,0,0,0,218,19,95,98,
-    111,111,116,115,116,114,97,112,95,101,120,116,101,114,110,97,
-    108,218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,
-    100,69,114,114,111,114,90,11,95,103,101,116,95,99,97,99,
-    104,101,100,41,1,114,26,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,113,0,0,0,147,1,
-    0,0,115,12,0,0,0,0,2,10,1,16,1,8,1,4,
-    1,14,1,122,17,77,111,100,117,108,101,83,112,101,99,46,
-    99,97,99,104,101,100,99,2,0,0,0,0,0,0,0,2,
-    0,0,0,2,0,0,0,67,0,0,0,115,10,0,0,0,
-    124,1,124,0,95,0,100,0,83,0,41,1,78,41,1,114,
-    109,0,0,0,41,2,114,26,0,0,0,114,113,0,0,0,
-    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
-    113,0,0,0,156,1,0,0,115,2,0,0,0,0,2,99,
-    1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,
-    67,0,0,0,115,36,0,0,0,124,0,106,0,100,1,107,
-    8,114,26,124,0,106,1,106,2,100,2,131,1,100,3,25,
-    0,83,0,124,0,106,1,83,0,100,1,83,0,41,4,122,
-    32,84,104,101,32,110,97,109,101,32,111,102,32,116,104,101,
-    32,109,111,100,117,108,101,39,115,32,112,97,114,101,110,116,
-    46,78,218,1,46,114,19,0,0,0,41,3,114,107,0,0,
-    0,114,15,0,0,0,218,10,114,112,97,114,116,105,116,105,
-    111,110,41,1,114,26,0,0,0,114,10,0,0,0,114,10,
-    0,0,0,114,11,0,0,0,218,6,112,97,114,101,110,116,
-    160,1,0,0,115,6,0,0,0,0,3,10,1,16,2,122,
-    17,77,111,100,117,108,101,83,112,101,99,46,112,97,114,101,
-    110,116,99,1,0,0,0,0,0,0,0,1,0,0,0,1,
-    0,0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,
-    83,0,41,1,78,41,1,114,108,0,0,0,41,1,114,26,
-    0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,114,114,0,0,0,168,1,0,0,115,2,0,0,0,
-    0,2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,
-    97,115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,
-    0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,
-    115,14,0,0,0,116,0,124,1,131,1,124,0,95,1,100,
-    0,83,0,41,1,78,41,2,218,4,98,111,111,108,114,108,
-    0,0,0,41,2,114,26,0,0,0,218,5,118,97,108,117,
-    101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    114,114,0,0,0,172,1,0,0,115,2,0,0,0,0,2,
-    41,12,114,1,0,0,0,114,0,0,0,0,114,2,0,0,
-    0,114,3,0,0,0,114,27,0,0,0,114,40,0,0,0,
-    114,115,0,0,0,218,8,112,114,111,112,101,114,116,121,114,
-    113,0,0,0,218,6,115,101,116,116,101,114,114,120,0,0,
-    0,114,114,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,103,0,0,0,76,
-    1,0,0,115,20,0,0,0,8,35,4,2,4,1,14,11,
-    8,10,8,12,12,9,14,4,12,8,12,4,114,103,0,0,
-    0,41,2,114,104,0,0,0,114,106,0,0,0,99,2,0,
-    0,0,2,0,0,0,6,0,0,0,14,0,0,0,67,0,
-    0,0,115,154,0,0,0,116,0,124,1,100,1,131,2,114,
-    74,116,1,100,2,107,8,114,22,116,2,130,1,116,1,106,
-    3,125,4,124,3,100,2,107,8,114,48,124,4,124,0,124,
-    1,100,3,141,2,83,0,124,3,114,56,103,0,110,2,100,
-    2,125,5,124,4,124,0,124,1,124,5,100,4,141,3,83,
-    0,124,3,100,2,107,8,114,138,116,0,124,1,100,5,131,
-    2,114,134,121,14,124,1,106,4,124,0,131,1,125,3,87,
-    0,113,138,4,0,116,5,107,10,114,130,1,0,1,0,1,
-    0,100,2,125,3,89,0,113,138,88,0,110,4,100,6,125,
-    3,116,6,124,0,124,1,124,2,124,3,100,7,141,4,83,
-    0,41,8,122,53,82,101,116,117,114,110,32,97,32,109,111,
-    100,117,108,101,32,115,112,101,99,32,98,97,115,101,100,32,
-    111,110,32,118,97,114,105,111,117,115,32,108,111,97,100,101,
-    114,32,109,101,116,104,111,100,115,46,90,12,103,101,116,95,
-    102,105,108,101,110,97,109,101,78,41,1,114,94,0,0,0,
-    41,2,114,94,0,0,0,114,107,0,0,0,114,106,0,0,
-    0,70,41,2,114,104,0,0,0,114,106,0,0,0,41,7,
-    114,4,0,0,0,114,116,0,0,0,114,117,0,0,0,218,
-    23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95,
-    108,111,99,97,116,105,111,110,114,106,0,0,0,114,71,0,
-    0,0,114,103,0,0,0,41,6,114,15,0,0,0,114,94,
-    0,0,0,114,104,0,0,0,114,106,0,0,0,114,125,0,
-    0,0,90,6,115,101,97,114,99,104,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,79,0,0,0,177,1,
-    0,0,115,34,0,0,0,0,2,10,1,8,1,4,1,6,
-    2,8,1,12,1,12,1,6,1,8,2,8,1,10,1,2,
-    1,14,1,14,1,12,3,4,2,114,79,0,0,0,99,3,
-    0,0,0,0,0,0,0,8,0,0,0,53,0,0,0,67,
-    0,0,0,115,56,1,0,0,121,10,124,0,106,0,125,3,
-    87,0,110,20,4,0,116,1,107,10,114,30,1,0,1,0,
-    1,0,89,0,110,14,88,0,124,3,100,0,107,9,114,44,
-    124,3,83,0,124,0,106,2,125,4,124,1,100,0,107,8,
-    114,90,121,10,124,0,106,3,125,1,87,0,110,20,4,0,
-    116,1,107,10,114,88,1,0,1,0,1,0,89,0,110,2,
-    88,0,121,10,124,0,106,4,125,5,87,0,110,24,4,0,
-    116,1,107,10,114,124,1,0,1,0,1,0,100,0,125,5,
-    89,0,110,2,88,0,124,2,100,0,107,8,114,184,124,5,
-    100,0,107,8,114,180,121,10,124,1,106,5,125,2,87,0,
-    113,184,4,0,116,1,107,10,114,176,1,0,1,0,1,0,
-    100,0,125,2,89,0,113,184,88,0,110,4,124,5,125,2,
-    121,10,124,0,106,6,125,6,87,0,110,24,4,0,116,1,
-    107,10,114,218,1,0,1,0,1,0,100,0,125,6,89,0,
-    110,2,88,0,121,14,116,7,124,0,106,8,131,1,125,7,
-    87,0,110,26,4,0,116,1,107,10,144,1,114,4,1,0,
-    1,0,1,0,100,0,125,7,89,0,110,2,88,0,116,9,
-    124,4,124,1,124,2,100,1,141,3,125,3,124,5,100,0,
-    107,8,144,1,114,34,100,2,110,2,100,3,124,3,95,10,
-    124,6,124,3,95,11,124,7,124,3,95,12,124,3,83,0,
-    41,4,78,41,1,114,104,0,0,0,70,84,41,13,114,90,
-    0,0,0,114,91,0,0,0,114,1,0,0,0,114,86,0,
-    0,0,114,93,0,0,0,90,7,95,79,82,73,71,73,78,
-    218,10,95,95,99,97,99,104,101,100,95,95,218,4,108,105,
-    115,116,218,8,95,95,112,97,116,104,95,95,114,103,0,0,
-    0,114,108,0,0,0,114,113,0,0,0,114,107,0,0,0,
-    41,8,114,84,0,0,0,114,94,0,0,0,114,104,0,0,
-    0,114,83,0,0,0,114,15,0,0,0,90,8,108,111,99,
-    97,116,105,111,110,114,113,0,0,0,114,107,0,0,0,114,
-    10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,17,
-    95,115,112,101,99,95,102,114,111,109,95,109,111,100,117,108,
-    101,203,1,0,0,115,72,0,0,0,0,2,2,1,10,1,
-    14,1,6,2,8,1,4,2,6,1,8,1,2,1,10,1,
-    14,2,6,1,2,1,10,1,14,1,10,1,8,1,8,1,
-    2,1,10,1,14,1,12,2,4,1,2,1,10,1,14,1,
-    10,1,2,1,14,1,16,1,10,2,14,1,20,1,6,1,
-    6,1,114,129,0,0,0,70,41,1,218,8,111,118,101,114,
-    114,105,100,101,99,2,0,0,0,1,0,0,0,5,0,0,
-    0,59,0,0,0,67,0,0,0,115,212,1,0,0,124,2,
-    115,20,116,0,124,1,100,1,100,0,131,3,100,0,107,8,
-    114,54,121,12,124,0,106,1,124,1,95,2,87,0,110,20,
-    4,0,116,3,107,10,114,52,1,0,1,0,1,0,89,0,
-    110,2,88,0,124,2,115,74,116,0,124,1,100,2,100,0,
-    131,3,100,0,107,8,114,166,124,0,106,4,125,3,124,3,
-    100,0,107,8,114,134,124,0,106,5,100,0,107,9,114,134,
-    116,6,100,0,107,8,114,110,116,7,130,1,116,6,106,8,
-    125,4,124,4,106,9,124,4,131,1,125,3,124,0,106,5,
-    124,3,95,10,121,10,124,3,124,1,95,11,87,0,110,20,
-    4,0,116,3,107,10,114,164,1,0,1,0,1,0,89,0,
-    110,2,88,0,124,2,115,186,116,0,124,1,100,3,100,0,
-    131,3,100,0,107,8,114,220,121,12,124,0,106,12,124,1,
-    95,13,87,0,110,20,4,0,116,3,107,10,114,218,1,0,
-    1,0,1,0,89,0,110,2,88,0,121,10,124,0,124,1,
-    95,14,87,0,110,20,4,0,116,3,107,10,114,250,1,0,
-    1,0,1,0,89,0,110,2,88,0,124,2,144,1,115,20,
-    116,0,124,1,100,4,100,0,131,3,100,0,107,8,144,1,
-    114,68,124,0,106,5,100,0,107,9,144,1,114,68,121,12,
-    124,0,106,5,124,1,95,15,87,0,110,22,4,0,116,3,
-    107,10,144,1,114,66,1,0,1,0,1,0,89,0,110,2,
-    88,0,124,0,106,16,144,1,114,208,124,2,144,1,115,100,
-    116,0,124,1,100,5,100,0,131,3,100,0,107,8,144,1,
-    114,136,121,12,124,0,106,17,124,1,95,18,87,0,110,22,
-    4,0,116,3,107,10,144,1,114,134,1,0,1,0,1,0,
-    89,0,110,2,88,0,124,2,144,1,115,160,116,0,124,1,
-    100,6,100,0,131,3,100,0,107,8,144,1,114,208,124,0,
-    106,19,100,0,107,9,144,1,114,208,121,12,124,0,106,19,
-    124,1,95,20,87,0,110,22,4,0,116,3,107,10,144,1,
-    114,206,1,0,1,0,1,0,89,0,110,2,88,0,124,1,
-    83,0,41,7,78,114,1,0,0,0,114,86,0,0,0,218,
-    11,95,95,112,97,99,107,97,103,101,95,95,114,128,0,0,
-    0,114,93,0,0,0,114,126,0,0,0,41,21,114,6,0,
-    0,0,114,15,0,0,0,114,1,0,0,0,114,91,0,0,
-    0,114,94,0,0,0,114,107,0,0,0,114,116,0,0,0,
-    114,117,0,0,0,218,16,95,78,97,109,101,115,112,97,99,
-    101,76,111,97,100,101,114,218,7,95,95,110,101,119,95,95,
-    90,5,95,112,97,116,104,114,86,0,0,0,114,120,0,0,
-    0,114,131,0,0,0,114,90,0,0,0,114,128,0,0,0,
-    114,114,0,0,0,114,104,0,0,0,114,93,0,0,0,114,
-    113,0,0,0,114,126,0,0,0,41,5,114,83,0,0,0,
-    114,84,0,0,0,114,130,0,0,0,114,94,0,0,0,114,
-    132,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
-    0,0,0,218,18,95,105,110,105,116,95,109,111,100,117,108,
-    101,95,97,116,116,114,115,248,1,0,0,115,92,0,0,0,
-    0,4,20,1,2,1,12,1,14,1,6,2,20,1,6,1,
-    8,2,10,1,8,1,4,1,6,2,10,1,8,1,2,1,
-    10,1,14,1,6,2,20,1,2,1,12,1,14,1,6,2,
-    2,1,10,1,14,1,6,2,24,1,12,1,2,1,12,1,
-    16,1,6,2,8,1,24,1,2,1,12,1,16,1,6,2,
-    24,1,12,1,2,1,12,1,16,1,6,1,114,134,0,0,
-    0,99,1,0,0,0,0,0,0,0,2,0,0,0,3,0,
-    0,0,67,0,0,0,115,82,0,0,0,100,1,125,1,116,
-    0,124,0,106,1,100,2,131,2,114,30,124,0,106,1,106,
-    2,124,0,131,1,125,1,110,20,116,0,124,0,106,1,100,
-    3,131,2,114,50,116,3,100,4,131,1,130,1,124,1,100,
-    1,107,8,114,68,116,4,124,0,106,5,131,1,125,1,116,
-    6,124,0,124,1,131,2,1,0,124,1,83,0,41,5,122,
-    43,67,114,101,97,116,101,32,97,32,109,111,100,117,108,101,
-    32,98,97,115,101,100,32,111,110,32,116,104,101,32,112,114,
-    111,118,105,100,101,100,32,115,112,101,99,46,78,218,13,99,
-    114,101,97,116,101,95,109,111,100,117,108,101,218,11,101,120,
-    101,99,95,109,111,100,117,108,101,122,66,108,111,97,100,101,
-    114,115,32,116,104,97,116,32,100,101,102,105,110,101,32,101,
-    120,101,99,95,109,111,100,117,108,101,40,41,32,109,117,115,
-    116,32,97,108,115,111,32,100,101,102,105,110,101,32,99,114,
-    101,97,116,101,95,109,111,100,117,108,101,40,41,41,7,114,
-    4,0,0,0,114,94,0,0,0,114,135,0,0,0,114,71,
-    0,0,0,114,16,0,0,0,114,15,0,0,0,114,134,0,
-    0,0,41,2,114,83,0,0,0,114,84,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,218,16,109,
-    111,100,117,108,101,95,102,114,111,109,95,115,112,101,99,52,
-    2,0,0,115,18,0,0,0,0,3,4,1,12,3,14,1,
-    12,1,8,2,8,1,10,1,10,1,114,137,0,0,0,99,
+    115,18,0,0,0,124,0,4,0,106,0,100,1,55,0,2,
+    0,95,0,100,2,83,0,41,3,78,114,33,0,0,0,84,
+    41,1,114,24,0,0,0,41,1,114,26,0,0,0,114,10,
+    0,0,0,114,10,0,0,0,114,11,0,0,0,114,34,0,
+    0,0,128,0,0,0,115,4,0,0,0,0,1,14,1,122,
+    24,95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,
+    107,46,97,99,113,117,105,114,101,99,1,0,0,0,0,0,
+    0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,36,
+    0,0,0,124,0,106,0,100,1,107,2,114,18,116,1,100,
+    2,131,1,130,1,124,0,4,0,106,0,100,3,56,0,2,
+    0,95,0,100,0,83,0,41,4,78,114,19,0,0,0,122,
+    31,99,97,110,110,111,116,32,114,101,108,101,97,115,101,32,
+    117,110,45,97,99,113,117,105,114,101,100,32,108,111,99,107,
+    114,33,0,0,0,41,2,114,24,0,0,0,114,36,0,0,
+    0,41,1,114,26,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,35,0,0,0,132,0,0,0,
+    115,6,0,0,0,0,1,10,1,8,1,122,24,95,68,117,
+    109,109,121,77,111,100,117,108,101,76,111,99,107,46,114,101,
+    108,101,97,115,101,99,1,0,0,0,0,0,0,0,1,0,
+    0,0,4,0,0,0,67,0,0,0,115,18,0,0,0,100,
+    1,106,0,124,0,106,1,116,2,124,0,131,1,131,2,83,
+    0,41,2,78,122,28,95,68,117,109,109,121,77,111,100,117,
+    108,101,76,111,99,107,40,123,33,114,125,41,32,97,116,32,
+    123,125,41,3,114,38,0,0,0,114,15,0,0,0,114,39,
+    0,0,0,41,1,114,26,0,0,0,114,10,0,0,0,114,
+    10,0,0,0,114,11,0,0,0,114,40,0,0,0,137,0,
+    0,0,115,2,0,0,0,0,1,122,25,95,68,117,109,109,
+    121,77,111,100,117,108,101,76,111,99,107,46,95,95,114,101,
+    112,114,95,95,78,41,8,114,1,0,0,0,114,0,0,0,
+    0,114,2,0,0,0,114,3,0,0,0,114,27,0,0,0,
+    114,34,0,0,0,114,35,0,0,0,114,40,0,0,0,114,
+    10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,41,0,0,0,120,0,0,0,115,10,0,0,
+    0,8,2,4,2,8,4,8,4,8,5,114,41,0,0,0,
+    99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
+    0,64,0,0,0,115,36,0,0,0,101,0,90,1,100,0,
+    90,2,100,1,100,2,132,0,90,3,100,3,100,4,132,0,
+    90,4,100,5,100,6,132,0,90,5,100,7,83,0,41,8,
+    218,18,95,77,111,100,117,108,101,76,111,99,107,77,97,110,
+    97,103,101,114,99,2,0,0,0,0,0,0,0,2,0,0,
+    0,2,0,0,0,67,0,0,0,115,16,0,0,0,124,1,
+    124,0,95,0,100,0,124,0,95,1,100,0,83,0,41,1,
+    78,41,2,218,5,95,110,97,109,101,218,5,95,108,111,99,
+    107,41,2,114,26,0,0,0,114,15,0,0,0,114,10,0,
+    0,0,114,10,0,0,0,114,11,0,0,0,114,27,0,0,
+    0,143,0,0,0,115,4,0,0,0,0,1,6,1,122,27,
+    95,77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,
+    101,114,46,95,95,105,110,105,116,95,95,99,1,0,0,0,
+    0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0,
+    115,26,0,0,0,116,0,124,0,106,1,131,1,124,0,95,
+    2,124,0,106,2,106,3,131,0,1,0,100,0,83,0,41,
+    1,78,41,4,218,16,95,103,101,116,95,109,111,100,117,108,
+    101,95,108,111,99,107,114,43,0,0,0,114,44,0,0,0,
+    114,34,0,0,0,41,1,114,26,0,0,0,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,218,9,95,95,101,
+    110,116,101,114,95,95,147,0,0,0,115,4,0,0,0,0,
+    1,12,1,122,28,95,77,111,100,117,108,101,76,111,99,107,
+    77,97,110,97,103,101,114,46,95,95,101,110,116,101,114,95,
+    95,99,1,0,0,0,0,0,0,0,3,0,0,0,1,0,
+    0,0,79,0,0,0,115,14,0,0,0,124,0,106,0,106,
+    1,131,0,1,0,100,0,83,0,41,1,78,41,2,114,44,
+    0,0,0,114,35,0,0,0,41,3,114,26,0,0,0,218,
+    4,97,114,103,115,90,6,107,119,97,114,103,115,114,10,0,
+    0,0,114,10,0,0,0,114,11,0,0,0,218,8,95,95,
+    101,120,105,116,95,95,151,0,0,0,115,2,0,0,0,0,
+    1,122,27,95,77,111,100,117,108,101,76,111,99,107,77,97,
+    110,97,103,101,114,46,95,95,101,120,105,116,95,95,78,41,
+    6,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,
+    114,27,0,0,0,114,46,0,0,0,114,48,0,0,0,114,
+    10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,42,0,0,0,141,0,0,0,115,6,0,0,
+    0,8,2,8,4,8,4,114,42,0,0,0,99,1,0,0,
+    0,0,0,0,0,3,0,0,0,17,0,0,0,67,0,0,
+    0,115,130,0,0,0,116,0,106,1,131,0,1,0,122,106,
+    121,14,116,2,124,0,25,0,131,0,125,1,87,0,110,24,
+    4,0,116,3,107,10,114,48,1,0,1,0,1,0,100,1,
+    125,1,89,0,110,2,88,0,124,1,100,1,107,8,114,112,
+    116,4,100,1,107,8,114,76,116,5,124,0,131,1,125,1,
+    110,8,116,6,124,0,131,1,125,1,124,0,102,1,100,2,
+    100,3,132,1,125,2,116,7,106,8,124,1,124,2,131,2,
+    116,2,124,0,60,0,87,0,100,1,116,0,106,9,131,0,
+    1,0,88,0,124,1,83,0,41,4,122,139,71,101,116,32,
+    111,114,32,99,114,101,97,116,101,32,116,104,101,32,109,111,
+    100,117,108,101,32,108,111,99,107,32,102,111,114,32,97,32,
+    103,105,118,101,110,32,109,111,100,117,108,101,32,110,97,109,
+    101,46,10,10,32,32,32,32,65,99,113,117,105,114,101,47,
+    114,101,108,101,97,115,101,32,105,110,116,101,114,110,97,108,
+    108,121,32,116,104,101,32,103,108,111,98,97,108,32,105,109,
+    112,111,114,116,32,108,111,99,107,32,116,111,32,112,114,111,
+    116,101,99,116,10,32,32,32,32,95,109,111,100,117,108,101,
+    95,108,111,99,107,115,46,78,99,2,0,0,0,0,0,0,
+    0,2,0,0,0,10,0,0,0,83,0,0,0,115,48,0,
+    0,0,116,0,106,1,131,0,1,0,122,24,116,2,106,3,
+    124,1,131,1,124,0,107,8,114,30,116,2,124,1,61,0,
+    87,0,100,0,116,0,106,4,131,0,1,0,88,0,100,0,
+    83,0,41,1,78,41,5,218,4,95,105,109,112,218,12,97,
+    99,113,117,105,114,101,95,108,111,99,107,218,13,95,109,111,
+    100,117,108,101,95,108,111,99,107,115,114,30,0,0,0,218,
+    12,114,101,108,101,97,115,101,95,108,111,99,107,41,2,218,
+    3,114,101,102,114,15,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,218,2,99,98,176,0,0,0,
+    115,10,0,0,0,0,1,8,1,2,4,14,1,10,2,122,
+    28,95,103,101,116,95,109,111,100,117,108,101,95,108,111,99,
+    107,46,60,108,111,99,97,108,115,62,46,99,98,41,10,114,
+    49,0,0,0,114,50,0,0,0,114,51,0,0,0,218,8,
+    75,101,121,69,114,114,111,114,114,20,0,0,0,114,41,0,
+    0,0,114,18,0,0,0,218,8,95,119,101,97,107,114,101,
+    102,114,53,0,0,0,114,52,0,0,0,41,3,114,15,0,
+    0,0,114,21,0,0,0,114,54,0,0,0,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,114,45,0,0,0,
+    157,0,0,0,115,28,0,0,0,0,6,8,1,2,1,2,
+    1,14,1,14,1,10,2,8,1,8,1,10,2,8,2,12,
+    11,20,2,10,2,114,45,0,0,0,99,1,0,0,0,0,
+    0,0,0,2,0,0,0,11,0,0,0,67,0,0,0,115,
+    54,0,0,0,116,0,124,0,131,1,125,1,121,12,124,1,
+    106,1,131,0,1,0,87,0,110,20,4,0,116,2,107,10,
+    114,40,1,0,1,0,1,0,89,0,110,10,88,0,124,1,
+    106,3,131,0,1,0,100,1,83,0,41,2,122,189,65,99,
+    113,117,105,114,101,115,32,116,104,101,110,32,114,101,108,101,
+    97,115,101,115,32,116,104,101,32,109,111,100,117,108,101,32,
+    108,111,99,107,32,102,111,114,32,97,32,103,105,118,101,110,
+    32,109,111,100,117,108,101,32,110,97,109,101,46,10,10,32,
+    32,32,32,84,104,105,115,32,105,115,32,117,115,101,100,32,
+    116,111,32,101,110,115,117,114,101,32,97,32,109,111,100,117,
+    108,101,32,105,115,32,99,111,109,112,108,101,116,101,108,121,
+    32,105,110,105,116,105,97,108,105,122,101,100,44,32,105,110,
+    32,116,104,101,10,32,32,32,32,101,118,101,110,116,32,105,
+    116,32,105,115,32,98,101,105,110,103,32,105,109,112,111,114,
+    116,101,100,32,98,121,32,97,110,111,116,104,101,114,32,116,
+    104,114,101,97,100,46,10,32,32,32,32,78,41,4,114,45,
+    0,0,0,114,34,0,0,0,114,17,0,0,0,114,35,0,
+    0,0,41,2,114,15,0,0,0,114,21,0,0,0,114,10,
+    0,0,0,114,10,0,0,0,114,11,0,0,0,218,19,95,
+    108,111,99,107,95,117,110,108,111,99,107,95,109,111,100,117,
+    108,101,194,0,0,0,115,12,0,0,0,0,6,8,1,2,
+    1,12,1,14,3,6,2,114,57,0,0,0,99,1,0,0,
+    0,0,0,0,0,3,0,0,0,3,0,0,0,79,0,0,
+    0,115,10,0,0,0,124,0,124,1,124,2,142,1,83,0,
+    41,1,97,46,1,0,0,114,101,109,111,118,101,95,105,109,
+    112,111,114,116,108,105,98,95,102,114,97,109,101,115,32,105,
+    110,32,105,109,112,111,114,116,46,99,32,119,105,108,108,32,
+    97,108,119,97,121,115,32,114,101,109,111,118,101,32,115,101,
+    113,117,101,110,99,101,115,10,32,32,32,32,111,102,32,105,
+    109,112,111,114,116,108,105,98,32,102,114,97,109,101,115,32,
+    116,104,97,116,32,101,110,100,32,119,105,116,104,32,97,32,
+    99,97,108,108,32,116,111,32,116,104,105,115,32,102,117,110,
+    99,116,105,111,110,10,10,32,32,32,32,85,115,101,32,105,
+    116,32,105,110,115,116,101,97,100,32,111,102,32,97,32,110,
+    111,114,109,97,108,32,99,97,108,108,32,105,110,32,112,108,
+    97,99,101,115,32,119,104,101,114,101,32,105,110,99,108,117,
+    100,105,110,103,32,116,104,101,32,105,109,112,111,114,116,108,
+    105,98,10,32,32,32,32,102,114,97,109,101,115,32,105,110,
+    116,114,111,100,117,99,101,115,32,117,110,119,97,110,116,101,
+    100,32,110,111,105,115,101,32,105,110,116,111,32,116,104,101,
+    32,116,114,97,99,101,98,97,99,107,32,40,101,46,103,46,
+    32,119,104,101,110,32,101,120,101,99,117,116,105,110,103,10,
+    32,32,32,32,109,111,100,117,108,101,32,99,111,100,101,41,
+    10,32,32,32,32,114,10,0,0,0,41,3,218,1,102,114,
+    47,0,0,0,90,4,107,119,100,115,114,10,0,0,0,114,
+    10,0,0,0,114,11,0,0,0,218,25,95,99,97,108,108,
+    95,119,105,116,104,95,102,114,97,109,101,115,95,114,101,109,
+    111,118,101,100,211,0,0,0,115,2,0,0,0,0,8,114,
+    59,0,0,0,114,33,0,0,0,41,1,218,9,118,101,114,
+    98,111,115,105,116,121,99,1,0,0,0,1,0,0,0,3,
+    0,0,0,4,0,0,0,71,0,0,0,115,54,0,0,0,
+    116,0,106,1,106,2,124,1,107,5,114,50,124,0,106,3,
+    100,6,131,1,115,30,100,3,124,0,23,0,125,0,116,4,
+    124,0,106,5,124,2,142,0,116,0,106,6,100,4,141,2,
+    1,0,100,5,83,0,41,7,122,61,80,114,105,110,116,32,
+    116,104,101,32,109,101,115,115,97,103,101,32,116,111,32,115,
+    116,100,101,114,114,32,105,102,32,45,118,47,80,89,84,72,
+    79,78,86,69,82,66,79,83,69,32,105,115,32,116,117,114,
+    110,101,100,32,111,110,46,250,1,35,250,7,105,109,112,111,
+    114,116,32,122,2,35,32,41,1,90,4,102,105,108,101,78,
+    41,2,114,61,0,0,0,114,62,0,0,0,41,7,114,14,
+    0,0,0,218,5,102,108,97,103,115,218,7,118,101,114,98,
+    111,115,101,218,10,115,116,97,114,116,115,119,105,116,104,218,
+    5,112,114,105,110,116,114,38,0,0,0,218,6,115,116,100,
+    101,114,114,41,3,218,7,109,101,115,115,97,103,101,114,60,
+    0,0,0,114,47,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,218,16,95,118,101,114,98,111,115,
+    101,95,109,101,115,115,97,103,101,222,0,0,0,115,8,0,
+    0,0,0,2,12,1,10,1,8,1,114,69,0,0,0,99,
     1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
-    67,0,0,0,115,106,0,0,0,124,0,106,0,100,1,107,
-    8,114,14,100,2,110,4,124,0,106,0,125,1,124,0,106,
-    1,100,1,107,8,114,66,124,0,106,2,100,1,107,8,114,
-    50,100,3,106,3,124,1,131,1,83,0,100,4,106,3,124,
-    1,124,0,106,2,131,2,83,0,110,36,124,0,106,4,114,
-    86,100,5,106,3,124,1,124,0,106,1,131,2,83,0,100,
-    6,106,3,124,0,106,0,124,0,106,1,131,2,83,0,100,
-    1,83,0,41,7,122,38,82,101,116,117,114,110,32,116,104,
-    101,32,114,101,112,114,32,116,111,32,117,115,101,32,102,111,
-    114,32,116,104,101,32,109,111,100,117,108,101,46,78,114,88,
-    0,0,0,122,13,60,109,111,100,117,108,101,32,123,33,114,
+    3,0,0,0,115,26,0,0,0,135,0,102,1,100,1,100,
+    2,132,8,125,1,116,0,124,1,136,0,131,2,1,0,124,
+    1,83,0,41,3,122,49,68,101,99,111,114,97,116,111,114,
+    32,116,111,32,118,101,114,105,102,121,32,116,104,101,32,110,
+    97,109,101,100,32,109,111,100,117,108,101,32,105,115,32,98,
+    117,105,108,116,45,105,110,46,99,2,0,0,0,0,0,0,
+    0,2,0,0,0,4,0,0,0,19,0,0,0,115,38,0,
+    0,0,124,1,116,0,106,1,107,7,114,28,116,2,100,1,
+    106,3,124,1,131,1,124,1,100,2,141,2,130,1,136,0,
+    124,0,124,1,131,2,83,0,41,3,78,122,29,123,33,114,
+    125,32,105,115,32,110,111,116,32,97,32,98,117,105,108,116,
+    45,105,110,32,109,111,100,117,108,101,41,1,114,15,0,0,
+    0,41,4,114,14,0,0,0,218,20,98,117,105,108,116,105,
+    110,95,109,111,100,117,108,101,95,110,97,109,101,115,218,11,
+    73,109,112,111,114,116,69,114,114,111,114,114,38,0,0,0,
+    41,2,114,26,0,0,0,218,8,102,117,108,108,110,97,109,
+    101,41,1,218,3,102,120,110,114,10,0,0,0,114,11,0,
+    0,0,218,25,95,114,101,113,117,105,114,101,115,95,98,117,
+    105,108,116,105,110,95,119,114,97,112,112,101,114,232,0,0,
+    0,115,8,0,0,0,0,1,10,1,10,1,8,1,122,52,
+    95,114,101,113,117,105,114,101,115,95,98,117,105,108,116,105,
+    110,46,60,108,111,99,97,108,115,62,46,95,114,101,113,117,
+    105,114,101,115,95,98,117,105,108,116,105,110,95,119,114,97,
+    112,112,101,114,41,1,114,12,0,0,0,41,2,114,73,0,
+    0,0,114,74,0,0,0,114,10,0,0,0,41,1,114,73,
+    0,0,0,114,11,0,0,0,218,17,95,114,101,113,117,105,
+    114,101,115,95,98,117,105,108,116,105,110,230,0,0,0,115,
+    6,0,0,0,0,2,12,5,10,1,114,75,0,0,0,99,
+    1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,
+    3,0,0,0,115,26,0,0,0,135,0,102,1,100,1,100,
+    2,132,8,125,1,116,0,124,1,136,0,131,2,1,0,124,
+    1,83,0,41,3,122,47,68,101,99,111,114,97,116,111,114,
+    32,116,111,32,118,101,114,105,102,121,32,116,104,101,32,110,
+    97,109,101,100,32,109,111,100,117,108,101,32,105,115,32,102,
+    114,111,122,101,110,46,99,2,0,0,0,0,0,0,0,2,
+    0,0,0,4,0,0,0,19,0,0,0,115,38,0,0,0,
+    116,0,106,1,124,1,131,1,115,28,116,2,100,1,106,3,
+    124,1,131,1,124,1,100,2,141,2,130,1,136,0,124,0,
+    124,1,131,2,83,0,41,3,78,122,27,123,33,114,125,32,
+    105,115,32,110,111,116,32,97,32,102,114,111,122,101,110,32,
+    109,111,100,117,108,101,41,1,114,15,0,0,0,41,4,114,
+    49,0,0,0,218,9,105,115,95,102,114,111,122,101,110,114,
+    71,0,0,0,114,38,0,0,0,41,2,114,26,0,0,0,
+    114,72,0,0,0,41,1,114,73,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,24,95,114,101,113,117,105,114,101,
+    115,95,102,114,111,122,101,110,95,119,114,97,112,112,101,114,
+    243,0,0,0,115,8,0,0,0,0,1,10,1,10,1,8,
+    1,122,50,95,114,101,113,117,105,114,101,115,95,102,114,111,
+    122,101,110,46,60,108,111,99,97,108,115,62,46,95,114,101,
+    113,117,105,114,101,115,95,102,114,111,122,101,110,95,119,114,
+    97,112,112,101,114,41,1,114,12,0,0,0,41,2,114,73,
+    0,0,0,114,77,0,0,0,114,10,0,0,0,41,1,114,
+    73,0,0,0,114,11,0,0,0,218,16,95,114,101,113,117,
+    105,114,101,115,95,102,114,111,122,101,110,241,0,0,0,115,
+    6,0,0,0,0,2,12,5,10,1,114,78,0,0,0,99,
+    2,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,
+    67,0,0,0,115,62,0,0,0,116,0,124,1,124,0,131,
+    2,125,2,124,1,116,1,106,2,107,6,114,50,116,1,106,
+    2,124,1,25,0,125,3,116,3,124,2,124,3,131,2,1,
+    0,116,1,106,2,124,1,25,0,83,0,116,4,124,2,131,
+    1,83,0,100,1,83,0,41,2,122,128,76,111,97,100,32,
+    116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,
+    100,117,108,101,32,105,110,116,111,32,115,121,115,46,109,111,
+    100,117,108,101,115,32,97,110,100,32,114,101,116,117,114,110,
+    32,105,116,46,10,10,32,32,32,32,84,104,105,115,32,109,
+    101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,
+    116,101,100,46,32,32,85,115,101,32,108,111,97,100,101,114,
+    46,101,120,101,99,95,109,111,100,117,108,101,32,105,110,115,
+    116,101,97,100,46,10,10,32,32,32,32,78,41,5,218,16,
+    115,112,101,99,95,102,114,111,109,95,108,111,97,100,101,114,
+    114,14,0,0,0,218,7,109,111,100,117,108,101,115,218,5,
+    95,101,120,101,99,218,5,95,108,111,97,100,41,4,114,26,
+    0,0,0,114,72,0,0,0,218,4,115,112,101,99,218,6,
+    109,111,100,117,108,101,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,218,17,95,108,111,97,100,95,109,111,100,
+    117,108,101,95,115,104,105,109,253,0,0,0,115,12,0,0,
+    0,0,6,10,1,10,1,10,1,10,1,10,2,114,85,0,
+    0,0,99,1,0,0,0,0,0,0,0,5,0,0,0,35,
+    0,0,0,67,0,0,0,115,216,0,0,0,116,0,124,0,
+    100,1,100,0,131,3,125,1,116,1,124,1,100,2,131,2,
+    114,54,121,10,124,1,106,2,124,0,131,1,83,0,4,0,
+    116,3,107,10,114,52,1,0,1,0,1,0,89,0,110,2,
+    88,0,121,10,124,0,106,4,125,2,87,0,110,20,4,0,
+    116,5,107,10,114,84,1,0,1,0,1,0,89,0,110,18,
+    88,0,124,2,100,0,107,9,114,102,116,6,124,2,131,1,
+    83,0,121,10,124,0,106,7,125,3,87,0,110,24,4,0,
+    116,5,107,10,114,136,1,0,1,0,1,0,100,3,125,3,
+    89,0,110,2,88,0,121,10,124,0,106,8,125,4,87,0,
+    110,50,4,0,116,5,107,10,114,198,1,0,1,0,1,0,
+    124,1,100,0,107,8,114,182,100,4,106,9,124,3,131,1,
+    83,0,100,5,106,9,124,3,124,1,131,2,83,0,89,0,
+    110,14,88,0,100,6,106,9,124,3,124,4,131,2,83,0,
+    100,0,83,0,41,7,78,218,10,95,95,108,111,97,100,101,
+    114,95,95,218,11,109,111,100,117,108,101,95,114,101,112,114,
+    250,1,63,122,13,60,109,111,100,117,108,101,32,123,33,114,
     125,62,122,20,60,109,111,100,117,108,101,32,123,33,114,125,
     32,40,123,33,114,125,41,62,122,23,60,109,111,100,117,108,
     101,32,123,33,114,125,32,102,114,111,109,32,123,33,114,125,
-    62,122,18,60,109,111,100,117,108,101,32,123,33,114,125,32,
-    40,123,125,41,62,41,5,114,15,0,0,0,114,104,0,0,
-    0,114,94,0,0,0,114,38,0,0,0,114,114,0,0,0,
-    41,2,114,83,0,0,0,114,15,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,114,92,0,0,0,
-    69,2,0,0,115,16,0,0,0,0,3,20,1,10,1,10,
-    1,10,2,16,2,6,1,14,2,114,92,0,0,0,99,2,
-    0,0,0,0,0,0,0,4,0,0,0,12,0,0,0,67,
-    0,0,0,115,178,0,0,0,124,0,106,0,125,2,116,1,
-    124,2,131,1,143,148,1,0,116,2,106,3,106,4,124,2,
-    131,1,124,1,107,9,114,54,100,1,106,5,124,2,131,1,
-    125,3,116,6,124,3,124,2,100,2,141,2,130,1,124,0,
-    106,7,100,3,107,8,114,106,124,0,106,8,100,3,107,8,
-    114,88,116,6,100,4,124,0,106,0,100,2,141,2,130,1,
-    116,9,124,0,124,1,100,5,100,6,141,3,1,0,124,1,
-    83,0,116,9,124,0,124,1,100,5,100,6,141,3,1,0,
-    116,10,124,0,106,7,100,7,131,2,115,146,124,0,106,7,
-    106,11,124,2,131,1,1,0,110,12,124,0,106,7,106,12,
-    124,1,131,1,1,0,87,0,100,3,81,0,82,0,88,0,
-    116,2,106,3,124,2,25,0,83,0,41,8,122,70,69,120,
-    101,99,117,116,101,32,116,104,101,32,115,112,101,99,39,115,
-    32,115,112,101,99,105,102,105,101,100,32,109,111,100,117,108,
-    101,32,105,110,32,97,110,32,101,120,105,115,116,105,110,103,
-    32,109,111,100,117,108,101,39,115,32,110,97,109,101,115,112,
-    97,99,101,46,122,30,109,111,100,117,108,101,32,123,33,114,
-    125,32,110,111,116,32,105,110,32,115,121,115,46,109,111,100,
-    117,108,101,115,41,1,114,15,0,0,0,78,122,14,109,105,
-    115,115,105,110,103,32,108,111,97,100,101,114,84,41,1,114,
-    130,0,0,0,114,136,0,0,0,41,13,114,15,0,0,0,
-    114,42,0,0,0,114,14,0,0,0,114,80,0,0,0,114,
-    30,0,0,0,114,38,0,0,0,114,71,0,0,0,114,94,
-    0,0,0,114,107,0,0,0,114,134,0,0,0,114,4,0,
-    0,0,218,11,108,111,97,100,95,109,111,100,117,108,101,114,
-    136,0,0,0,41,4,114,83,0,0,0,114,84,0,0,0,
-    114,15,0,0,0,218,3,109,115,103,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,81,0,0,0,86,2,
-    0,0,115,30,0,0,0,0,2,6,1,10,1,16,1,10,
-    1,12,1,10,1,10,1,14,2,14,1,4,1,14,1,12,
-    4,14,2,22,1,114,81,0,0,0,99,1,0,0,0,0,
-    0,0,0,2,0,0,0,27,0,0,0,67,0,0,0,115,
-    206,0,0,0,124,0,106,0,106,1,124,0,106,2,131,1,
-    1,0,116,3,106,4,124,0,106,2,25,0,125,1,116,5,
-    124,1,100,1,100,0,131,3,100,0,107,8,114,76,121,12,
-    124,0,106,0,124,1,95,6,87,0,110,20,4,0,116,7,
-    107,10,114,74,1,0,1,0,1,0,89,0,110,2,88,0,
-    116,5,124,1,100,2,100,0,131,3,100,0,107,8,114,154,
-    121,40,124,1,106,8,124,1,95,9,116,10,124,1,100,3,
-    131,2,115,130,124,0,106,2,106,11,100,4,131,1,100,5,
-    25,0,124,1,95,9,87,0,110,20,4,0,116,7,107,10,
-    114,152,1,0,1,0,1,0,89,0,110,2,88,0,116,5,
-    124,1,100,6,100,0,131,3,100,0,107,8,114,202,121,10,
-    124,0,124,1,95,12,87,0,110,20,4,0,116,7,107,10,
-    114,200,1,0,1,0,1,0,89,0,110,2,88,0,124,1,
-    83,0,41,7,78,114,86,0,0,0,114,131,0,0,0,114,
-    128,0,0,0,114,118,0,0,0,114,19,0,0,0,114,90,
-    0,0,0,41,13,114,94,0,0,0,114,138,0,0,0,114,
-    15,0,0,0,114,14,0,0,0,114,80,0,0,0,114,6,
-    0,0,0,114,86,0,0,0,114,91,0,0,0,114,1,0,
-    0,0,114,131,0,0,0,114,4,0,0,0,114,119,0,0,
-    0,114,90,0,0,0,41,2,114,83,0,0,0,114,84,0,
-    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,218,25,95,108,111,97,100,95,98,97,99,107,119,97,114,
-    100,95,99,111,109,112,97,116,105,98,108,101,110,2,0,0,
-    115,40,0,0,0,0,4,14,2,12,1,16,1,2,1,12,
-    1,14,1,6,1,16,1,2,4,8,1,10,1,22,1,14,
-    1,6,1,16,1,2,1,10,1,14,1,6,1,114,140,0,
-    0,0,99,1,0,0,0,0,0,0,0,2,0,0,0,11,
-    0,0,0,67,0,0,0,115,118,0,0,0,124,0,106,0,
-    100,0,107,9,114,30,116,1,124,0,106,0,100,1,131,2,
-    115,30,116,2,124,0,131,1,83,0,116,3,124,0,131,1,
-    125,1,116,4,124,1,131,1,143,54,1,0,124,0,106,0,
-    100,0,107,8,114,84,124,0,106,5,100,0,107,8,114,96,
-    116,6,100,2,124,0,106,7,100,3,141,2,130,1,110,12,
-    124,0,106,0,106,8,124,1,131,1,1,0,87,0,100,0,
-    81,0,82,0,88,0,116,9,106,10,124,0,106,7,25,0,
-    83,0,41,4,78,114,136,0,0,0,122,14,109,105,115,115,
-    105,110,103,32,108,111,97,100,101,114,41,1,114,15,0,0,
-    0,41,11,114,94,0,0,0,114,4,0,0,0,114,140,0,
-    0,0,114,137,0,0,0,114,97,0,0,0,114,107,0,0,
-    0,114,71,0,0,0,114,15,0,0,0,114,136,0,0,0,
-    114,14,0,0,0,114,80,0,0,0,41,2,114,83,0,0,
-    0,114,84,0,0,0,114,10,0,0,0,114,10,0,0,0,
-    114,11,0,0,0,218,14,95,108,111,97,100,95,117,110,108,
-    111,99,107,101,100,139,2,0,0,115,20,0,0,0,0,2,
-    10,2,12,1,8,2,8,1,10,1,10,1,10,1,16,3,
-    22,5,114,141,0,0,0,99,1,0,0,0,0,0,0,0,
-    1,0,0,0,9,0,0,0,67,0,0,0,115,30,0,0,
-    0,116,0,124,0,106,1,131,1,143,10,1,0,116,2,124,
-    0,131,1,83,0,81,0,82,0,88,0,100,1,83,0,41,
-    2,122,191,82,101,116,117,114,110,32,97,32,110,101,119,32,
-    109,111,100,117,108,101,32,111,98,106,101,99,116,44,32,108,
-    111,97,100,101,100,32,98,121,32,116,104,101,32,115,112,101,
-    99,39,115,32,108,111,97,100,101,114,46,10,10,32,32,32,
-    32,84,104,101,32,109,111,100,117,108,101,32,105,115,32,110,
-    111,116,32,97,100,100,101,100,32,116,111,32,105,116,115,32,
-    112,97,114,101,110,116,46,10,10,32,32,32,32,73,102,32,
-    97,32,109,111,100,117,108,101,32,105,115,32,97,108,114,101,
-    97,100,121,32,105,110,32,115,121,115,46,109,111,100,117,108,
-    101,115,44,32,116,104,97,116,32,101,120,105,115,116,105,110,
-    103,32,109,111,100,117,108,101,32,103,101,116,115,10,32,32,
-    32,32,99,108,111,98,98,101,114,101,100,46,10,10,32,32,
-    32,32,78,41,3,114,42,0,0,0,114,15,0,0,0,114,
-    141,0,0,0,41,1,114,83,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,82,0,0,0,162,
-    2,0,0,115,4,0,0,0,0,9,12,1,114,82,0,0,
-    0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,
-    0,0,64,0,0,0,115,136,0,0,0,101,0,90,1,100,
-    0,90,2,100,1,90,3,101,4,100,2,100,3,132,0,131,
-    1,90,5,101,6,100,19,100,5,100,6,132,1,131,1,90,
-    7,101,6,100,20,100,7,100,8,132,1,131,1,90,8,101,
-    6,100,9,100,10,132,0,131,1,90,9,101,6,100,11,100,
-    12,132,0,131,1,90,10,101,6,101,11,100,13,100,14,132,
-    0,131,1,131,1,90,12,101,6,101,11,100,15,100,16,132,
-    0,131,1,131,1,90,13,101,6,101,11,100,17,100,18,132,
-    0,131,1,131,1,90,14,101,6,101,15,131,1,90,16,100,
-    4,83,0,41,21,218,15,66,117,105,108,116,105,110,73,109,
-    112,111,114,116,101,114,122,144,77,101,116,97,32,112,97,116,
-    104,32,105,109,112,111,114,116,32,102,111,114,32,98,117,105,
-    108,116,45,105,110,32,109,111,100,117,108,101,115,46,10,10,
-    32,32,32,32,65,108,108,32,109,101,116,104,111,100,115,32,
-    97,114,101,32,101,105,116,104,101,114,32,99,108,97,115,115,
-    32,111,114,32,115,116,97,116,105,99,32,109,101,116,104,111,
-    100,115,32,116,111,32,97,118,111,105,100,32,116,104,101,32,
-    110,101,101,100,32,116,111,10,32,32,32,32,105,110,115,116,
-    97,110,116,105,97,116,101,32,116,104,101,32,99,108,97,115,
-    115,46,10,10,32,32,32,32,99,1,0,0,0,0,0,0,
-    0,1,0,0,0,2,0,0,0,67,0,0,0,115,12,0,
-    0,0,100,1,106,0,124,0,106,1,131,1,83,0,41,2,
-    122,115,82,101,116,117,114,110,32,114,101,112,114,32,102,111,
-    114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,32,
-    32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,111,
-    100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
-    32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,99,
-    104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,32,
-    106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,32,
-    32,32,32,32,32,122,24,60,109,111,100,117,108,101,32,123,
-    33,114,125,32,40,98,117,105,108,116,45,105,110,41,62,41,
-    2,114,38,0,0,0,114,1,0,0,0,41,1,114,84,0,
-    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,87,0,0,0,186,2,0,0,115,2,0,0,0,0,
-    7,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116,
-    101,114,46,109,111,100,117,108,101,95,114,101,112,114,78,99,
-    4,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,
-    67,0,0,0,115,44,0,0,0,124,2,100,0,107,9,114,
-    12,100,0,83,0,116,0,106,1,124,1,131,1,114,36,116,
-    2,124,1,124,0,100,1,100,2,141,3,83,0,100,0,83,
-    0,100,0,83,0,41,3,78,122,8,98,117,105,108,116,45,
-    105,110,41,1,114,104,0,0,0,41,3,114,49,0,0,0,
-    90,10,105,115,95,98,117,105,108,116,105,110,114,79,0,0,
-    0,41,4,218,3,99,108,115,114,72,0,0,0,218,4,112,
-    97,116,104,218,6,116,97,114,103,101,116,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,218,9,102,105,110,100,
-    95,115,112,101,99,195,2,0,0,115,10,0,0,0,0,2,
-    8,1,4,1,10,1,14,2,122,25,66,117,105,108,116,105,
-    110,73,109,112,111,114,116,101,114,46,102,105,110,100,95,115,
-    112,101,99,99,3,0,0,0,0,0,0,0,4,0,0,0,
-    3,0,0,0,67,0,0,0,115,30,0,0,0,124,0,106,
-    0,124,1,124,2,131,2,125,3,124,3,100,1,107,9,114,
-    26,124,3,106,1,83,0,100,1,83,0,41,2,122,175,70,
-    105,110,100,32,116,104,101,32,98,117,105,108,116,45,105,110,
-    32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,
-    32,32,73,102,32,39,112,97,116,104,39,32,105,115,32,101,
-    118,101,114,32,115,112,101,99,105,102,105,101,100,32,116,104,
-    101,110,32,116,104,101,32,115,101,97,114,99,104,32,105,115,
-    32,99,111,110,115,105,100,101,114,101,100,32,97,32,102,97,
-    105,108,117,114,101,46,10,10,32,32,32,32,32,32,32,32,
-    84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,
-    101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,
-    102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,
-    101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,41,
-    2,114,146,0,0,0,114,94,0,0,0,41,4,114,143,0,
-    0,0,114,72,0,0,0,114,144,0,0,0,114,83,0,0,
+    62,41,10,114,6,0,0,0,114,4,0,0,0,114,87,0,
+    0,0,218,9,69,120,99,101,112,116,105,111,110,218,8,95,
+    95,115,112,101,99,95,95,218,14,65,116,116,114,105,98,117,
+    116,101,69,114,114,111,114,218,22,95,109,111,100,117,108,101,
+    95,114,101,112,114,95,102,114,111,109,95,115,112,101,99,114,
+    1,0,0,0,218,8,95,95,102,105,108,101,95,95,114,38,
+    0,0,0,41,5,114,84,0,0,0,218,6,108,111,97,100,
+    101,114,114,83,0,0,0,114,15,0,0,0,218,8,102,105,
+    108,101,110,97,109,101,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,218,12,95,109,111,100,117,108,101,95,114,
+    101,112,114,13,1,0,0,115,46,0,0,0,0,2,12,1,
+    10,4,2,1,10,1,14,1,6,1,2,1,10,1,14,1,
+    6,2,8,1,8,4,2,1,10,1,14,1,10,1,2,1,
+    10,1,14,1,8,1,10,2,18,2,114,96,0,0,0,99,
+    0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,
+    64,0,0,0,115,36,0,0,0,101,0,90,1,100,0,90,
+    2,100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,
+    4,100,5,100,6,132,0,90,5,100,7,83,0,41,8,218,
+    17,95,105,110,115,116,97,108,108,101,100,95,115,97,102,101,
+    108,121,99,2,0,0,0,0,0,0,0,2,0,0,0,2,
+    0,0,0,67,0,0,0,115,18,0,0,0,124,1,124,0,
+    95,0,124,1,106,1,124,0,95,2,100,0,83,0,41,1,
+    78,41,3,218,7,95,109,111,100,117,108,101,114,90,0,0,
+    0,218,5,95,115,112,101,99,41,2,114,26,0,0,0,114,
+    84,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,27,0,0,0,51,1,0,0,115,4,0,0,
+    0,0,1,6,1,122,26,95,105,110,115,116,97,108,108,101,
+    100,95,115,97,102,101,108,121,46,95,95,105,110,105,116,95,
+    95,99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,
+    0,0,67,0,0,0,115,28,0,0,0,100,1,124,0,106,
+    0,95,1,124,0,106,2,116,3,106,4,124,0,106,0,106,
+    5,60,0,100,0,83,0,41,2,78,84,41,6,114,99,0,
+    0,0,218,13,95,105,110,105,116,105,97,108,105,122,105,110,
+    103,114,98,0,0,0,114,14,0,0,0,114,80,0,0,0,
+    114,15,0,0,0,41,1,114,26,0,0,0,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,114,46,0,0,0,
+    55,1,0,0,115,4,0,0,0,0,4,8,1,122,27,95,
+    105,110,115,116,97,108,108,101,100,95,115,97,102,101,108,121,
+    46,95,95,101,110,116,101,114,95,95,99,1,0,0,0,0,
+    0,0,0,3,0,0,0,17,0,0,0,71,0,0,0,115,
+    98,0,0,0,122,82,124,0,106,0,125,2,116,1,100,1,
+    100,2,132,0,124,1,68,0,131,1,131,1,114,64,121,14,
+    116,2,106,3,124,2,106,4,61,0,87,0,113,80,4,0,
+    116,5,107,10,114,60,1,0,1,0,1,0,89,0,113,80,
+    88,0,110,16,116,6,100,3,124,2,106,4,124,2,106,7,
+    131,3,1,0,87,0,100,0,100,4,124,0,106,0,95,8,
+    88,0,100,0,83,0,41,5,78,99,1,0,0,0,0,0,
+    0,0,2,0,0,0,3,0,0,0,115,0,0,0,115,22,
+    0,0,0,124,0,93,14,125,1,124,1,100,0,107,9,86,
+    0,1,0,113,2,100,0,83,0,41,1,78,114,10,0,0,
+    0,41,2,90,2,46,48,90,3,97,114,103,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,250,9,60,103,101,
+    110,101,120,112,114,62,65,1,0,0,115,2,0,0,0,4,
+    0,122,45,95,105,110,115,116,97,108,108,101,100,95,115,97,
+    102,101,108,121,46,95,95,101,120,105,116,95,95,46,60,108,
+    111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,
+    122,18,105,109,112,111,114,116,32,123,33,114,125,32,35,32,
+    123,33,114,125,70,41,9,114,99,0,0,0,218,3,97,110,
+    121,114,14,0,0,0,114,80,0,0,0,114,15,0,0,0,
+    114,55,0,0,0,114,69,0,0,0,114,94,0,0,0,114,
+    100,0,0,0,41,3,114,26,0,0,0,114,47,0,0,0,
+    114,83,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+    11,0,0,0,114,48,0,0,0,62,1,0,0,115,18,0,
+    0,0,0,1,2,1,6,1,18,1,2,1,14,1,14,1,
+    8,2,20,2,122,26,95,105,110,115,116,97,108,108,101,100,
+    95,115,97,102,101,108,121,46,95,95,101,120,105,116,95,95,
+    78,41,6,114,1,0,0,0,114,0,0,0,0,114,2,0,
+    0,0,114,27,0,0,0,114,46,0,0,0,114,48,0,0,
+    0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,114,97,0,0,0,49,1,0,0,115,6,
+    0,0,0,8,2,8,4,8,7,114,97,0,0,0,99,0,
+    0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64,
+    0,0,0,115,114,0,0,0,101,0,90,1,100,0,90,2,
+    100,1,90,3,100,2,100,2,100,2,100,3,156,3,100,4,
+    100,5,132,2,90,4,100,6,100,7,132,0,90,5,100,8,
+    100,9,132,0,90,6,101,7,100,10,100,11,132,0,131,1,
+    90,8,101,8,106,9,100,12,100,11,132,0,131,1,90,8,
+    101,7,100,13,100,14,132,0,131,1,90,10,101,7,100,15,
+    100,16,132,0,131,1,90,11,101,11,106,9,100,17,100,16,
+    132,0,131,1,90,11,100,2,83,0,41,18,218,10,77,111,
+    100,117,108,101,83,112,101,99,97,208,5,0,0,84,104,101,
+    32,115,112,101,99,105,102,105,99,97,116,105,111,110,32,102,
+    111,114,32,97,32,109,111,100,117,108,101,44,32,117,115,101,
+    100,32,102,111,114,32,108,111,97,100,105,110,103,46,10,10,
+    32,32,32,32,65,32,109,111,100,117,108,101,39,115,32,115,
+    112,101,99,32,105,115,32,116,104,101,32,115,111,117,114,99,
+    101,32,102,111,114,32,105,110,102,111,114,109,97,116,105,111,
+    110,32,97,98,111,117,116,32,116,104,101,32,109,111,100,117,
+    108,101,46,32,32,70,111,114,10,32,32,32,32,100,97,116,
+    97,32,97,115,115,111,99,105,97,116,101,100,32,119,105,116,
+    104,32,116,104,101,32,109,111,100,117,108,101,44,32,105,110,
+    99,108,117,100,105,110,103,32,115,111,117,114,99,101,44,32,
+    117,115,101,32,116,104,101,32,115,112,101,99,39,115,10,32,
+    32,32,32,108,111,97,100,101,114,46,10,10,32,32,32,32,
+    96,110,97,109,101,96,32,105,115,32,116,104,101,32,97,98,
+    115,111,108,117,116,101,32,110,97,109,101,32,111,102,32,116,
+    104,101,32,109,111,100,117,108,101,46,32,32,96,108,111,97,
+    100,101,114,96,32,105,115,32,116,104,101,32,108,111,97,100,
+    101,114,10,32,32,32,32,116,111,32,117,115,101,32,119,104,
+    101,110,32,108,111,97,100,105,110,103,32,116,104,101,32,109,
+    111,100,117,108,101,46,32,32,96,112,97,114,101,110,116,96,
+    32,105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,
+    116,104,101,10,32,32,32,32,112,97,99,107,97,103,101,32,
+    116,104,101,32,109,111,100,117,108,101,32,105,115,32,105,110,
+    46,32,32,84,104,101,32,112,97,114,101,110,116,32,105,115,
+    32,100,101,114,105,118,101,100,32,102,114,111,109,32,116,104,
+    101,32,110,97,109,101,46,10,10,32,32,32,32,96,105,115,
+    95,112,97,99,107,97,103,101,96,32,100,101,116,101,114,109,
+    105,110,101,115,32,105,102,32,116,104,101,32,109,111,100,117,
+    108,101,32,105,115,32,99,111,110,115,105,100,101,114,101,100,
+    32,97,32,112,97,99,107,97,103,101,32,111,114,10,32,32,
+    32,32,110,111,116,46,32,32,79,110,32,109,111,100,117,108,
+    101,115,32,116,104,105,115,32,105,115,32,114,101,102,108,101,
+    99,116,101,100,32,98,121,32,116,104,101,32,96,95,95,112,
+    97,116,104,95,95,96,32,97,116,116,114,105,98,117,116,101,
+    46,10,10,32,32,32,32,96,111,114,105,103,105,110,96,32,
+    105,115,32,116,104,101,32,115,112,101,99,105,102,105,99,32,
+    108,111,99,97,116,105,111,110,32,117,115,101,100,32,98,121,
+    32,116,104,101,32,108,111,97,100,101,114,32,102,114,111,109,
+    32,119,104,105,99,104,32,116,111,10,32,32,32,32,108,111,
+    97,100,32,116,104,101,32,109,111,100,117,108,101,44,32,105,
+    102,32,116,104,97,116,32,105,110,102,111,114,109,97,116,105,
+    111,110,32,105,115,32,97,118,97,105,108,97,98,108,101,46,
+    32,32,87,104,101,110,32,102,105,108,101,110,97,109,101,32,
+    105,115,10,32,32,32,32,115,101,116,44,32,111,114,105,103,
+    105,110,32,119,105,108,108,32,109,97,116,99,104,46,10,10,
+    32,32,32,32,96,104,97,115,95,108,111,99,97,116,105,111,
+    110,96,32,105,110,100,105,99,97,116,101,115,32,116,104,97,
+    116,32,97,32,115,112,101,99,39,115,32,34,111,114,105,103,
+    105,110,34,32,114,101,102,108,101,99,116,115,32,97,32,108,
+    111,99,97,116,105,111,110,46,10,32,32,32,32,87,104,101,
+    110,32,116,104,105,115,32,105,115,32,84,114,117,101,44,32,
+    96,95,95,102,105,108,101,95,95,96,32,97,116,116,114,105,
+    98,117,116,101,32,111,102,32,116,104,101,32,109,111,100,117,
+    108,101,32,105,115,32,115,101,116,46,10,10,32,32,32,32,
+    96,99,97,99,104,101,100,96,32,105,115,32,116,104,101,32,
+    108,111,99,97,116,105,111,110,32,111,102,32,116,104,101,32,
+    99,97,99,104,101,100,32,98,121,116,101,99,111,100,101,32,
+    102,105,108,101,44,32,105,102,32,97,110,121,46,32,32,73,
+    116,10,32,32,32,32,99,111,114,114,101,115,112,111,110,100,
+    115,32,116,111,32,116,104,101,32,96,95,95,99,97,99,104,
+    101,100,95,95,96,32,97,116,116,114,105,98,117,116,101,46,
+    10,10,32,32,32,32,96,115,117,98,109,111,100,117,108,101,
+    95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,110,
+    115,96,32,105,115,32,116,104,101,32,115,101,113,117,101,110,
+    99,101,32,111,102,32,112,97,116,104,32,101,110,116,114,105,
+    101,115,32,116,111,10,32,32,32,32,115,101,97,114,99,104,
+    32,119,104,101,110,32,105,109,112,111,114,116,105,110,103,32,
+    115,117,98,109,111,100,117,108,101,115,46,32,32,73,102,32,
+    115,101,116,44,32,105,115,95,112,97,99,107,97,103,101,32,
+    115,104,111,117,108,100,32,98,101,10,32,32,32,32,84,114,
+    117,101,45,45,97,110,100,32,70,97,108,115,101,32,111,116,
+    104,101,114,119,105,115,101,46,10,10,32,32,32,32,80,97,
+    99,107,97,103,101,115,32,97,114,101,32,115,105,109,112,108,
+    121,32,109,111,100,117,108,101,115,32,116,104,97,116,32,40,
+    109,97,121,41,32,104,97,118,101,32,115,117,98,109,111,100,
+    117,108,101,115,46,32,32,73,102,32,97,32,115,112,101,99,
+    10,32,32,32,32,104,97,115,32,97,32,110,111,110,45,78,
+    111,110,101,32,118,97,108,117,101,32,105,110,32,96,115,117,
+    98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108,
+    111,99,97,116,105,111,110,115,96,44,32,116,104,101,32,105,
+    109,112,111,114,116,10,32,32,32,32,115,121,115,116,101,109,
+    32,119,105,108,108,32,99,111,110,115,105,100,101,114,32,109,
+    111,100,117,108,101,115,32,108,111,97,100,101,100,32,102,114,
+    111,109,32,116,104,101,32,115,112,101,99,32,97,115,32,112,
+    97,99,107,97,103,101,115,46,10,10,32,32,32,32,79,110,
+    108,121,32,102,105,110,100,101,114,115,32,40,115,101,101,32,
+    105,109,112,111,114,116,108,105,98,46,97,98,99,46,77,101,
+    116,97,80,97,116,104,70,105,110,100,101,114,32,97,110,100,
+    10,32,32,32,32,105,109,112,111,114,116,108,105,98,46,97,
+    98,99,46,80,97,116,104,69,110,116,114,121,70,105,110,100,
+    101,114,41,32,115,104,111,117,108,100,32,109,111,100,105,102,
+    121,32,77,111,100,117,108,101,83,112,101,99,32,105,110,115,
+    116,97,110,99,101,115,46,10,10,32,32,32,32,78,41,3,
+    218,6,111,114,105,103,105,110,218,12,108,111,97,100,101,114,
+    95,115,116,97,116,101,218,10,105,115,95,112,97,99,107,97,
+    103,101,99,3,0,0,0,3,0,0,0,6,0,0,0,2,
+    0,0,0,67,0,0,0,115,54,0,0,0,124,1,124,0,
+    95,0,124,2,124,0,95,1,124,3,124,0,95,2,124,4,
+    124,0,95,3,124,5,114,32,103,0,110,2,100,0,124,0,
+    95,4,100,1,124,0,95,5,100,0,124,0,95,6,100,0,
+    83,0,41,2,78,70,41,7,114,15,0,0,0,114,94,0,
+    0,0,114,104,0,0,0,114,105,0,0,0,218,26,115,117,
+    98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108,
+    111,99,97,116,105,111,110,115,218,13,95,115,101,116,95,102,
+    105,108,101,97,116,116,114,218,7,95,99,97,99,104,101,100,
+    41,6,114,26,0,0,0,114,15,0,0,0,114,94,0,0,
+    0,114,104,0,0,0,114,105,0,0,0,114,106,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    27,0,0,0,113,1,0,0,115,14,0,0,0,0,2,6,
+    1,6,1,6,1,6,1,14,3,6,1,122,19,77,111,100,
+    117,108,101,83,112,101,99,46,95,95,105,110,105,116,95,95,
+    99,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0,
+    0,67,0,0,0,115,102,0,0,0,100,1,106,0,124,0,
+    106,1,131,1,100,2,106,0,124,0,106,2,131,1,103,2,
+    125,1,124,0,106,3,100,0,107,9,114,52,124,1,106,4,
+    100,3,106,0,124,0,106,3,131,1,131,1,1,0,124,0,
+    106,5,100,0,107,9,114,80,124,1,106,4,100,4,106,0,
+    124,0,106,5,131,1,131,1,1,0,100,5,106,0,124,0,
+    106,6,106,7,100,6,106,8,124,1,131,1,131,2,83,0,
+    41,7,78,122,9,110,97,109,101,61,123,33,114,125,122,11,
+    108,111,97,100,101,114,61,123,33,114,125,122,11,111,114,105,
+    103,105,110,61,123,33,114,125,122,29,115,117,98,109,111,100,
+    117,108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,
+    105,111,110,115,61,123,125,122,6,123,125,40,123,125,41,122,
+    2,44,32,41,9,114,38,0,0,0,114,15,0,0,0,114,
+    94,0,0,0,114,104,0,0,0,218,6,97,112,112,101,110,
+    100,114,107,0,0,0,218,9,95,95,99,108,97,115,115,95,
+    95,114,1,0,0,0,218,4,106,111,105,110,41,2,114,26,
+    0,0,0,114,47,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,40,0,0,0,125,1,0,0,
+    115,16,0,0,0,0,1,10,1,14,1,10,1,18,1,10,
+    1,8,1,10,1,122,19,77,111,100,117,108,101,83,112,101,
+    99,46,95,95,114,101,112,114,95,95,99,2,0,0,0,0,
+    0,0,0,3,0,0,0,11,0,0,0,67,0,0,0,115,
+    102,0,0,0,124,0,106,0,125,2,121,70,124,0,106,1,
+    124,1,106,1,107,2,111,76,124,0,106,2,124,1,106,2,
+    107,2,111,76,124,0,106,3,124,1,106,3,107,2,111,76,
+    124,2,124,1,106,0,107,2,111,76,124,0,106,4,124,1,
+    106,4,107,2,111,76,124,0,106,5,124,1,106,5,107,2,
+    83,0,4,0,116,6,107,10,114,96,1,0,1,0,1,0,
+    100,1,83,0,88,0,100,0,83,0,41,2,78,70,41,7,
+    114,107,0,0,0,114,15,0,0,0,114,94,0,0,0,114,
+    104,0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,
+    115,95,108,111,99,97,116,105,111,110,114,91,0,0,0,41,
+    3,114,26,0,0,0,90,5,111,116,104,101,114,90,4,115,
+    109,115,108,114,10,0,0,0,114,10,0,0,0,114,11,0,
+    0,0,218,6,95,95,101,113,95,95,135,1,0,0,115,20,
+    0,0,0,0,1,6,1,2,1,12,1,12,1,12,1,10,
+    1,12,1,12,1,14,1,122,17,77,111,100,117,108,101,83,
+    112,101,99,46,95,95,101,113,95,95,99,1,0,0,0,0,
+    0,0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,
+    58,0,0,0,124,0,106,0,100,0,107,8,114,52,124,0,
+    106,1,100,0,107,9,114,52,124,0,106,2,114,52,116,3,
+    100,0,107,8,114,38,116,4,130,1,116,3,106,5,124,0,
+    106,1,131,1,124,0,95,0,124,0,106,0,83,0,41,1,
+    78,41,6,114,109,0,0,0,114,104,0,0,0,114,108,0,
+    0,0,218,19,95,98,111,111,116,115,116,114,97,112,95,101,
+    120,116,101,114,110,97,108,218,19,78,111,116,73,109,112,108,
+    101,109,101,110,116,101,100,69,114,114,111,114,90,11,95,103,
+    101,116,95,99,97,99,104,101,100,41,1,114,26,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    113,0,0,0,147,1,0,0,115,12,0,0,0,0,2,10,
+    1,16,1,8,1,4,1,14,1,122,17,77,111,100,117,108,
+    101,83,112,101,99,46,99,97,99,104,101,100,99,2,0,0,
+    0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,
+    0,115,10,0,0,0,124,1,124,0,95,0,100,0,83,0,
+    41,1,78,41,1,114,109,0,0,0,41,2,114,26,0,0,
+    0,114,113,0,0,0,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,114,113,0,0,0,156,1,0,0,115,2,
+    0,0,0,0,2,99,1,0,0,0,0,0,0,0,1,0,
+    0,0,2,0,0,0,67,0,0,0,115,36,0,0,0,124,
+    0,106,0,100,1,107,8,114,26,124,0,106,1,106,2,100,
+    2,131,1,100,3,25,0,83,0,124,0,106,1,83,0,100,
+    1,83,0,41,4,122,32,84,104,101,32,110,97,109,101,32,
+    111,102,32,116,104,101,32,109,111,100,117,108,101,39,115,32,
+    112,97,114,101,110,116,46,78,218,1,46,114,19,0,0,0,
+    41,3,114,107,0,0,0,114,15,0,0,0,218,10,114,112,
+    97,114,116,105,116,105,111,110,41,1,114,26,0,0,0,114,
+    10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,6,
+    112,97,114,101,110,116,160,1,0,0,115,6,0,0,0,0,
+    3,10,1,16,2,122,17,77,111,100,117,108,101,83,112,101,
+    99,46,112,97,114,101,110,116,99,1,0,0,0,0,0,0,
+    0,1,0,0,0,1,0,0,0,67,0,0,0,115,6,0,
+    0,0,124,0,106,0,83,0,41,1,78,41,1,114,108,0,
+    0,0,41,1,114,26,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,114,114,0,0,0,168,1,0,
+    0,115,2,0,0,0,0,2,122,23,77,111,100,117,108,101,
+    83,112,101,99,46,104,97,115,95,108,111,99,97,116,105,111,
+    110,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0,
+    0,0,67,0,0,0,115,14,0,0,0,116,0,124,1,131,
+    1,124,0,95,1,100,0,83,0,41,1,78,41,2,218,4,
+    98,111,111,108,114,108,0,0,0,41,2,114,26,0,0,0,
+    218,5,118,97,108,117,101,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,114,114,0,0,0,172,1,0,0,115,
+    2,0,0,0,0,2,41,12,114,1,0,0,0,114,0,0,
+    0,0,114,2,0,0,0,114,3,0,0,0,114,27,0,0,
+    0,114,40,0,0,0,114,115,0,0,0,218,8,112,114,111,
+    112,101,114,116,121,114,113,0,0,0,218,6,115,101,116,116,
+    101,114,114,120,0,0,0,114,114,0,0,0,114,10,0,0,
     0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,11,102,105,110,100,95,109,111,100,117,108,101,204,2,0,
-    0,115,4,0,0,0,0,9,12,1,122,27,66,117,105,108,
-    116,105,110,73,109,112,111,114,116,101,114,46,102,105,110,100,
-    95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,
-    2,0,0,0,4,0,0,0,67,0,0,0,115,46,0,0,
-    0,124,1,106,0,116,1,106,2,107,7,114,34,116,3,100,
-    1,106,4,124,1,106,0,131,1,124,1,106,0,100,2,141,
-    2,130,1,116,5,116,6,106,7,124,1,131,2,83,0,41,
-    3,122,24,67,114,101,97,116,101,32,97,32,98,117,105,108,
-    116,45,105,110,32,109,111,100,117,108,101,122,29,123,33,114,
-    125,32,105,115,32,110,111,116,32,97,32,98,117,105,108,116,
-    45,105,110,32,109,111,100,117,108,101,41,1,114,15,0,0,
-    0,41,8,114,15,0,0,0,114,14,0,0,0,114,70,0,
-    0,0,114,71,0,0,0,114,38,0,0,0,114,59,0,0,
-    0,114,49,0,0,0,90,14,99,114,101,97,116,101,95,98,
-    117,105,108,116,105,110,41,2,114,26,0,0,0,114,83,0,
+    114,103,0,0,0,76,1,0,0,115,20,0,0,0,8,35,
+    4,2,4,1,14,11,8,10,8,12,12,9,14,4,12,8,
+    12,4,114,103,0,0,0,41,2,114,104,0,0,0,114,106,
+    0,0,0,99,2,0,0,0,2,0,0,0,6,0,0,0,
+    14,0,0,0,67,0,0,0,115,154,0,0,0,116,0,124,
+    1,100,1,131,2,114,74,116,1,100,2,107,8,114,22,116,
+    2,130,1,116,1,106,3,125,4,124,3,100,2,107,8,114,
+    48,124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,
+    56,103,0,110,2,100,2,125,5,124,4,124,0,124,1,124,
+    5,100,4,141,3,83,0,124,3,100,2,107,8,114,138,116,
+    0,124,1,100,5,131,2,114,134,121,14,124,1,106,4,124,
+    0,131,1,125,3,87,0,113,138,4,0,116,5,107,10,114,
+    130,1,0,1,0,1,0,100,2,125,3,89,0,113,138,88,
+    0,110,4,100,6,125,3,116,6,124,0,124,1,124,2,124,
+    3,100,7,141,4,83,0,41,8,122,53,82,101,116,117,114,
+    110,32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,
+    98,97,115,101,100,32,111,110,32,118,97,114,105,111,117,115,
+    32,108,111,97,100,101,114,32,109,101,116,104,111,100,115,46,
+    90,12,103,101,116,95,102,105,108,101,110,97,109,101,78,41,
+    1,114,94,0,0,0,41,2,114,94,0,0,0,114,107,0,
+    0,0,114,106,0,0,0,70,41,2,114,104,0,0,0,114,
+    106,0,0,0,41,7,114,4,0,0,0,114,116,0,0,0,
+    114,117,0,0,0,218,23,115,112,101,99,95,102,114,111,109,
+    95,102,105,108,101,95,108,111,99,97,116,105,111,110,114,106,
+    0,0,0,114,71,0,0,0,114,103,0,0,0,41,6,114,
+    15,0,0,0,114,94,0,0,0,114,104,0,0,0,114,106,
+    0,0,0,114,125,0,0,0,90,6,115,101,97,114,99,104,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    79,0,0,0,177,1,0,0,115,34,0,0,0,0,2,10,
+    1,8,1,4,1,6,2,8,1,12,1,12,1,6,1,8,
+    2,8,1,10,1,2,1,14,1,14,1,12,3,4,2,114,
+    79,0,0,0,99,3,0,0,0,0,0,0,0,8,0,0,
+    0,53,0,0,0,67,0,0,0,115,56,1,0,0,121,10,
+    124,0,106,0,125,3,87,0,110,20,4,0,116,1,107,10,
+    114,30,1,0,1,0,1,0,89,0,110,14,88,0,124,3,
+    100,0,107,9,114,44,124,3,83,0,124,0,106,2,125,4,
+    124,1,100,0,107,8,114,90,121,10,124,0,106,3,125,1,
+    87,0,110,20,4,0,116,1,107,10,114,88,1,0,1,0,
+    1,0,89,0,110,2,88,0,121,10,124,0,106,4,125,5,
+    87,0,110,24,4,0,116,1,107,10,114,124,1,0,1,0,
+    1,0,100,0,125,5,89,0,110,2,88,0,124,2,100,0,
+    107,8,114,184,124,5,100,0,107,8,114,180,121,10,124,1,
+    106,5,125,2,87,0,113,184,4,0,116,1,107,10,114,176,
+    1,0,1,0,1,0,100,0,125,2,89,0,113,184,88,0,
+    110,4,124,5,125,2,121,10,124,0,106,6,125,6,87,0,
+    110,24,4,0,116,1,107,10,114,218,1,0,1,0,1,0,
+    100,0,125,6,89,0,110,2,88,0,121,14,116,7,124,0,
+    106,8,131,1,125,7,87,0,110,26,4,0,116,1,107,10,
+    144,1,114,4,1,0,1,0,1,0,100,0,125,7,89,0,
+    110,2,88,0,116,9,124,4,124,1,124,2,100,1,141,3,
+    125,3,124,5,100,0,107,8,144,1,114,34,100,2,110,2,
+    100,3,124,3,95,10,124,6,124,3,95,11,124,7,124,3,
+    95,12,124,3,83,0,41,4,78,41,1,114,104,0,0,0,
+    70,84,41,13,114,90,0,0,0,114,91,0,0,0,114,1,
+    0,0,0,114,86,0,0,0,114,93,0,0,0,90,7,95,
+    79,82,73,71,73,78,218,10,95,95,99,97,99,104,101,100,
+    95,95,218,4,108,105,115,116,218,8,95,95,112,97,116,104,
+    95,95,114,103,0,0,0,114,108,0,0,0,114,113,0,0,
+    0,114,107,0,0,0,41,8,114,84,0,0,0,114,94,0,
+    0,0,114,104,0,0,0,114,83,0,0,0,114,15,0,0,
+    0,90,8,108,111,99,97,116,105,111,110,114,113,0,0,0,
+    114,107,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+    11,0,0,0,218,17,95,115,112,101,99,95,102,114,111,109,
+    95,109,111,100,117,108,101,203,1,0,0,115,72,0,0,0,
+    0,2,2,1,10,1,14,1,6,2,8,1,4,2,6,1,
+    8,1,2,1,10,1,14,2,6,1,2,1,10,1,14,1,
+    10,1,8,1,8,1,2,1,10,1,14,1,12,2,4,1,
+    2,1,10,1,14,1,10,1,2,1,14,1,16,1,10,2,
+    14,1,20,1,6,1,6,1,114,129,0,0,0,70,41,1,
+    218,8,111,118,101,114,114,105,100,101,99,2,0,0,0,1,
+    0,0,0,5,0,0,0,59,0,0,0,67,0,0,0,115,
+    212,1,0,0,124,2,115,20,116,0,124,1,100,1,100,0,
+    131,3,100,0,107,8,114,54,121,12,124,0,106,1,124,1,
+    95,2,87,0,110,20,4,0,116,3,107,10,114,52,1,0,
+    1,0,1,0,89,0,110,2,88,0,124,2,115,74,116,0,
+    124,1,100,2,100,0,131,3,100,0,107,8,114,166,124,0,
+    106,4,125,3,124,3,100,0,107,8,114,134,124,0,106,5,
+    100,0,107,9,114,134,116,6,100,0,107,8,114,110,116,7,
+    130,1,116,6,106,8,125,4,124,4,106,9,124,4,131,1,
+    125,3,124,0,106,5,124,3,95,10,121,10,124,3,124,1,
+    95,11,87,0,110,20,4,0,116,3,107,10,114,164,1,0,
+    1,0,1,0,89,0,110,2,88,0,124,2,115,186,116,0,
+    124,1,100,3,100,0,131,3,100,0,107,8,114,220,121,12,
+    124,0,106,12,124,1,95,13,87,0,110,20,4,0,116,3,
+    107,10,114,218,1,0,1,0,1,0,89,0,110,2,88,0,
+    121,10,124,0,124,1,95,14,87,0,110,20,4,0,116,3,
+    107,10,114,250,1,0,1,0,1,0,89,0,110,2,88,0,
+    124,2,144,1,115,20,116,0,124,1,100,4,100,0,131,3,
+    100,0,107,8,144,1,114,68,124,0,106,5,100,0,107,9,
+    144,1,114,68,121,12,124,0,106,5,124,1,95,15,87,0,
+    110,22,4,0,116,3,107,10,144,1,114,66,1,0,1,0,
+    1,0,89,0,110,2,88,0,124,0,106,16,144,1,114,208,
+    124,2,144,1,115,100,116,0,124,1,100,5,100,0,131,3,
+    100,0,107,8,144,1,114,136,121,12,124,0,106,17,124,1,
+    95,18,87,0,110,22,4,0,116,3,107,10,144,1,114,134,
+    1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1,
+    115,160,116,0,124,1,100,6,100,0,131,3,100,0,107,8,
+    144,1,114,208,124,0,106,19,100,0,107,9,144,1,114,208,
+    121,12,124,0,106,19,124,1,95,20,87,0,110,22,4,0,
+    116,3,107,10,144,1,114,206,1,0,1,0,1,0,89,0,
+    110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0,
+    114,86,0,0,0,218,11,95,95,112,97,99,107,97,103,101,
+    95,95,114,128,0,0,0,114,93,0,0,0,114,126,0,0,
+    0,41,21,114,6,0,0,0,114,15,0,0,0,114,1,0,
+    0,0,114,91,0,0,0,114,94,0,0,0,114,107,0,0,
+    0,114,116,0,0,0,114,117,0,0,0,218,16,95,78,97,
+    109,101,115,112,97,99,101,76,111,97,100,101,114,218,7,95,
+    95,110,101,119,95,95,90,5,95,112,97,116,104,114,86,0,
+    0,0,114,120,0,0,0,114,131,0,0,0,114,90,0,0,
+    0,114,128,0,0,0,114,114,0,0,0,114,104,0,0,0,
+    114,93,0,0,0,114,113,0,0,0,114,126,0,0,0,41,
+    5,114,83,0,0,0,114,84,0,0,0,114,130,0,0,0,
+    114,94,0,0,0,114,132,0,0,0,114,10,0,0,0,114,
+    10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116,
+    95,109,111,100,117,108,101,95,97,116,116,114,115,248,1,0,
+    0,115,92,0,0,0,0,4,20,1,2,1,12,1,14,1,
+    6,2,20,1,6,1,8,2,10,1,8,1,4,1,6,2,
+    10,1,8,1,2,1,10,1,14,1,6,2,20,1,2,1,
+    12,1,14,1,6,2,2,1,10,1,14,1,6,2,24,1,
+    12,1,2,1,12,1,16,1,6,2,8,1,24,1,2,1,
+    12,1,16,1,6,2,24,1,12,1,2,1,12,1,16,1,
+    6,1,114,134,0,0,0,99,1,0,0,0,0,0,0,0,
+    2,0,0,0,3,0,0,0,67,0,0,0,115,82,0,0,
+    0,100,1,125,1,116,0,124,0,106,1,100,2,131,2,114,
+    30,124,0,106,1,106,2,124,0,131,1,125,1,110,20,116,
+    0,124,0,106,1,100,3,131,2,114,50,116,3,100,4,131,
+    1,130,1,124,1,100,1,107,8,114,68,116,4,124,0,106,
+    5,131,1,125,1,116,6,124,0,124,1,131,2,1,0,124,
+    1,83,0,41,5,122,43,67,114,101,97,116,101,32,97,32,
+    109,111,100,117,108,101,32,98,97,115,101,100,32,111,110,32,
+    116,104,101,32,112,114,111,118,105,100,101,100,32,115,112,101,
+    99,46,78,218,13,99,114,101,97,116,101,95,109,111,100,117,
+    108,101,218,11,101,120,101,99,95,109,111,100,117,108,101,122,
+    66,108,111,97,100,101,114,115,32,116,104,97,116,32,100,101,
+    102,105,110,101,32,101,120,101,99,95,109,111,100,117,108,101,
+    40,41,32,109,117,115,116,32,97,108,115,111,32,100,101,102,
+    105,110,101,32,99,114,101,97,116,101,95,109,111,100,117,108,
+    101,40,41,41,7,114,4,0,0,0,114,94,0,0,0,114,
+    135,0,0,0,114,71,0,0,0,114,16,0,0,0,114,15,
+    0,0,0,114,134,0,0,0,41,2,114,83,0,0,0,114,
+    84,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,218,16,109,111,100,117,108,101,95,102,114,111,109,
+    95,115,112,101,99,52,2,0,0,115,18,0,0,0,0,3,
+    4,1,12,3,14,1,12,1,8,2,8,1,10,1,10,1,
+    114,137,0,0,0,99,1,0,0,0,0,0,0,0,2,0,
+    0,0,3,0,0,0,67,0,0,0,115,106,0,0,0,124,
+    0,106,0,100,1,107,8,114,14,100,2,110,4,124,0,106,
+    0,125,1,124,0,106,1,100,1,107,8,114,66,124,0,106,
+    2,100,1,107,8,114,50,100,3,106,3,124,1,131,1,83,
+    0,100,4,106,3,124,1,124,0,106,2,131,2,83,0,110,
+    36,124,0,106,4,114,86,100,5,106,3,124,1,124,0,106,
+    1,131,2,83,0,100,6,106,3,124,0,106,0,124,0,106,
+    1,131,2,83,0,100,1,83,0,41,7,122,38,82,101,116,
+    117,114,110,32,116,104,101,32,114,101,112,114,32,116,111,32,
+    117,115,101,32,102,111,114,32,116,104,101,32,109,111,100,117,
+    108,101,46,78,114,88,0,0,0,122,13,60,109,111,100,117,
+    108,101,32,123,33,114,125,62,122,20,60,109,111,100,117,108,
+    101,32,123,33,114,125,32,40,123,33,114,125,41,62,122,23,
+    60,109,111,100,117,108,101,32,123,33,114,125,32,102,114,111,
+    109,32,123,33,114,125,62,122,18,60,109,111,100,117,108,101,
+    32,123,33,114,125,32,40,123,125,41,62,41,5,114,15,0,
+    0,0,114,104,0,0,0,114,94,0,0,0,114,38,0,0,
+    0,114,114,0,0,0,41,2,114,83,0,0,0,114,15,0,
     0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,135,0,0,0,216,2,0,0,115,8,0,0,0,0,
-    3,12,1,12,1,10,1,122,29,66,117,105,108,116,105,110,
-    73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95,
-    109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,2,
-    0,0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,
-    116,0,116,1,106,2,124,1,131,2,1,0,100,1,83,0,
-    41,2,122,22,69,120,101,99,32,97,32,98,117,105,108,116,
-    45,105,110,32,109,111,100,117,108,101,78,41,3,114,59,0,
-    0,0,114,49,0,0,0,90,12,101,120,101,99,95,98,117,
-    105,108,116,105,110,41,2,114,26,0,0,0,114,84,0,0,
+    0,114,92,0,0,0,69,2,0,0,115,16,0,0,0,0,
+    3,20,1,10,1,10,1,10,2,16,2,6,1,14,2,114,
+    92,0,0,0,99,2,0,0,0,0,0,0,0,4,0,0,
+    0,12,0,0,0,67,0,0,0,115,178,0,0,0,124,0,
+    106,0,125,2,116,1,124,2,131,1,143,148,1,0,116,2,
+    106,3,106,4,124,2,131,1,124,1,107,9,114,54,100,1,
+    106,5,124,2,131,1,125,3,116,6,124,3,124,2,100,2,
+    141,2,130,1,124,0,106,7,100,3,107,8,114,106,124,0,
+    106,8,100,3,107,8,114,88,116,6,100,4,124,0,106,0,
+    100,2,141,2,130,1,116,9,124,0,124,1,100,5,100,6,
+    141,3,1,0,124,1,83,0,116,9,124,0,124,1,100,5,
+    100,6,141,3,1,0,116,10,124,0,106,7,100,7,131,2,
+    115,146,124,0,106,7,106,11,124,2,131,1,1,0,110,12,
+    124,0,106,7,106,12,124,1,131,1,1,0,87,0,100,3,
+    81,0,82,0,88,0,116,2,106,3,124,2,25,0,83,0,
+    41,8,122,70,69,120,101,99,117,116,101,32,116,104,101,32,
+    115,112,101,99,39,115,32,115,112,101,99,105,102,105,101,100,
+    32,109,111,100,117,108,101,32,105,110,32,97,110,32,101,120,
+    105,115,116,105,110,103,32,109,111,100,117,108,101,39,115,32,
+    110,97,109,101,115,112,97,99,101,46,122,30,109,111,100,117,
+    108,101,32,123,33,114,125,32,110,111,116,32,105,110,32,115,
+    121,115,46,109,111,100,117,108,101,115,41,1,114,15,0,0,
+    0,78,122,14,109,105,115,115,105,110,103,32,108,111,97,100,
+    101,114,84,41,1,114,130,0,0,0,114,136,0,0,0,41,
+    13,114,15,0,0,0,114,42,0,0,0,114,14,0,0,0,
+    114,80,0,0,0,114,30,0,0,0,114,38,0,0,0,114,
+    71,0,0,0,114,94,0,0,0,114,107,0,0,0,114,134,
+    0,0,0,114,4,0,0,0,218,11,108,111,97,100,95,109,
+    111,100,117,108,101,114,136,0,0,0,41,4,114,83,0,0,
+    0,114,84,0,0,0,114,15,0,0,0,218,3,109,115,103,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    81,0,0,0,86,2,0,0,115,30,0,0,0,0,2,6,
+    1,10,1,16,1,10,1,12,1,10,1,10,1,14,2,14,
+    1,4,1,14,1,12,4,14,2,22,1,114,81,0,0,0,
+    99,1,0,0,0,0,0,0,0,2,0,0,0,27,0,0,
+    0,67,0,0,0,115,206,0,0,0,124,0,106,0,106,1,
+    124,0,106,2,131,1,1,0,116,3,106,4,124,0,106,2,
+    25,0,125,1,116,5,124,1,100,1,100,0,131,3,100,0,
+    107,8,114,76,121,12,124,0,106,0,124,1,95,6,87,0,
+    110,20,4,0,116,7,107,10,114,74,1,0,1,0,1,0,
+    89,0,110,2,88,0,116,5,124,1,100,2,100,0,131,3,
+    100,0,107,8,114,154,121,40,124,1,106,8,124,1,95,9,
+    116,10,124,1,100,3,131,2,115,130,124,0,106,2,106,11,
+    100,4,131,1,100,5,25,0,124,1,95,9,87,0,110,20,
+    4,0,116,7,107,10,114,152,1,0,1,0,1,0,89,0,
+    110,2,88,0,116,5,124,1,100,6,100,0,131,3,100,0,
+    107,8,114,202,121,10,124,0,124,1,95,12,87,0,110,20,
+    4,0,116,7,107,10,114,200,1,0,1,0,1,0,89,0,
+    110,2,88,0,124,1,83,0,41,7,78,114,86,0,0,0,
+    114,131,0,0,0,114,128,0,0,0,114,118,0,0,0,114,
+    19,0,0,0,114,90,0,0,0,41,13,114,94,0,0,0,
+    114,138,0,0,0,114,15,0,0,0,114,14,0,0,0,114,
+    80,0,0,0,114,6,0,0,0,114,86,0,0,0,114,91,
+    0,0,0,114,1,0,0,0,114,131,0,0,0,114,4,0,
+    0,0,114,119,0,0,0,114,90,0,0,0,41,2,114,83,
+    0,0,0,114,84,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,218,25,95,108,111,97,100,95,98,
+    97,99,107,119,97,114,100,95,99,111,109,112,97,116,105,98,
+    108,101,110,2,0,0,115,40,0,0,0,0,4,14,2,12,
+    1,16,1,2,1,12,1,14,1,6,1,16,1,2,4,8,
+    1,10,1,22,1,14,1,6,1,16,1,2,1,10,1,14,
+    1,6,1,114,140,0,0,0,99,1,0,0,0,0,0,0,
+    0,2,0,0,0,11,0,0,0,67,0,0,0,115,118,0,
+    0,0,124,0,106,0,100,0,107,9,114,30,116,1,124,0,
+    106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0,
+    116,3,124,0,131,1,125,1,116,4,124,1,131,1,143,54,
+    1,0,124,0,106,0,100,0,107,8,114,84,124,0,106,5,
+    100,0,107,8,114,96,116,6,100,2,124,0,106,7,100,3,
+    141,2,130,1,110,12,124,0,106,0,106,8,124,1,131,1,
+    1,0,87,0,100,0,81,0,82,0,88,0,116,9,106,10,
+    124,0,106,7,25,0,83,0,41,4,78,114,136,0,0,0,
+    122,14,109,105,115,115,105,110,103,32,108,111,97,100,101,114,
+    41,1,114,15,0,0,0,41,11,114,94,0,0,0,114,4,
+    0,0,0,114,140,0,0,0,114,137,0,0,0,114,97,0,
+    0,0,114,107,0,0,0,114,71,0,0,0,114,15,0,0,
+    0,114,136,0,0,0,114,14,0,0,0,114,80,0,0,0,
+    41,2,114,83,0,0,0,114,84,0,0,0,114,10,0,0,
+    0,114,10,0,0,0,114,11,0,0,0,218,14,95,108,111,
+    97,100,95,117,110,108,111,99,107,101,100,139,2,0,0,115,
+    20,0,0,0,0,2,10,2,12,1,8,2,8,1,10,1,
+    10,1,10,1,16,3,22,5,114,141,0,0,0,99,1,0,
+    0,0,0,0,0,0,1,0,0,0,9,0,0,0,67,0,
+    0,0,115,30,0,0,0,116,0,124,0,106,1,131,1,143,
+    10,1,0,116,2,124,0,131,1,83,0,81,0,82,0,88,
+    0,100,1,83,0,41,2,122,191,82,101,116,117,114,110,32,
+    97,32,110,101,119,32,109,111,100,117,108,101,32,111,98,106,
+    101,99,116,44,32,108,111,97,100,101,100,32,98,121,32,116,
+    104,101,32,115,112,101,99,39,115,32,108,111,97,100,101,114,
+    46,10,10,32,32,32,32,84,104,101,32,109,111,100,117,108,
+    101,32,105,115,32,110,111,116,32,97,100,100,101,100,32,116,
+    111,32,105,116,115,32,112,97,114,101,110,116,46,10,10,32,
+    32,32,32,73,102,32,97,32,109,111,100,117,108,101,32,105,
+    115,32,97,108,114,101,97,100,121,32,105,110,32,115,121,115,
+    46,109,111,100,117,108,101,115,44,32,116,104,97,116,32,101,
+    120,105,115,116,105,110,103,32,109,111,100,117,108,101,32,103,
+    101,116,115,10,32,32,32,32,99,108,111,98,98,101,114,101,
+    100,46,10,10,32,32,32,32,78,41,3,114,42,0,0,0,
+    114,15,0,0,0,114,141,0,0,0,41,1,114,83,0,0,
     0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    114,136,0,0,0,224,2,0,0,115,2,0,0,0,0,3,
-    122,27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,
-    114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,
-    0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,
-    0,0,115,4,0,0,0,100,1,83,0,41,2,122,57,82,
-    101,116,117,114,110,32,78,111,110,101,32,97,115,32,98,117,
-    105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,100,
-    111,32,110,111,116,32,104,97,118,101,32,99,111,100,101,32,
-    111,98,106,101,99,116,115,46,78,114,10,0,0,0,41,2,
-    114,143,0,0,0,114,72,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,218,8,103,101,116,95,99,
-    111,100,101,229,2,0,0,115,2,0,0,0,0,4,122,24,
+    114,82,0,0,0,162,2,0,0,115,4,0,0,0,0,9,
+    12,1,114,82,0,0,0,99,0,0,0,0,0,0,0,0,
+    0,0,0,0,4,0,0,0,64,0,0,0,115,136,0,0,
+    0,101,0,90,1,100,0,90,2,100,1,90,3,101,4,100,
+    2,100,3,132,0,131,1,90,5,101,6,100,19,100,5,100,
+    6,132,1,131,1,90,7,101,6,100,20,100,7,100,8,132,
+    1,131,1,90,8,101,6,100,9,100,10,132,0,131,1,90,
+    9,101,6,100,11,100,12,132,0,131,1,90,10,101,6,101,
+    11,100,13,100,14,132,0,131,1,131,1,90,12,101,6,101,
+    11,100,15,100,16,132,0,131,1,131,1,90,13,101,6,101,
+    11,100,17,100,18,132,0,131,1,131,1,90,14,101,6,101,
+    15,131,1,90,16,100,4,83,0,41,21,218,15,66,117,105,
+    108,116,105,110,73,109,112,111,114,116,101,114,122,144,77,101,
+    116,97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,
+    111,114,32,98,117,105,108,116,45,105,110,32,109,111,100,117,
+    108,101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,
+    116,104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,
+    32,99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,
+    32,109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,
+    100,32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,
+    32,32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,
+    101,32,99,108,97,115,115,46,10,10,32,32,32,32,99,1,
+    0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67,
+    0,0,0,115,12,0,0,0,100,1,106,0,124,0,106,1,
+    131,1,83,0,41,2,122,115,82,101,116,117,114,110,32,114,
+    101,112,114,32,102,111,114,32,116,104,101,32,109,111,100,117,
+    108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,101,
+    32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,
+    99,97,116,101,100,46,32,32,84,104,101,32,105,109,112,111,
+    114,116,32,109,97,99,104,105,110,101,114,121,32,100,111,101,
+    115,32,116,104,101,32,106,111,98,32,105,116,115,101,108,102,
+    46,10,10,32,32,32,32,32,32,32,32,122,24,60,109,111,
+    100,117,108,101,32,123,33,114,125,32,40,98,117,105,108,116,
+    45,105,110,41,62,41,2,114,38,0,0,0,114,1,0,0,
+    0,41,1,114,84,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,87,0,0,0,186,2,0,0,
+    115,2,0,0,0,0,7,122,27,66,117,105,108,116,105,110,
+    73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95,
+    114,101,112,114,78,99,4,0,0,0,0,0,0,0,4,0,
+    0,0,5,0,0,0,67,0,0,0,115,44,0,0,0,124,
+    2,100,0,107,9,114,12,100,0,83,0,116,0,106,1,124,
+    1,131,1,114,36,116,2,124,1,124,0,100,1,100,2,141,
+    3,83,0,100,0,83,0,100,0,83,0,41,3,78,122,8,
+    98,117,105,108,116,45,105,110,41,1,114,104,0,0,0,41,
+    3,114,49,0,0,0,90,10,105,115,95,98,117,105,108,116,
+    105,110,114,79,0,0,0,41,4,218,3,99,108,115,114,72,
+    0,0,0,218,4,112,97,116,104,218,6,116,97,114,103,101,
+    116,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    218,9,102,105,110,100,95,115,112,101,99,195,2,0,0,115,
+    10,0,0,0,0,2,8,1,4,1,10,1,14,2,122,25,
     66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,
-    103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0,
-    0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,
-    0,0,100,1,83,0,41,2,122,56,82,101,116,117,114,110,
-    32,78,111,110,101,32,97,115,32,98,117,105,108,116,45,105,
-    110,32,109,111,100,117,108,101,115,32,100,111,32,110,111,116,
-    32,104,97,118,101,32,115,111,117,114,99,101,32,99,111,100,
-    101,46,78,114,10,0,0,0,41,2,114,143,0,0,0,114,
-    72,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
-    0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,235,
-    2,0,0,115,2,0,0,0,0,4,122,26,66,117,105,108,
-    116,105,110,73,109,112,111,114,116,101,114,46,103,101,116,95,
-    115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,2,
-    0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,
-    100,1,83,0,41,2,122,52,82,101,116,117,114,110,32,70,
-    97,108,115,101,32,97,115,32,98,117,105,108,116,45,105,110,
-    32,109,111,100,117,108,101,115,32,97,114,101,32,110,101,118,
-    101,114,32,112,97,99,107,97,103,101,115,46,70,114,10,0,
-    0,0,41,2,114,143,0,0,0,114,72,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,114,106,0,
-    0,0,241,2,0,0,115,2,0,0,0,0,4,122,26,66,
-    117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,105,
-    115,95,112,97,99,107,97,103,101,41,2,78,78,41,1,78,
-    41,17,114,1,0,0,0,114,0,0,0,0,114,2,0,0,
-    0,114,3,0,0,0,218,12,115,116,97,116,105,99,109,101,
-    116,104,111,100,114,87,0,0,0,218,11,99,108,97,115,115,
-    109,101,116,104,111,100,114,146,0,0,0,114,147,0,0,0,
-    114,135,0,0,0,114,136,0,0,0,114,75,0,0,0,114,
-    148,0,0,0,114,149,0,0,0,114,106,0,0,0,114,85,
-    0,0,0,114,138,0,0,0,114,10,0,0,0,114,10,0,
-    0,0,114,10,0,0,0,114,11,0,0,0,114,142,0,0,
-    0,177,2,0,0,115,30,0,0,0,8,7,4,2,12,9,
-    2,1,12,8,2,1,12,11,12,8,12,5,2,1,14,5,
-    2,1,14,5,2,1,14,5,114,142,0,0,0,99,0,0,
-    0,0,0,0,0,0,0,0,0,0,4,0,0,0,64,0,
-    0,0,115,140,0,0,0,101,0,90,1,100,0,90,2,100,
-    1,90,3,101,4,100,2,100,3,132,0,131,1,90,5,101,
-    6,100,21,100,5,100,6,132,1,131,1,90,7,101,6,100,
-    22,100,7,100,8,132,1,131,1,90,8,101,6,100,9,100,
-    10,132,0,131,1,90,9,101,4,100,11,100,12,132,0,131,
-    1,90,10,101,6,100,13,100,14,132,0,131,1,90,11,101,
-    6,101,12,100,15,100,16,132,0,131,1,131,1,90,13,101,
-    6,101,12,100,17,100,18,132,0,131,1,131,1,90,14,101,
-    6,101,12,100,19,100,20,132,0,131,1,131,1,90,15,100,
-    4,83,0,41,23,218,14,70,114,111,122,101,110,73,109,112,
-    111,114,116,101,114,122,142,77,101,116,97,32,112,97,116,104,
-    32,105,109,112,111,114,116,32,102,111,114,32,102,114,111,122,
-    101,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32,
-    32,65,108,108,32,109,101,116,104,111,100,115,32,97,114,101,
-    32,101,105,116,104,101,114,32,99,108,97,115,115,32,111,114,
-    32,115,116,97,116,105,99,32,109,101,116,104,111,100,115,32,
-    116,111,32,97,118,111,105,100,32,116,104,101,32,110,101,101,
-    100,32,116,111,10,32,32,32,32,105,110,115,116,97,110,116,
-    105,97,116,101,32,116,104,101,32,99,108,97,115,115,46,10,
-    10,32,32,32,32,99,1,0,0,0,0,0,0,0,1,0,
-    0,0,2,0,0,0,67,0,0,0,115,12,0,0,0,100,
-    1,106,0,124,0,106,1,131,1,83,0,41,2,122,115,82,
-    101,116,117,114,110,32,114,101,112,114,32,102,111,114,32,116,
-    104,101,32,109,111,100,117,108,101,46,10,10,32,32,32,32,
-    32,32,32,32,84,104,101,32,109,101,116,104,111,100,32,105,
-    115,32,100,101,112,114,101,99,97,116,101,100,46,32,32,84,
-    104,101,32,105,109,112,111,114,116,32,109,97,99,104,105,110,
-    101,114,121,32,100,111,101,115,32,116,104,101,32,106,111,98,
-    32,105,116,115,101,108,102,46,10,10,32,32,32,32,32,32,
-    32,32,122,22,60,109,111,100,117,108,101,32,123,33,114,125,
-    32,40,102,114,111,122,101,110,41,62,41,2,114,38,0,0,
-    0,114,1,0,0,0,41,1,218,1,109,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,87,0,0,0,3,
-    3,0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,
-    101,110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,
-    101,95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,
-    4,0,0,0,5,0,0,0,67,0,0,0,115,32,0,0,
-    0,116,0,106,1,124,1,131,1,114,24,116,2,124,1,124,
-    0,100,1,100,2,141,3,83,0,100,0,83,0,100,0,83,
-    0,41,3,78,90,6,102,114,111,122,101,110,41,1,114,104,
-    0,0,0,41,3,114,49,0,0,0,114,76,0,0,0,114,
-    79,0,0,0,41,4,114,143,0,0,0,114,72,0,0,0,
-    114,144,0,0,0,114,145,0,0,0,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,146,0,0,0,12,3,
-    0,0,115,6,0,0,0,0,2,10,1,14,2,122,24,70,
-    114,111,122,101,110,73,109,112,111,114,116,101,114,46,102,105,
-    110,100,95,115,112,101,99,99,3,0,0,0,0,0,0,0,
-    3,0,0,0,2,0,0,0,67,0,0,0,115,18,0,0,
-    0,116,0,106,1,124,1,131,1,114,14,124,0,83,0,100,
-    1,83,0,41,2,122,93,70,105,110,100,32,97,32,102,114,
-    111,122,101,110,32,109,111,100,117,108,101,46,10,10,32,32,
+    102,105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,
+    0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,30,
+    0,0,0,124,0,106,0,124,1,124,2,131,2,125,3,124,
+    3,100,1,107,9,114,26,124,3,106,1,83,0,100,1,83,
+    0,41,2,122,175,70,105,110,100,32,116,104,101,32,98,117,
+    105,108,116,45,105,110,32,109,111,100,117,108,101,46,10,10,
+    32,32,32,32,32,32,32,32,73,102,32,39,112,97,116,104,
+    39,32,105,115,32,101,118,101,114,32,115,112,101,99,105,102,
+    105,101,100,32,116,104,101,110,32,116,104,101,32,115,101,97,
+    114,99,104,32,105,115,32,99,111,110,115,105,100,101,114,101,
+    100,32,97,32,102,97,105,108,117,114,101,46,10,10,32,32,
     32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,
     100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,
     32,32,85,115,101,32,102,105,110,100,95,115,112,101,99,40,
     41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32,
-    32,32,32,32,78,41,2,114,49,0,0,0,114,76,0,0,
-    0,41,3,114,143,0,0,0,114,72,0,0,0,114,144,0,
-    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
-    0,114,147,0,0,0,19,3,0,0,115,2,0,0,0,0,
-    7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,
+    32,32,32,32,78,41,2,114,146,0,0,0,114,94,0,0,
+    0,41,4,114,143,0,0,0,114,72,0,0,0,114,144,0,
+    0,0,114,83,0,0,0,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,11,102,105,110,100,95,109,111,100,
+    117,108,101,204,2,0,0,115,4,0,0,0,0,9,12,1,
+    122,27,66,117,105,108,116,105,110,73,109,112,111,114,116,101,
     114,46,102,105,110,100,95,109,111,100,117,108,101,99,2,0,
-    0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,
-    0,0,115,4,0,0,0,100,1,83,0,41,2,122,42,85,
-    115,101,32,100,101,102,97,117,108,116,32,115,101,109,97,110,
-    116,105,99,115,32,102,111,114,32,109,111,100,117,108,101,32,
-    99,114,101,97,116,105,111,110,46,78,114,10,0,0,0,41,
-    2,114,143,0,0,0,114,83,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,135,0,0,0,28,
-    3,0,0,115,0,0,0,0,122,28,70,114,111,122,101,110,
-    73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95,
-    109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,3,
-    0,0,0,4,0,0,0,67,0,0,0,115,64,0,0,0,
-    124,0,106,0,106,1,125,1,116,2,106,3,124,1,131,1,
-    115,36,116,4,100,1,106,5,124,1,131,1,124,1,100,2,
-    141,2,130,1,116,6,116,2,106,7,124,1,131,2,125,2,
-    116,8,124,2,124,0,106,9,131,2,1,0,100,0,83,0,
-    41,3,78,122,27,123,33,114,125,32,105,115,32,110,111,116,
-    32,97,32,102,114,111,122,101,110,32,109,111,100,117,108,101,
-    41,1,114,15,0,0,0,41,10,114,90,0,0,0,114,15,
-    0,0,0,114,49,0,0,0,114,76,0,0,0,114,71,0,
-    0,0,114,38,0,0,0,114,59,0,0,0,218,17,103,101,
-    116,95,102,114,111,122,101,110,95,111,98,106,101,99,116,218,
-    4,101,120,101,99,114,7,0,0,0,41,3,114,84,0,0,
-    0,114,15,0,0,0,218,4,99,111,100,101,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,114,136,0,0,0,
-    32,3,0,0,115,12,0,0,0,0,2,8,1,10,1,10,
-    1,8,1,12,1,122,26,70,114,111,122,101,110,73,109,112,
-    111,114,116,101,114,46,101,120,101,99,95,109,111,100,117,108,
-    101,99,2,0,0,0,0,0,0,0,2,0,0,0,3,0,
-    0,0,67,0,0,0,115,10,0,0,0,116,0,124,0,124,
-    1,131,2,83,0,41,1,122,95,76,111,97,100,32,97,32,
-    102,114,111,122,101,110,32,109,111,100,117,108,101,46,10,10,
-    32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,
-    104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,
-    100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100,
-    117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10,
-    32,32,32,32,32,32,32,32,41,1,114,85,0,0,0,41,
-    2,114,143,0,0,0,114,72,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,138,0,0,0,41,
-    3,0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,
-    101,110,73,109,112,111,114,116,101,114,46,108,111,97,100,95,
-    109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,2,
-    0,0,0,2,0,0,0,67,0,0,0,115,10,0,0,0,
-    116,0,106,1,124,1,131,1,83,0,41,1,122,45,82,101,
-    116,117,114,110,32,116,104,101,32,99,111,100,101,32,111,98,
-    106,101,99,116,32,102,111,114,32,116,104,101,32,102,114,111,
-    122,101,110,32,109,111,100,117,108,101,46,41,2,114,49,0,
-    0,0,114,154,0,0,0,41,2,114,143,0,0,0,114,72,
+    0,0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,
+    0,0,115,46,0,0,0,124,1,106,0,116,1,106,2,107,
+    7,114,34,116,3,100,1,106,4,124,1,106,0,131,1,124,
+    1,106,0,100,2,141,2,130,1,116,5,116,6,106,7,124,
+    1,131,2,83,0,41,3,122,24,67,114,101,97,116,101,32,
+    97,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,
+    101,122,29,123,33,114,125,32,105,115,32,110,111,116,32,97,
+    32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+    41,1,114,15,0,0,0,41,8,114,15,0,0,0,114,14,
+    0,0,0,114,70,0,0,0,114,71,0,0,0,114,38,0,
+    0,0,114,59,0,0,0,114,49,0,0,0,90,14,99,114,
+    101,97,116,101,95,98,117,105,108,116,105,110,41,2,114,26,
+    0,0,0,114,83,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,135,0,0,0,216,2,0,0,
+    115,8,0,0,0,0,3,12,1,12,1,10,1,122,29,66,
+    117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,99,
+    114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,
+    0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,
+    0,115,16,0,0,0,116,0,116,1,106,2,124,1,131,2,
+    1,0,100,1,83,0,41,2,122,22,69,120,101,99,32,97,
+    32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+    78,41,3,114,59,0,0,0,114,49,0,0,0,90,12,101,
+    120,101,99,95,98,117,105,108,116,105,110,41,2,114,26,0,
+    0,0,114,84,0,0,0,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,114,136,0,0,0,224,2,0,0,115,
+    2,0,0,0,0,3,122,27,66,117,105,108,116,105,110,73,
+    109,112,111,114,116,101,114,46,101,120,101,99,95,109,111,100,
+    117,108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,
+    1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,
+    0,41,2,122,57,82,101,116,117,114,110,32,78,111,110,101,
+    32,97,115,32,98,117,105,108,116,45,105,110,32,109,111,100,
+    117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101,
+    32,99,111,100,101,32,111,98,106,101,99,116,115,46,78,114,
+    10,0,0,0,41,2,114,143,0,0,0,114,72,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,
+    8,103,101,116,95,99,111,100,101,229,2,0,0,115,2,0,
+    0,0,0,4,122,24,66,117,105,108,116,105,110,73,109,112,
+    111,114,116,101,114,46,103,101,116,95,99,111,100,101,99,2,
+    0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,
+    0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,56,
+    82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,98,
+    117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,
+    100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,114,
+    99,101,32,99,111,100,101,46,78,114,10,0,0,0,41,2,
+    114,143,0,0,0,114,72,0,0,0,114,10,0,0,0,114,
+    10,0,0,0,114,11,0,0,0,218,10,103,101,116,95,115,
+    111,117,114,99,101,235,2,0,0,115,2,0,0,0,0,4,
+    122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101,
+    114,46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,
+    0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,
+    0,115,4,0,0,0,100,1,83,0,41,2,122,52,82,101,
+    116,117,114,110,32,70,97,108,115,101,32,97,115,32,98,117,
+    105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,
+    114,101,32,110,101,118,101,114,32,112,97,99,107,97,103,101,
+    115,46,70,114,10,0,0,0,41,2,114,143,0,0,0,114,
+    72,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,106,0,0,0,241,2,0,0,115,2,0,0,
+    0,0,4,122,26,66,117,105,108,116,105,110,73,109,112,111,
+    114,116,101,114,46,105,115,95,112,97,99,107,97,103,101,41,
+    2,78,78,41,1,78,41,17,114,1,0,0,0,114,0,0,
+    0,0,114,2,0,0,0,114,3,0,0,0,218,12,115,116,
+    97,116,105,99,109,101,116,104,111,100,114,87,0,0,0,218,
+    11,99,108,97,115,115,109,101,116,104,111,100,114,146,0,0,
+    0,114,147,0,0,0,114,135,0,0,0,114,136,0,0,0,
+    114,75,0,0,0,114,148,0,0,0,114,149,0,0,0,114,
+    106,0,0,0,114,85,0,0,0,114,138,0,0,0,114,10,
     0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,114,148,0,0,0,50,3,0,0,115,2,0,0,0,
-    0,4,122,23,70,114,111,122,101,110,73,109,112,111,114,116,
-    101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,
-    0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,
-    115,4,0,0,0,100,1,83,0,41,2,122,54,82,101,116,
-    117,114,110,32,78,111,110,101,32,97,115,32,102,114,111,122,
-    101,110,32,109,111,100,117,108,101,115,32,100,111,32,110,111,
-    116,32,104,97,118,101,32,115,111,117,114,99,101,32,99,111,
-    100,101,46,78,114,10,0,0,0,41,2,114,143,0,0,0,
-    114,72,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
-    11,0,0,0,114,149,0,0,0,56,3,0,0,115,2,0,
-    0,0,0,4,122,25,70,114,111,122,101,110,73,109,112,111,
-    114,116,101,114,46,103,101,116,95,115,111,117,114,99,101,99,
-    2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,
-    67,0,0,0,115,10,0,0,0,116,0,106,1,124,1,131,
-    1,83,0,41,1,122,46,82,101,116,117,114,110,32,84,114,
-    117,101,32,105,102,32,116,104,101,32,102,114,111,122,101,110,
-    32,109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,
-    107,97,103,101,46,41,2,114,49,0,0,0,90,17,105,115,
-    95,102,114,111,122,101,110,95,112,97,99,107,97,103,101,41,
+    0,0,114,142,0,0,0,177,2,0,0,115,30,0,0,0,
+    8,7,4,2,12,9,2,1,12,8,2,1,12,11,12,8,
+    12,5,2,1,14,5,2,1,14,5,2,1,14,5,114,142,
+    0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,
+    4,0,0,0,64,0,0,0,115,140,0,0,0,101,0,90,
+    1,100,0,90,2,100,1,90,3,101,4,100,2,100,3,132,
+    0,131,1,90,5,101,6,100,21,100,5,100,6,132,1,131,
+    1,90,7,101,6,100,22,100,7,100,8,132,1,131,1,90,
+    8,101,6,100,9,100,10,132,0,131,1,90,9,101,4,100,
+    11,100,12,132,0,131,1,90,10,101,6,100,13,100,14,132,
+    0,131,1,90,11,101,6,101,12,100,15,100,16,132,0,131,
+    1,131,1,90,13,101,6,101,12,100,17,100,18,132,0,131,
+    1,131,1,90,14,101,6,101,12,100,19,100,20,132,0,131,
+    1,131,1,90,15,100,4,83,0,41,23,218,14,70,114,111,
+    122,101,110,73,109,112,111,114,116,101,114,122,142,77,101,116,
+    97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,111,
+    114,32,102,114,111,122,101,110,32,109,111,100,117,108,101,115,
+    46,10,10,32,32,32,32,65,108,108,32,109,101,116,104,111,
+    100,115,32,97,114,101,32,101,105,116,104,101,114,32,99,108,
+    97,115,115,32,111,114,32,115,116,97,116,105,99,32,109,101,
+    116,104,111,100,115,32,116,111,32,97,118,111,105,100,32,116,
+    104,101,32,110,101,101,100,32,116,111,10,32,32,32,32,105,
+    110,115,116,97,110,116,105,97,116,101,32,116,104,101,32,99,
+    108,97,115,115,46,10,10,32,32,32,32,99,1,0,0,0,
+    0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0,
+    115,12,0,0,0,100,1,106,0,124,0,106,1,131,1,83,
+    0,41,2,122,115,82,101,116,117,114,110,32,114,101,112,114,
+    32,102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,
+    10,10,32,32,32,32,32,32,32,32,84,104,101,32,109,101,
+    116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,
+    101,100,46,32,32,84,104,101,32,105,109,112,111,114,116,32,
+    109,97,99,104,105,110,101,114,121,32,100,111,101,115,32,116,
+    104,101,32,106,111,98,32,105,116,115,101,108,102,46,10,10,
+    32,32,32,32,32,32,32,32,122,22,60,109,111,100,117,108,
+    101,32,123,33,114,125,32,40,102,114,111,122,101,110,41,62,
+    41,2,114,38,0,0,0,114,1,0,0,0,41,1,218,1,
+    109,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    114,87,0,0,0,3,3,0,0,115,2,0,0,0,0,7,
+    122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,
+    46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0,
+    0,0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,
+    0,0,115,32,0,0,0,116,0,106,1,124,1,131,1,114,
+    24,116,2,124,1,124,0,100,1,100,2,141,3,83,0,100,
+    0,83,0,100,0,83,0,41,3,78,90,6,102,114,111,122,
+    101,110,41,1,114,104,0,0,0,41,3,114,49,0,0,0,
+    114,76,0,0,0,114,79,0,0,0,41,4,114,143,0,0,
+    0,114,72,0,0,0,114,144,0,0,0,114,145,0,0,0,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    146,0,0,0,12,3,0,0,115,6,0,0,0,0,2,10,
+    1,14,2,122,24,70,114,111,122,101,110,73,109,112,111,114,
+    116,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,
+    0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,
+    0,0,115,18,0,0,0,116,0,106,1,124,1,131,1,114,
+    14,124,0,83,0,100,1,83,0,41,2,122,93,70,105,110,
+    100,32,97,32,102,114,111,122,101,110,32,109,111,100,117,108,
+    101,46,10,10,32,32,32,32,32,32,32,32,84,104,105,115,
+    32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,
+    99,97,116,101,100,46,32,32,85,115,101,32,102,105,110,100,
+    95,115,112,101,99,40,41,32,105,110,115,116,101,97,100,46,
+    10,10,32,32,32,32,32,32,32,32,78,41,2,114,49,0,
+    0,0,114,76,0,0,0,41,3,114,143,0,0,0,114,72,
+    0,0,0,114,144,0,0,0,114,10,0,0,0,114,10,0,
+    0,0,114,11,0,0,0,114,147,0,0,0,19,3,0,0,
+    115,2,0,0,0,0,7,122,26,70,114,111,122,101,110,73,
+    109,112,111,114,116,101,114,46,102,105,110,100,95,109,111,100,
+    117,108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,
+    1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,
+    0,41,2,122,42,85,115,101,32,100,101,102,97,117,108,116,
+    32,115,101,109,97,110,116,105,99,115,32,102,111,114,32,109,
+    111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,78,
+    114,10,0,0,0,41,2,114,143,0,0,0,114,83,0,0,
+    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    114,135,0,0,0,28,3,0,0,115,0,0,0,0,122,28,
+    70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,99,
+    114,101,97,116,101,95,109,111,100,117,108,101,99,1,0,0,
+    0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0,
+    0,115,64,0,0,0,124,0,106,0,106,1,125,1,116,2,
+    106,3,124,1,131,1,115,36,116,4,100,1,106,5,124,1,
+    131,1,124,1,100,2,141,2,130,1,116,6,116,2,106,7,
+    124,1,131,2,125,2,116,8,124,2,124,0,106,9,131,2,
+    1,0,100,0,83,0,41,3,78,122,27,123,33,114,125,32,
+    105,115,32,110,111,116,32,97,32,102,114,111,122,101,110,32,
+    109,111,100,117,108,101,41,1,114,15,0,0,0,41,10,114,
+    90,0,0,0,114,15,0,0,0,114,49,0,0,0,114,76,
+    0,0,0,114,71,0,0,0,114,38,0,0,0,114,59,0,
+    0,0,218,17,103,101,116,95,102,114,111,122,101,110,95,111,
+    98,106,101,99,116,218,4,101,120,101,99,114,7,0,0,0,
+    41,3,114,84,0,0,0,114,15,0,0,0,218,4,99,111,
+    100,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+    0,114,136,0,0,0,32,3,0,0,115,12,0,0,0,0,
+    2,8,1,10,1,10,1,8,1,12,1,122,26,70,114,111,
+    122,101,110,73,109,112,111,114,116,101,114,46,101,120,101,99,
+    95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,
+    2,0,0,0,3,0,0,0,67,0,0,0,115,10,0,0,
+    0,116,0,124,0,124,1,131,2,83,0,41,1,122,95,76,
+    111,97,100,32,97,32,102,114,111,122,101,110,32,109,111,100,
+    117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,
+    105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,
+    114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120,
+    101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116,
+    101,97,100,46,10,10,32,32,32,32,32,32,32,32,41,1,
+    114,85,0,0,0,41,2,114,143,0,0,0,114,72,0,0,
+    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    114,138,0,0,0,41,3,0,0,115,2,0,0,0,0,7,
+    122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,
+    46,108,111,97,100,95,109,111,100,117,108,101,99,2,0,0,
+    0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,
+    0,115,10,0,0,0,116,0,106,1,124,1,131,1,83,0,
+    41,1,122,45,82,101,116,117,114,110,32,116,104,101,32,99,
+    111,100,101,32,111,98,106,101,99,116,32,102,111,114,32,116,
+    104,101,32,102,114,111,122,101,110,32,109,111,100,117,108,101,
+    46,41,2,114,49,0,0,0,114,154,0,0,0,41,2,114,
+    143,0,0,0,114,72,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,114,148,0,0,0,50,3,0,
+    0,115,2,0,0,0,0,4,122,23,70,114,111,122,101,110,
+    73,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100,
+    101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,
+    0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,
+    2,122,54,82,101,116,117,114,110,32,78,111,110,101,32,97,
+    115,32,102,114,111,122,101,110,32,109,111,100,117,108,101,115,
+    32,100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,
+    114,99,101,32,99,111,100,101,46,78,114,10,0,0,0,41,
     2,114,143,0,0,0,114,72,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,114,106,0,0,0,62,
+    114,10,0,0,0,114,11,0,0,0,114,149,0,0,0,56,
     3,0,0,115,2,0,0,0,0,4,122,25,70,114,111,122,
-    101,110,73,109,112,111,114,116,101,114,46,105,115,95,112,97,
-    99,107,97,103,101,41,2,78,78,41,1,78,41,16,114,1,
-    0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,0,
-    0,0,114,150,0,0,0,114,87,0,0,0,114,151,0,0,
-    0,114,146,0,0,0,114,147,0,0,0,114,135,0,0,0,
-    114,136,0,0,0,114,138,0,0,0,114,78,0,0,0,114,
-    148,0,0,0,114,149,0,0,0,114,106,0,0,0,114,10,
-    0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,114,152,0,0,0,250,2,0,0,115,30,0,0,0,
-    8,7,4,2,12,9,2,1,12,6,2,1,12,8,12,4,
-    12,9,12,9,2,1,14,5,2,1,14,5,2,1,114,152,
-    0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,
-    2,0,0,0,64,0,0,0,115,32,0,0,0,101,0,90,
-    1,100,0,90,2,100,1,90,3,100,2,100,3,132,0,90,
-    4,100,4,100,5,132,0,90,5,100,6,83,0,41,7,218,
-    18,95,73,109,112,111,114,116,76,111,99,107,67,111,110,116,
-    101,120,116,122,36,67,111,110,116,101,120,116,32,109,97,110,
-    97,103,101,114,32,102,111,114,32,116,104,101,32,105,109,112,
-    111,114,116,32,108,111,99,107,46,99,1,0,0,0,0,0,
-    0,0,1,0,0,0,1,0,0,0,67,0,0,0,115,12,
-    0,0,0,116,0,106,1,131,0,1,0,100,1,83,0,41,
-    2,122,24,65,99,113,117,105,114,101,32,116,104,101,32,105,
-    109,112,111,114,116,32,108,111,99,107,46,78,41,2,114,49,
-    0,0,0,114,50,0,0,0,41,1,114,26,0,0,0,114,
-    10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,46,
-    0,0,0,75,3,0,0,115,2,0,0,0,0,2,122,28,
-    95,73,109,112,111,114,116,76,111,99,107,67,111,110,116,101,
-    120,116,46,95,95,101,110,116,101,114,95,95,99,4,0,0,
-    0,0,0,0,0,4,0,0,0,1,0,0,0,67,0,0,
-    0,115,12,0,0,0,116,0,106,1,131,0,1,0,100,1,
-    83,0,41,2,122,60,82,101,108,101,97,115,101,32,116,104,
-    101,32,105,109,112,111,114,116,32,108,111,99,107,32,114,101,
-    103,97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,
-    114,97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,
-    115,46,78,41,2,114,49,0,0,0,114,52,0,0,0,41,
-    4,114,26,0,0,0,90,8,101,120,99,95,116,121,112,101,
-    90,9,101,120,99,95,118,97,108,117,101,90,13,101,120,99,
-    95,116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,
-    10,0,0,0,114,11,0,0,0,114,48,0,0,0,79,3,
-    0,0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,
-    114,116,76,111,99,107,67,111,110,116,101,120,116,46,95,95,
-    101,120,105,116,95,95,78,41,6,114,1,0,0,0,114,0,
-    0,0,0,114,2,0,0,0,114,3,0,0,0,114,46,0,
-    0,0,114,48,0,0,0,114,10,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,114,157,0,0,0,
-    71,3,0,0,115,6,0,0,0,8,2,4,2,8,4,114,
-    157,0,0,0,99,3,0,0,0,0,0,0,0,5,0,0,
-    0,4,0,0,0,67,0,0,0,115,64,0,0,0,124,1,
-    106,0,100,1,124,2,100,2,24,0,131,2,125,3,116,1,
-    124,3,131,1,124,2,107,0,114,36,116,2,100,3,131,1,
-    130,1,124,3,100,4,25,0,125,4,124,0,114,60,100,5,
-    106,3,124,4,124,0,131,2,83,0,124,4,83,0,41,6,
-    122,50,82,101,115,111,108,118,101,32,97,32,114,101,108,97,
-    116,105,118,101,32,109,111,100,117,108,101,32,110,97,109,101,
-    32,116,111,32,97,110,32,97,98,115,111,108,117,116,101,32,
-    111,110,101,46,114,118,0,0,0,114,33,0,0,0,122,50,
-    97,116,116,101,109,112,116,101,100,32,114,101,108,97,116,105,
-    118,101,32,105,109,112,111,114,116,32,98,101,121,111,110,100,
-    32,116,111,112,45,108,101,118,101,108,32,112,97,99,107,97,
-    103,101,114,19,0,0,0,122,5,123,125,46,123,125,41,4,
-    218,6,114,115,112,108,105,116,218,3,108,101,110,218,10,86,
-    97,108,117,101,69,114,114,111,114,114,38,0,0,0,41,5,
-    114,15,0,0,0,218,7,112,97,99,107,97,103,101,218,5,
-    108,101,118,101,108,90,4,98,105,116,115,90,4,98,97,115,
-    101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,13,95,114,101,115,111,108,118,101,95,110,97,109,101,84,
-    3,0,0,115,10,0,0,0,0,2,16,1,12,1,8,1,
-    8,1,114,163,0,0,0,99,3,0,0,0,0,0,0,0,
-    4,0,0,0,3,0,0,0,67,0,0,0,115,34,0,0,
-    0,124,0,106,0,124,1,124,2,131,2,125,3,124,3,100,
-    0,107,8,114,24,100,0,83,0,116,1,124,1,124,3,131,
-    2,83,0,41,1,78,41,2,114,147,0,0,0,114,79,0,
-    0,0,41,4,218,6,102,105,110,100,101,114,114,15,0,0,
-    0,114,144,0,0,0,114,94,0,0,0,114,10,0,0,0,
-    114,10,0,0,0,114,11,0,0,0,218,17,95,102,105,110,
-    100,95,115,112,101,99,95,108,101,103,97,99,121,93,3,0,
-    0,115,8,0,0,0,0,3,12,1,8,1,4,1,114,165,
-    0,0,0,99,3,0,0,0,0,0,0,0,10,0,0,0,
-    27,0,0,0,67,0,0,0,115,242,0,0,0,116,0,106,
-    1,125,3,124,3,100,1,107,8,114,22,116,2,100,2,131,
-    1,130,1,124,3,115,38,116,3,106,4,100,3,116,5,131,
-    2,1,0,124,0,116,0,106,6,107,6,125,4,120,188,124,
-    3,68,0,93,176,125,5,116,7,131,0,143,72,1,0,121,
-    10,124,5,106,8,125,6,87,0,110,42,4,0,116,9,107,
-    10,114,118,1,0,1,0,1,0,116,10,124,5,124,0,124,
-    1,131,3,125,7,124,7,100,1,107,8,114,114,119,54,89,
-    0,110,14,88,0,124,6,124,0,124,1,124,2,131,3,125,
-    7,87,0,100,1,81,0,82,0,88,0,124,7,100,1,107,
-    9,114,54,124,4,12,0,114,226,124,0,116,0,106,6,107,
-    6,114,226,116,0,106,6,124,0,25,0,125,8,121,10,124,
-    8,106,11,125,9,87,0,110,20,4,0,116,9,107,10,114,
-    206,1,0,1,0,1,0,124,7,83,0,88,0,124,9,100,
-    1,107,8,114,220,124,7,83,0,124,9,83,0,113,54,124,
-    7,83,0,113,54,87,0,100,1,83,0,100,1,83,0,41,
-    4,122,21,70,105,110,100,32,97,32,109,111,100,117,108,101,
-    39,115,32,115,112,101,99,46,78,122,53,115,121,115,46,109,
-    101,116,97,95,112,97,116,104,32,105,115,32,78,111,110,101,
-    44,32,80,121,116,104,111,110,32,105,115,32,108,105,107,101,
-    108,121,32,115,104,117,116,116,105,110,103,32,100,111,119,110,
-    122,22,115,121,115,46,109,101,116,97,95,112,97,116,104,32,
-    105,115,32,101,109,112,116,121,41,12,114,14,0,0,0,218,
-    9,109,101,116,97,95,112,97,116,104,114,71,0,0,0,218,
-    9,95,119,97,114,110,105,110,103,115,218,4,119,97,114,110,
-    218,13,73,109,112,111,114,116,87,97,114,110,105,110,103,114,
-    80,0,0,0,114,157,0,0,0,114,146,0,0,0,114,91,
-    0,0,0,114,165,0,0,0,114,90,0,0,0,41,10,114,
-    15,0,0,0,114,144,0,0,0,114,145,0,0,0,114,166,
-    0,0,0,90,9,105,115,95,114,101,108,111,97,100,114,164,
-    0,0,0,114,146,0,0,0,114,83,0,0,0,114,84,0,
-    0,0,114,90,0,0,0,114,10,0,0,0,114,10,0,0,
-    0,114,11,0,0,0,218,10,95,102,105,110,100,95,115,112,
-    101,99,102,3,0,0,115,54,0,0,0,0,2,6,1,8,
-    2,8,3,4,1,12,5,10,1,10,1,8,1,2,1,10,
-    1,14,1,12,1,8,1,8,2,22,1,8,2,16,1,10,
-    1,2,1,10,1,14,4,6,2,8,1,4,2,6,2,8,
-    2,114,170,0,0,0,99,3,0,0,0,0,0,0,0,3,
-    0,0,0,4,0,0,0,67,0,0,0,115,110,0,0,0,
-    116,0,124,0,116,1,131,2,115,28,116,2,100,1,106,3,
-    116,4,124,0,131,1,131,1,131,1,130,1,124,2,100,2,
-    107,0,114,44,116,5,100,3,131,1,130,1,124,2,100,2,
-    107,4,114,84,116,0,124,1,116,1,131,2,115,72,116,2,
-    100,4,131,1,130,1,110,12,124,1,115,84,116,6,100,5,
-    131,1,130,1,124,0,12,0,114,106,124,2,100,2,107,2,
-    114,106,116,5,100,6,131,1,130,1,100,7,83,0,41,8,
-    122,28,86,101,114,105,102,121,32,97,114,103,117,109,101,110,
-    116,115,32,97,114,101,32,34,115,97,110,101,34,46,122,31,
-    109,111,100,117,108,101,32,110,97,109,101,32,109,117,115,116,
-    32,98,101,32,115,116,114,44,32,110,111,116,32,123,125,114,
-    19,0,0,0,122,18,108,101,118,101,108,32,109,117,115,116,
-    32,98,101,32,62,61,32,48,122,31,95,95,112,97,99,107,
-    97,103,101,95,95,32,110,111,116,32,115,101,116,32,116,111,
-    32,97,32,115,116,114,105,110,103,122,54,97,116,116,101,109,
-    112,116,101,100,32,114,101,108,97,116,105,118,101,32,105,109,
-    112,111,114,116,32,119,105,116,104,32,110,111,32,107,110,111,
-    119,110,32,112,97,114,101,110,116,32,112,97,99,107,97,103,
-    101,122,17,69,109,112,116,121,32,109,111,100,117,108,101,32,
-    110,97,109,101,78,41,7,218,10,105,115,105,110,115,116,97,
-    110,99,101,218,3,115,116,114,218,9,84,121,112,101,69,114,
-    114,111,114,114,38,0,0,0,114,13,0,0,0,114,160,0,
-    0,0,114,71,0,0,0,41,3,114,15,0,0,0,114,161,
-    0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,0,
-    0,0,114,11,0,0,0,218,13,95,115,97,110,105,116,121,
-    95,99,104,101,99,107,149,3,0,0,115,22,0,0,0,0,
-    2,10,1,18,1,8,1,8,1,8,1,10,1,10,1,4,
-    1,8,2,14,1,114,174,0,0,0,122,16,78,111,32,109,
-    111,100,117,108,101,32,110,97,109,101,100,32,122,4,123,33,
-    114,125,99,2,0,0,0,0,0,0,0,8,0,0,0,12,
-    0,0,0,67,0,0,0,115,220,0,0,0,100,0,125,2,
-    124,0,106,0,100,1,131,1,100,2,25,0,125,3,124,3,
-    114,134,124,3,116,1,106,2,107,7,114,42,116,3,124,1,
-    124,3,131,2,1,0,124,0,116,1,106,2,107,6,114,62,
-    116,1,106,2,124,0,25,0,83,0,116,1,106,2,124,3,
-    25,0,125,4,121,10,124,4,106,4,125,2,87,0,110,50,
-    4,0,116,5,107,10,114,132,1,0,1,0,1,0,116,6,
-    100,3,23,0,106,7,124,0,124,3,131,2,125,5,116,8,
-    124,5,124,0,100,4,141,2,100,0,130,2,89,0,110,2,
-    88,0,116,9,124,0,124,2,131,2,125,6,124,6,100,0,
-    107,8,114,172,116,8,116,6,106,7,124,0,131,1,124,0,
-    100,4,141,2,130,1,110,8,116,10,124,6,131,1,125,7,
-    124,3,114,216,116,1,106,2,124,3,25,0,125,4,116,11,
-    124,4,124,0,106,0,100,1,131,1,100,5,25,0,124,7,
-    131,3,1,0,124,7,83,0,41,6,78,114,118,0,0,0,
-    114,19,0,0,0,122,23,59,32,123,33,114,125,32,105,115,
-    32,110,111,116,32,97,32,112,97,99,107,97,103,101,41,1,
-    114,15,0,0,0,233,2,0,0,0,41,12,114,119,0,0,
-    0,114,14,0,0,0,114,80,0,0,0,114,59,0,0,0,
-    114,128,0,0,0,114,91,0,0,0,218,8,95,69,82,82,
-    95,77,83,71,114,38,0,0,0,218,19,77,111,100,117,108,
-    101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,170,
-    0,0,0,114,141,0,0,0,114,5,0,0,0,41,8,114,
-    15,0,0,0,218,7,105,109,112,111,114,116,95,114,144,0,
-    0,0,114,120,0,0,0,90,13,112,97,114,101,110,116,95,
-    109,111,100,117,108,101,114,139,0,0,0,114,83,0,0,0,
-    114,84,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
-    11,0,0,0,218,23,95,102,105,110,100,95,97,110,100,95,
-    108,111,97,100,95,117,110,108,111,99,107,101,100,168,3,0,
-    0,115,42,0,0,0,0,1,4,1,14,1,4,1,10,1,
-    10,2,10,1,10,1,10,1,2,1,10,1,14,1,16,1,
-    20,1,10,1,8,1,20,2,8,1,4,2,10,1,22,1,
-    114,179,0,0,0,99,2,0,0,0,0,0,0,0,4,0,
-    0,0,11,0,0,0,67,0,0,0,115,94,0,0,0,116,
-    0,124,0,131,1,143,38,1,0,116,1,106,2,106,3,124,
-    0,116,4,131,2,125,2,124,2,116,4,107,8,114,42,116,
-    5,124,0,124,1,131,2,83,0,87,0,100,1,81,0,82,
-    0,88,0,124,2,100,1,107,8,114,82,100,2,106,6,124,
-    0,131,1,125,3,116,7,124,3,124,0,100,3,141,2,130,
-    1,116,8,124,0,131,1,1,0,124,2,83,0,41,4,122,
-    25,70,105,110,100,32,97,110,100,32,108,111,97,100,32,116,
-    104,101,32,109,111,100,117,108,101,46,78,122,40,105,109,112,
-    111,114,116,32,111,102,32,123,125,32,104,97,108,116,101,100,
-    59,32,78,111,110,101,32,105,110,32,115,121,115,46,109,111,
-    100,117,108,101,115,41,1,114,15,0,0,0,41,9,114,42,
-    0,0,0,114,14,0,0,0,114,80,0,0,0,114,30,0,
-    0,0,218,14,95,78,69,69,68,83,95,76,79,65,68,73,
-    78,71,114,179,0,0,0,114,38,0,0,0,114,177,0,0,
-    0,114,57,0,0,0,41,4,114,15,0,0,0,114,178,0,
-    0,0,114,84,0,0,0,114,68,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,218,14,95,102,105,
-    110,100,95,97,110,100,95,108,111,97,100,198,3,0,0,115,
-    20,0,0,0,0,2,10,1,14,1,8,1,20,2,8,1,
-    4,1,6,1,12,2,8,1,114,181,0,0,0,114,19,0,
-    0,0,99,3,0,0,0,0,0,0,0,3,0,0,0,4,
-    0,0,0,67,0,0,0,115,42,0,0,0,116,0,124,0,
-    124,1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,
-    116,1,124,0,124,1,124,2,131,3,125,0,116,2,124,0,
-    116,3,131,2,83,0,41,2,97,50,1,0,0,73,109,112,
-    111,114,116,32,97,110,100,32,114,101,116,117,114,110,32,116,
-    104,101,32,109,111,100,117,108,101,32,98,97,115,101,100,32,
-    111,110,32,105,116,115,32,110,97,109,101,44,32,116,104,101,
-    32,112,97,99,107,97,103,101,32,116,104,101,32,99,97,108,
-    108,32,105,115,10,32,32,32,32,98,101,105,110,103,32,109,
-    97,100,101,32,102,114,111,109,44,32,97,110,100,32,116,104,
-    101,32,108,101,118,101,108,32,97,100,106,117,115,116,109,101,
-    110,116,46,10,10,32,32,32,32,84,104,105,115,32,102,117,
-    110,99,116,105,111,110,32,114,101,112,114,101,115,101,110,116,
-    115,32,116,104,101,32,103,114,101,97,116,101,115,116,32,99,
-    111,109,109,111,110,32,100,101,110,111,109,105,110,97,116,111,
-    114,32,111,102,32,102,117,110,99,116,105,111,110,97,108,105,
-    116,121,10,32,32,32,32,98,101,116,119,101,101,110,32,105,
-    109,112,111,114,116,95,109,111,100,117,108,101,32,97,110,100,
-    32,95,95,105,109,112,111,114,116,95,95,46,32,84,104,105,
-    115,32,105,110,99,108,117,100,101,115,32,115,101,116,116,105,
-    110,103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,
-    102,10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,
-    32,100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,
-    19,0,0,0,41,4,114,174,0,0,0,114,163,0,0,0,
-    114,181,0,0,0,218,11,95,103,99,100,95,105,109,112,111,
-    114,116,41,3,114,15,0,0,0,114,161,0,0,0,114,162,
-    0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,
-    0,0,114,182,0,0,0,214,3,0,0,115,8,0,0,0,
-    0,9,12,1,8,1,12,1,114,182,0,0,0,99,3,0,
-    0,0,0,0,0,0,6,0,0,0,17,0,0,0,67,0,
-    0,0,115,164,0,0,0,116,0,124,0,100,1,131,2,114,
-    160,100,2,124,1,107,6,114,58,116,1,124,1,131,1,125,
-    1,124,1,106,2,100,2,131,1,1,0,116,0,124,0,100,
-    3,131,2,114,58,124,1,106,3,124,0,106,4,131,1,1,
-    0,120,100,124,1,68,0,93,92,125,3,116,0,124,0,124,
-    3,131,2,115,64,100,4,106,5,124,0,106,6,124,3,131,
-    2,125,4,121,14,116,7,124,2,124,4,131,2,1,0,87,
-    0,113,64,4,0,116,8,107,10,114,154,1,0,125,5,1,
-    0,122,20,124,5,106,9,124,4,107,2,114,136,119,64,130,
-    0,87,0,89,0,100,5,100,5,125,5,126,5,88,0,113,
-    64,88,0,113,64,87,0,124,0,83,0,41,6,122,238,70,
-    105,103,117,114,101,32,111,117,116,32,119,104,97,116,32,95,
-    95,105,109,112,111,114,116,95,95,32,115,104,111,117,108,100,
-    32,114,101,116,117,114,110,46,10,10,32,32,32,32,84,104,
-    101,32,105,109,112,111,114,116,95,32,112,97,114,97,109,101,
-    116,101,114,32,105,115,32,97,32,99,97,108,108,97,98,108,
-    101,32,119,104,105,99,104,32,116,97,107,101,115,32,116,104,
-    101,32,110,97,109,101,32,111,102,32,109,111,100,117,108,101,
-    32,116,111,10,32,32,32,32,105,109,112,111,114,116,46,32,
-    73,116,32,105,115,32,114,101,113,117,105,114,101,100,32,116,
-    111,32,100,101,99,111,117,112,108,101,32,116,104,101,32,102,
-    117,110,99,116,105,111,110,32,102,114,111,109,32,97,115,115,
-    117,109,105,110,103,32,105,109,112,111,114,116,108,105,98,39,
-    115,10,32,32,32,32,105,109,112,111,114,116,32,105,109,112,
-    108,101,109,101,110,116,97,116,105,111,110,32,105,115,32,100,
-    101,115,105,114,101,100,46,10,10,32,32,32,32,114,128,0,
-    0,0,250,1,42,218,7,95,95,97,108,108,95,95,122,5,
-    123,125,46,123,125,78,41,10,114,4,0,0,0,114,127,0,
-    0,0,218,6,114,101,109,111,118,101,218,6,101,120,116,101,
-    110,100,114,184,0,0,0,114,38,0,0,0,114,1,0,0,
-    0,114,59,0,0,0,114,177,0,0,0,114,15,0,0,0,
-    41,6,114,84,0,0,0,218,8,102,114,111,109,108,105,115,
-    116,114,178,0,0,0,218,1,120,90,9,102,114,111,109,95,
-    110,97,109,101,90,3,101,120,99,114,10,0,0,0,114,10,
-    0,0,0,114,11,0,0,0,218,16,95,104,97,110,100,108,
-    101,95,102,114,111,109,108,105,115,116,229,3,0,0,115,32,
-    0,0,0,0,10,10,1,8,1,8,1,10,1,10,1,12,
-    1,10,1,10,1,14,1,2,1,14,1,16,4,10,1,2,
-    1,24,1,114,189,0,0,0,99,1,0,0,0,0,0,0,
-    0,3,0,0,0,6,0,0,0,67,0,0,0,115,146,0,
-    0,0,124,0,106,0,100,1,131,1,125,1,124,0,106,0,
-    100,2,131,1,125,2,124,1,100,3,107,9,114,82,124,2,
-    100,3,107,9,114,78,124,1,124,2,106,1,107,3,114,78,
-    116,2,106,3,100,4,124,1,155,2,100,5,124,2,106,1,
-    155,2,100,6,157,5,116,4,100,7,100,8,141,3,1,0,
-    124,1,83,0,124,2,100,3,107,9,114,96,124,2,106,1,
-    83,0,116,2,106,3,100,9,116,4,100,7,100,8,141,3,
-    1,0,124,0,100,10,25,0,125,1,100,11,124,0,107,7,
-    114,142,124,1,106,5,100,12,131,1,100,13,25,0,125,1,
-    124,1,83,0,41,14,122,167,67,97,108,99,117,108,97,116,
-    101,32,119,104,97,116,32,95,95,112,97,99,107,97,103,101,
-    95,95,32,115,104,111,117,108,100,32,98,101,46,10,10,32,
-    32,32,32,95,95,112,97,99,107,97,103,101,95,95,32,105,
-    115,32,110,111,116,32,103,117,97,114,97,110,116,101,101,100,
-    32,116,111,32,98,101,32,100,101,102,105,110,101,100,32,111,
-    114,32,99,111,117,108,100,32,98,101,32,115,101,116,32,116,
-    111,32,78,111,110,101,10,32,32,32,32,116,111,32,114,101,
-    112,114,101,115,101,110,116,32,116,104,97,116,32,105,116,115,
-    32,112,114,111,112,101,114,32,118,97,108,117,101,32,105,115,
-    32,117,110,107,110,111,119,110,46,10,10,32,32,32,32,114,
-    131,0,0,0,114,90,0,0,0,78,122,32,95,95,112,97,
-    99,107,97,103,101,95,95,32,33,61,32,95,95,115,112,101,
-    99,95,95,46,112,97,114,101,110,116,32,40,122,4,32,33,
-    61,32,250,1,41,233,3,0,0,0,41,1,90,10,115,116,
-    97,99,107,108,101,118,101,108,122,89,99,97,110,39,116,32,
-    114,101,115,111,108,118,101,32,112,97,99,107,97,103,101,32,
-    102,114,111,109,32,95,95,115,112,101,99,95,95,32,111,114,
-    32,95,95,112,97,99,107,97,103,101,95,95,44,32,102,97,
-    108,108,105,110,103,32,98,97,99,107,32,111,110,32,95,95,
-    110,97,109,101,95,95,32,97,110,100,32,95,95,112,97,116,
-    104,95,95,114,1,0,0,0,114,128,0,0,0,114,118,0,
-    0,0,114,19,0,0,0,41,6,114,30,0,0,0,114,120,
-    0,0,0,114,167,0,0,0,114,168,0,0,0,114,169,0,
-    0,0,114,119,0,0,0,41,3,218,7,103,108,111,98,97,
-    108,115,114,161,0,0,0,114,83,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,218,17,95,99,97,
-    108,99,95,95,95,112,97,99,107,97,103,101,95,95,4,4,
-    0,0,115,30,0,0,0,0,7,10,1,10,1,8,1,18,
-    1,22,2,10,1,4,1,8,1,6,2,6,2,10,1,8,
-    1,8,1,14,1,114,193,0,0,0,99,5,0,0,0,0,
-    0,0,0,9,0,0,0,5,0,0,0,67,0,0,0,115,
-    166,0,0,0,124,4,100,1,107,2,114,18,116,0,124,0,
-    131,1,125,5,110,36,124,1,100,2,107,9,114,30,124,1,
-    110,2,105,0,125,6,116,1,124,6,131,1,125,7,116,0,
-    124,0,124,7,124,4,131,3,125,5,124,3,115,150,124,4,
-    100,1,107,2,114,84,116,0,124,0,106,2,100,3,131,1,
-    100,1,25,0,131,1,83,0,124,0,115,92,124,5,83,0,
-    116,3,124,0,131,1,116,3,124,0,106,2,100,3,131,1,
-    100,1,25,0,131,1,24,0,125,8,116,4,106,5,124,5,
-    106,6,100,2,116,3,124,5,106,6,131,1,124,8,24,0,
-    133,2,25,0,25,0,83,0,110,12,116,7,124,5,124,3,
-    116,0,131,3,83,0,100,2,83,0,41,4,97,215,1,0,
-    0,73,109,112,111,114,116,32,97,32,109,111,100,117,108,101,
-    46,10,10,32,32,32,32,84,104,101,32,39,103,108,111,98,
-    97,108,115,39,32,97,114,103,117,109,101,110,116,32,105,115,
-    32,117,115,101,100,32,116,111,32,105,110,102,101,114,32,119,
-    104,101,114,101,32,116,104,101,32,105,109,112,111,114,116,32,
-    105,115,32,111,99,99,117,114,114,105,110,103,32,102,114,111,
-    109,10,32,32,32,32,116,111,32,104,97,110,100,108,101,32,
-    114,101,108,97,116,105,118,101,32,105,109,112,111,114,116,115,
-    46,32,84,104,101,32,39,108,111,99,97,108,115,39,32,97,
-    114,103,117,109,101,110,116,32,105,115,32,105,103,110,111,114,
-    101,100,46,32,84,104,101,10,32,32,32,32,39,102,114,111,
-    109,108,105,115,116,39,32,97,114,103,117,109,101,110,116,32,
-    115,112,101,99,105,102,105,101,115,32,119,104,97,116,32,115,
-    104,111,117,108,100,32,101,120,105,115,116,32,97,115,32,97,
-    116,116,114,105,98,117,116,101,115,32,111,110,32,116,104,101,
-    32,109,111,100,117,108,101,10,32,32,32,32,98,101,105,110,
-    103,32,105,109,112,111,114,116,101,100,32,40,101,46,103,46,
-    32,96,96,102,114,111,109,32,109,111,100,117,108,101,32,105,
-    109,112,111,114,116,32,60,102,114,111,109,108,105,115,116,62,
-    96,96,41,46,32,32,84,104,101,32,39,108,101,118,101,108,
-    39,10,32,32,32,32,97,114,103,117,109,101,110,116,32,114,
-    101,112,114,101,115,101,110,116,115,32,116,104,101,32,112,97,
-    99,107,97,103,101,32,108,111,99,97,116,105,111,110,32,116,
-    111,32,105,109,112,111,114,116,32,102,114,111,109,32,105,110,
-    32,97,32,114,101,108,97,116,105,118,101,10,32,32,32,32,
-    105,109,112,111,114,116,32,40,101,46,103,46,32,96,96,102,
-    114,111,109,32,46,46,112,107,103,32,105,109,112,111,114,116,
-    32,109,111,100,96,96,32,119,111,117,108,100,32,104,97,118,
-    101,32,97,32,39,108,101,118,101,108,39,32,111,102,32,50,
-    41,46,10,10,32,32,32,32,114,19,0,0,0,78,114,118,
-    0,0,0,41,8,114,182,0,0,0,114,193,0,0,0,218,
-    9,112,97,114,116,105,116,105,111,110,114,159,0,0,0,114,
-    14,0,0,0,114,80,0,0,0,114,1,0,0,0,114,189,
-    0,0,0,41,9,114,15,0,0,0,114,192,0,0,0,218,
-    6,108,111,99,97,108,115,114,187,0,0,0,114,162,0,0,
-    0,114,84,0,0,0,90,8,103,108,111,98,97,108,115,95,
-    114,161,0,0,0,90,7,99,117,116,95,111,102,102,114,10,
-    0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,95,
-    95,105,109,112,111,114,116,95,95,31,4,0,0,115,26,0,
-    0,0,0,11,8,1,10,2,16,1,8,1,12,1,4,3,
-    8,1,18,1,4,1,4,4,26,3,32,2,114,196,0,0,
-    0,99,1,0,0,0,0,0,0,0,2,0,0,0,3,0,
-    0,0,67,0,0,0,115,38,0,0,0,116,0,106,1,124,
-    0,131,1,125,1,124,1,100,0,107,8,114,30,116,2,100,
-    1,124,0,23,0,131,1,130,1,116,3,124,1,131,1,83,
-    0,41,2,78,122,25,110,111,32,98,117,105,108,116,45,105,
-    110,32,109,111,100,117,108,101,32,110,97,109,101,100,32,41,
-    4,114,142,0,0,0,114,146,0,0,0,114,71,0,0,0,
-    114,141,0,0,0,41,2,114,15,0,0,0,114,83,0,0,
+    101,110,73,109,112,111,114,116,101,114,46,103,101,116,95,115,
+    111,117,114,99,101,99,2,0,0,0,0,0,0,0,2,0,
+    0,0,2,0,0,0,67,0,0,0,115,10,0,0,0,116,
+    0,106,1,124,1,131,1,83,0,41,1,122,46,82,101,116,
+    117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32,
+    102,114,111,122,101,110,32,109,111,100,117,108,101,32,105,115,
+    32,97,32,112,97,99,107,97,103,101,46,41,2,114,49,0,
+    0,0,90,17,105,115,95,102,114,111,122,101,110,95,112,97,
+    99,107,97,103,101,41,2,114,143,0,0,0,114,72,0,0,
     0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
-    218,18,95,98,117,105,108,116,105,110,95,102,114,111,109,95,
-    110,97,109,101,66,4,0,0,115,8,0,0,0,0,1,10,
-    1,8,1,12,1,114,197,0,0,0,99,2,0,0,0,0,
-    0,0,0,12,0,0,0,12,0,0,0,67,0,0,0,115,
-    244,0,0,0,124,1,97,0,124,0,97,1,116,2,116,1,
-    131,1,125,2,120,86,116,1,106,3,106,4,131,0,68,0,
-    93,72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,
-    114,28,124,3,116,1,106,6,107,6,114,62,116,7,125,5,
-    110,18,116,0,106,8,124,3,131,1,114,28,116,9,125,5,
-    110,2,113,28,116,10,124,4,124,5,131,2,125,6,116,11,
-    124,6,124,4,131,2,1,0,113,28,87,0,116,1,106,3,
-    116,12,25,0,125,7,120,54,100,5,68,0,93,46,125,8,
-    124,8,116,1,106,3,107,7,114,144,116,13,124,8,131,1,
-    125,9,110,10,116,1,106,3,124,8,25,0,125,9,116,14,
-    124,7,124,8,124,9,131,3,1,0,113,120,87,0,121,12,
-    116,13,100,2,131,1,125,10,87,0,110,24,4,0,116,15,
-    107,10,114,206,1,0,1,0,1,0,100,3,125,10,89,0,
-    110,2,88,0,116,14,124,7,100,2,124,10,131,3,1,0,
-    116,13,100,4,131,1,125,11,116,14,124,7,100,4,124,11,
-    131,3,1,0,100,3,83,0,41,6,122,250,83,101,116,117,
-    112,32,105,109,112,111,114,116,108,105,98,32,98,121,32,105,
-    109,112,111,114,116,105,110,103,32,110,101,101,100,101,100,32,
-    98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,
-    32,97,110,100,32,105,110,106,101,99,116,105,110,103,32,116,
-    104,101,109,10,32,32,32,32,105,110,116,111,32,116,104,101,
-    32,103,108,111,98,97,108,32,110,97,109,101,115,112,97,99,
-    101,46,10,10,32,32,32,32,65,115,32,115,121,115,32,105,
-    115,32,110,101,101,100,101,100,32,102,111,114,32,115,121,115,
-    46,109,111,100,117,108,101,115,32,97,99,99,101,115,115,32,
-    97,110,100,32,95,105,109,112,32,105,115,32,110,101,101,100,
-    101,100,32,116,111,32,108,111,97,100,32,98,117,105,108,116,
-    45,105,110,10,32,32,32,32,109,111,100,117,108,101,115,44,
-    32,116,104,111,115,101,32,116,119,111,32,109,111,100,117,108,
-    101,115,32,109,117,115,116,32,98,101,32,101,120,112,108,105,
-    99,105,116,108,121,32,112,97,115,115,101,100,32,105,110,46,
-    10,10,32,32,32,32,114,167,0,0,0,114,20,0,0,0,
-    78,114,56,0,0,0,41,1,114,167,0,0,0,41,16,114,
-    49,0,0,0,114,14,0,0,0,114,13,0,0,0,114,80,
-    0,0,0,218,5,105,116,101,109,115,114,171,0,0,0,114,
-    70,0,0,0,114,142,0,0,0,114,76,0,0,0,114,152,
-    0,0,0,114,129,0,0,0,114,134,0,0,0,114,1,0,
-    0,0,114,197,0,0,0,114,5,0,0,0,114,71,0,0,
-    0,41,12,218,10,115,121,115,95,109,111,100,117,108,101,218,
-    11,95,105,109,112,95,109,111,100,117,108,101,90,11,109,111,
-    100,117,108,101,95,116,121,112,101,114,15,0,0,0,114,84,
-    0,0,0,114,94,0,0,0,114,83,0,0,0,90,11,115,
-    101,108,102,95,109,111,100,117,108,101,90,12,98,117,105,108,
-    116,105,110,95,110,97,109,101,90,14,98,117,105,108,116,105,
-    110,95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,
-    95,109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,
-    95,109,111,100,117,108,101,114,10,0,0,0,114,10,0,0,
-    0,114,11,0,0,0,218,6,95,115,101,116,117,112,73,4,
-    0,0,115,50,0,0,0,0,9,4,1,4,3,8,1,20,
-    1,10,1,10,1,6,1,10,1,6,2,2,1,10,1,14,
-    3,10,1,10,1,10,1,10,2,10,1,16,3,2,1,12,
-    1,14,2,10,1,12,3,8,1,114,201,0,0,0,99,2,
-    0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,
-    0,0,0,115,66,0,0,0,116,0,124,0,124,1,131,2,
-    1,0,116,1,106,2,106,3,116,4,131,1,1,0,116,1,
-    106,2,106,3,116,5,131,1,1,0,100,1,100,2,108,6,
-    125,2,124,2,97,7,124,2,106,8,116,1,106,9,116,10,
-    25,0,131,1,1,0,100,2,83,0,41,3,122,50,73,110,
-    115,116,97,108,108,32,105,109,112,111,114,116,108,105,98,32,
-    97,115,32,116,104,101,32,105,109,112,108,101,109,101,110,116,
-    97,116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,
-    114,19,0,0,0,78,41,11,114,201,0,0,0,114,14,0,
-    0,0,114,166,0,0,0,114,110,0,0,0,114,142,0,0,
-    0,114,152,0,0,0,218,26,95,102,114,111,122,101,110,95,
-    105,109,112,111,114,116,108,105,98,95,101,120,116,101,114,110,
-    97,108,114,116,0,0,0,218,8,95,105,110,115,116,97,108,
-    108,114,80,0,0,0,114,1,0,0,0,41,3,114,199,0,
+    114,106,0,0,0,62,3,0,0,115,2,0,0,0,0,4,
+    122,25,70,114,111,122,101,110,73,109,112,111,114,116,101,114,
+    46,105,115,95,112,97,99,107,97,103,101,41,2,78,78,41,
+    1,78,41,16,114,1,0,0,0,114,0,0,0,0,114,2,
+    0,0,0,114,3,0,0,0,114,150,0,0,0,114,87,0,
+    0,0,114,151,0,0,0,114,146,0,0,0,114,147,0,0,
+    0,114,135,0,0,0,114,136,0,0,0,114,138,0,0,0,
+    114,78,0,0,0,114,148,0,0,0,114,149,0,0,0,114,
+    106,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,114,152,0,0,0,250,2,0,
+    0,115,30,0,0,0,8,7,4,2,12,9,2,1,12,6,
+    2,1,12,8,12,4,12,9,12,9,2,1,14,5,2,1,
+    14,5,2,1,114,152,0,0,0,99,0,0,0,0,0,0,
+    0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,32,
+    0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,
+    2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,
+    6,83,0,41,7,218,18,95,73,109,112,111,114,116,76,111,
+    99,107,67,111,110,116,101,120,116,122,36,67,111,110,116,101,
+    120,116,32,109,97,110,97,103,101,114,32,102,111,114,32,116,
+    104,101,32,105,109,112,111,114,116,32,108,111,99,107,46,99,
+    1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,
+    67,0,0,0,115,12,0,0,0,116,0,106,1,131,0,1,
+    0,100,1,83,0,41,2,122,24,65,99,113,117,105,114,101,
+    32,116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,
+    46,78,41,2,114,49,0,0,0,114,50,0,0,0,41,1,
+    114,26,0,0,0,114,10,0,0,0,114,10,0,0,0,114,
+    11,0,0,0,114,46,0,0,0,75,3,0,0,115,2,0,
+    0,0,0,2,122,28,95,73,109,112,111,114,116,76,111,99,
+    107,67,111,110,116,101,120,116,46,95,95,101,110,116,101,114,
+    95,95,99,4,0,0,0,0,0,0,0,4,0,0,0,1,
+    0,0,0,67,0,0,0,115,12,0,0,0,116,0,106,1,
+    131,0,1,0,100,1,83,0,41,2,122,60,82,101,108,101,
+    97,115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,
+    111,99,107,32,114,101,103,97,114,100,108,101,115,115,32,111,
+    102,32,97,110,121,32,114,97,105,115,101,100,32,101,120,99,
+    101,112,116,105,111,110,115,46,78,41,2,114,49,0,0,0,
+    114,52,0,0,0,41,4,114,26,0,0,0,90,8,101,120,
+    99,95,116,121,112,101,90,9,101,120,99,95,118,97,108,117,
+    101,90,13,101,120,99,95,116,114,97,99,101,98,97,99,107,
+    114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,
+    48,0,0,0,79,3,0,0,115,2,0,0,0,0,2,122,
+    27,95,73,109,112,111,114,116,76,111,99,107,67,111,110,116,
+    101,120,116,46,95,95,101,120,105,116,95,95,78,41,6,114,
+    1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,
+    0,0,0,114,46,0,0,0,114,48,0,0,0,114,10,0,
+    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+    0,114,157,0,0,0,71,3,0,0,115,6,0,0,0,8,
+    2,4,2,8,4,114,157,0,0,0,99,3,0,0,0,0,
+    0,0,0,5,0,0,0,4,0,0,0,67,0,0,0,115,
+    64,0,0,0,124,1,106,0,100,1,124,2,100,2,24,0,
+    131,2,125,3,116,1,124,3,131,1,124,2,107,0,114,36,
+    116,2,100,3,131,1,130,1,124,3,100,4,25,0,125,4,
+    124,0,114,60,100,5,106,3,124,4,124,0,131,2,83,0,
+    124,4,83,0,41,6,122,50,82,101,115,111,108,118,101,32,
+    97,32,114,101,108,97,116,105,118,101,32,109,111,100,117,108,
+    101,32,110,97,109,101,32,116,111,32,97,110,32,97,98,115,
+    111,108,117,116,101,32,111,110,101,46,114,118,0,0,0,114,
+    33,0,0,0,122,50,97,116,116,101,109,112,116,101,100,32,
+    114,101,108,97,116,105,118,101,32,105,109,112,111,114,116,32,
+    98,101,121,111,110,100,32,116,111,112,45,108,101,118,101,108,
+    32,112,97,99,107,97,103,101,114,19,0,0,0,122,5,123,
+    125,46,123,125,41,4,218,6,114,115,112,108,105,116,218,3,
+    108,101,110,218,10,86,97,108,117,101,69,114,114,111,114,114,
+    38,0,0,0,41,5,114,15,0,0,0,218,7,112,97,99,
+    107,97,103,101,218,5,108,101,118,101,108,90,4,98,105,116,
+    115,90,4,98,97,115,101,114,10,0,0,0,114,10,0,0,
+    0,114,11,0,0,0,218,13,95,114,101,115,111,108,118,101,
+    95,110,97,109,101,84,3,0,0,115,10,0,0,0,0,2,
+    16,1,12,1,8,1,8,1,114,163,0,0,0,99,3,0,
+    0,0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,
+    0,0,115,34,0,0,0,124,0,106,0,124,1,124,2,131,
+    2,125,3,124,3,100,0,107,8,114,24,100,0,83,0,116,
+    1,124,1,124,3,131,2,83,0,41,1,78,41,2,114,147,
+    0,0,0,114,79,0,0,0,41,4,218,6,102,105,110,100,
+    101,114,114,15,0,0,0,114,144,0,0,0,114,94,0,0,
+    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    218,17,95,102,105,110,100,95,115,112,101,99,95,108,101,103,
+    97,99,121,93,3,0,0,115,8,0,0,0,0,3,12,1,
+    8,1,4,1,114,165,0,0,0,99,3,0,0,0,0,0,
+    0,0,10,0,0,0,27,0,0,0,67,0,0,0,115,242,
+    0,0,0,116,0,106,1,125,3,124,3,100,1,107,8,114,
+    22,116,2,100,2,131,1,130,1,124,3,115,38,116,3,106,
+    4,100,3,116,5,131,2,1,0,124,0,116,0,106,6,107,
+    6,125,4,120,188,124,3,68,0,93,176,125,5,116,7,131,
+    0,143,72,1,0,121,10,124,5,106,8,125,6,87,0,110,
+    42,4,0,116,9,107,10,114,118,1,0,1,0,1,0,116,
+    10,124,5,124,0,124,1,131,3,125,7,124,7,100,1,107,
+    8,114,114,119,54,89,0,110,14,88,0,124,6,124,0,124,
+    1,124,2,131,3,125,7,87,0,100,1,81,0,82,0,88,
+    0,124,7,100,1,107,9,114,54,124,4,12,0,114,226,124,
+    0,116,0,106,6,107,6,114,226,116,0,106,6,124,0,25,
+    0,125,8,121,10,124,8,106,11,125,9,87,0,110,20,4,
+    0,116,9,107,10,114,206,1,0,1,0,1,0,124,7,83,
+    0,88,0,124,9,100,1,107,8,114,220,124,7,83,0,124,
+    9,83,0,113,54,124,7,83,0,113,54,87,0,100,1,83,
+    0,100,1,83,0,41,4,122,21,70,105,110,100,32,97,32,
+    109,111,100,117,108,101,39,115,32,115,112,101,99,46,78,122,
+    53,115,121,115,46,109,101,116,97,95,112,97,116,104,32,105,
+    115,32,78,111,110,101,44,32,80,121,116,104,111,110,32,105,
+    115,32,108,105,107,101,108,121,32,115,104,117,116,116,105,110,
+    103,32,100,111,119,110,122,22,115,121,115,46,109,101,116,97,
+    95,112,97,116,104,32,105,115,32,101,109,112,116,121,41,12,
+    114,14,0,0,0,218,9,109,101,116,97,95,112,97,116,104,
+    114,71,0,0,0,218,9,95,119,97,114,110,105,110,103,115,
+    218,4,119,97,114,110,218,13,73,109,112,111,114,116,87,97,
+    114,110,105,110,103,114,80,0,0,0,114,157,0,0,0,114,
+    146,0,0,0,114,91,0,0,0,114,165,0,0,0,114,90,
+    0,0,0,41,10,114,15,0,0,0,114,144,0,0,0,114,
+    145,0,0,0,114,166,0,0,0,90,9,105,115,95,114,101,
+    108,111,97,100,114,164,0,0,0,114,146,0,0,0,114,83,
+    0,0,0,114,84,0,0,0,114,90,0,0,0,114,10,0,
+    0,0,114,10,0,0,0,114,11,0,0,0,218,10,95,102,
+    105,110,100,95,115,112,101,99,102,3,0,0,115,54,0,0,
+    0,0,2,6,1,8,2,8,3,4,1,12,5,10,1,10,
+    1,8,1,2,1,10,1,14,1,12,1,8,1,8,2,22,
+    1,8,2,16,1,10,1,2,1,10,1,14,4,6,2,8,
+    1,4,2,6,2,8,2,114,170,0,0,0,99,3,0,0,
+    0,0,0,0,0,3,0,0,0,4,0,0,0,67,0,0,
+    0,115,110,0,0,0,116,0,124,0,116,1,131,2,115,28,
+    116,2,100,1,106,3,116,4,124,0,131,1,131,1,131,1,
+    130,1,124,2,100,2,107,0,114,44,116,5,100,3,131,1,
+    130,1,124,2,100,2,107,4,114,84,116,0,124,1,116,1,
+    131,2,115,72,116,2,100,4,131,1,130,1,110,12,124,1,
+    115,84,116,6,100,5,131,1,130,1,124,0,12,0,114,106,
+    124,2,100,2,107,2,114,106,116,5,100,6,131,1,130,1,
+    100,7,83,0,41,8,122,28,86,101,114,105,102,121,32,97,
+    114,103,117,109,101,110,116,115,32,97,114,101,32,34,115,97,
+    110,101,34,46,122,31,109,111,100,117,108,101,32,110,97,109,
+    101,32,109,117,115,116,32,98,101,32,115,116,114,44,32,110,
+    111,116,32,123,125,114,19,0,0,0,122,18,108,101,118,101,
+    108,32,109,117,115,116,32,98,101,32,62,61,32,48,122,31,
+    95,95,112,97,99,107,97,103,101,95,95,32,110,111,116,32,
+    115,101,116,32,116,111,32,97,32,115,116,114,105,110,103,122,
+    54,97,116,116,101,109,112,116,101,100,32,114,101,108,97,116,
+    105,118,101,32,105,109,112,111,114,116,32,119,105,116,104,32,
+    110,111,32,107,110,111,119,110,32,112,97,114,101,110,116,32,
+    112,97,99,107,97,103,101,122,17,69,109,112,116,121,32,109,
+    111,100,117,108,101,32,110,97,109,101,78,41,7,218,10,105,
+    115,105,110,115,116,97,110,99,101,218,3,115,116,114,218,9,
+    84,121,112,101,69,114,114,111,114,114,38,0,0,0,114,13,
+    0,0,0,114,160,0,0,0,114,71,0,0,0,41,3,114,
+    15,0,0,0,114,161,0,0,0,114,162,0,0,0,114,10,
+    0,0,0,114,10,0,0,0,114,11,0,0,0,218,13,95,
+    115,97,110,105,116,121,95,99,104,101,99,107,149,3,0,0,
+    115,22,0,0,0,0,2,10,1,18,1,8,1,8,1,8,
+    1,10,1,10,1,4,1,8,2,14,1,114,174,0,0,0,
+    122,16,78,111,32,109,111,100,117,108,101,32,110,97,109,101,
+    100,32,122,4,123,33,114,125,99,2,0,0,0,0,0,0,
+    0,8,0,0,0,12,0,0,0,67,0,0,0,115,220,0,
+    0,0,100,0,125,2,124,0,106,0,100,1,131,1,100,2,
+    25,0,125,3,124,3,114,134,124,3,116,1,106,2,107,7,
+    114,42,116,3,124,1,124,3,131,2,1,0,124,0,116,1,
+    106,2,107,6,114,62,116,1,106,2,124,0,25,0,83,0,
+    116,1,106,2,124,3,25,0,125,4,121,10,124,4,106,4,
+    125,2,87,0,110,50,4,0,116,5,107,10,114,132,1,0,
+    1,0,1,0,116,6,100,3,23,0,106,7,124,0,124,3,
+    131,2,125,5,116,8,124,5,124,0,100,4,141,2,100,0,
+    130,2,89,0,110,2,88,0,116,9,124,0,124,2,131,2,
+    125,6,124,6,100,0,107,8,114,172,116,8,116,6,106,7,
+    124,0,131,1,124,0,100,4,141,2,130,1,110,8,116,10,
+    124,6,131,1,125,7,124,3,114,216,116,1,106,2,124,3,
+    25,0,125,4,116,11,124,4,124,0,106,0,100,1,131,1,
+    100,5,25,0,124,7,131,3,1,0,124,7,83,0,41,6,
+    78,114,118,0,0,0,114,19,0,0,0,122,23,59,32,123,
+    33,114,125,32,105,115,32,110,111,116,32,97,32,112,97,99,
+    107,97,103,101,41,1,114,15,0,0,0,233,2,0,0,0,
+    41,12,114,119,0,0,0,114,14,0,0,0,114,80,0,0,
+    0,114,59,0,0,0,114,128,0,0,0,114,91,0,0,0,
+    218,8,95,69,82,82,95,77,83,71,114,38,0,0,0,218,
+    19,77,111,100,117,108,101,78,111,116,70,111,117,110,100,69,
+    114,114,111,114,114,170,0,0,0,114,141,0,0,0,114,5,
+    0,0,0,41,8,114,15,0,0,0,218,7,105,109,112,111,
+    114,116,95,114,144,0,0,0,114,120,0,0,0,90,13,112,
+    97,114,101,110,116,95,109,111,100,117,108,101,114,139,0,0,
+    0,114,83,0,0,0,114,84,0,0,0,114,10,0,0,0,
+    114,10,0,0,0,114,11,0,0,0,218,23,95,102,105,110,
+    100,95,97,110,100,95,108,111,97,100,95,117,110,108,111,99,
+    107,101,100,168,3,0,0,115,42,0,0,0,0,1,4,1,
+    14,1,4,1,10,1,10,2,10,1,10,1,10,1,2,1,
+    10,1,14,1,16,1,20,1,10,1,8,1,20,2,8,1,
+    4,2,10,1,22,1,114,179,0,0,0,99,2,0,0,0,
+    0,0,0,0,4,0,0,0,11,0,0,0,67,0,0,0,
+    115,94,0,0,0,116,0,124,0,131,1,143,38,1,0,116,
+    1,106,2,106,3,124,0,116,4,131,2,125,2,124,2,116,
+    4,107,8,114,42,116,5,124,0,124,1,131,2,83,0,87,
+    0,100,1,81,0,82,0,88,0,124,2,100,1,107,8,114,
+    82,100,2,106,6,124,0,131,1,125,3,116,7,124,3,124,
+    0,100,3,141,2,130,1,116,8,124,0,131,1,1,0,124,
+    2,83,0,41,4,122,25,70,105,110,100,32,97,110,100,32,
+    108,111,97,100,32,116,104,101,32,109,111,100,117,108,101,46,
+    78,122,40,105,109,112,111,114,116,32,111,102,32,123,125,32,
+    104,97,108,116,101,100,59,32,78,111,110,101,32,105,110,32,
+    115,121,115,46,109,111,100,117,108,101,115,41,1,114,15,0,
+    0,0,41,9,114,42,0,0,0,114,14,0,0,0,114,80,
+    0,0,0,114,30,0,0,0,218,14,95,78,69,69,68,83,
+    95,76,79,65,68,73,78,71,114,179,0,0,0,114,38,0,
+    0,0,114,177,0,0,0,114,57,0,0,0,41,4,114,15,
+    0,0,0,114,178,0,0,0,114,84,0,0,0,114,68,0,
+    0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,
+    0,218,14,95,102,105,110,100,95,97,110,100,95,108,111,97,
+    100,198,3,0,0,115,20,0,0,0,0,2,10,1,14,1,
+    8,1,20,2,8,1,4,1,6,1,12,2,8,1,114,181,
+    0,0,0,114,19,0,0,0,99,3,0,0,0,0,0,0,
+    0,3,0,0,0,4,0,0,0,67,0,0,0,115,42,0,
+    0,0,116,0,124,0,124,1,124,2,131,3,1,0,124,2,
+    100,1,107,4,114,32,116,1,124,0,124,1,124,2,131,3,
+    125,0,116,2,124,0,116,3,131,2,83,0,41,2,97,50,
+    1,0,0,73,109,112,111,114,116,32,97,110,100,32,114,101,
+    116,117,114,110,32,116,104,101,32,109,111,100,117,108,101,32,
+    98,97,115,101,100,32,111,110,32,105,116,115,32,110,97,109,
+    101,44,32,116,104,101,32,112,97,99,107,97,103,101,32,116,
+    104,101,32,99,97,108,108,32,105,115,10,32,32,32,32,98,
+    101,105,110,103,32,109,97,100,101,32,102,114,111,109,44,32,
+    97,110,100,32,116,104,101,32,108,101,118,101,108,32,97,100,
+    106,117,115,116,109,101,110,116,46,10,10,32,32,32,32,84,
+    104,105,115,32,102,117,110,99,116,105,111,110,32,114,101,112,
+    114,101,115,101,110,116,115,32,116,104,101,32,103,114,101,97,
+    116,101,115,116,32,99,111,109,109,111,110,32,100,101,110,111,
+    109,105,110,97,116,111,114,32,111,102,32,102,117,110,99,116,
+    105,111,110,97,108,105,116,121,10,32,32,32,32,98,101,116,
+    119,101,101,110,32,105,109,112,111,114,116,95,109,111,100,117,
+    108,101,32,97,110,100,32,95,95,105,109,112,111,114,116,95,
+    95,46,32,84,104,105,115,32,105,110,99,108,117,100,101,115,
+    32,115,101,116,116,105,110,103,32,95,95,112,97,99,107,97,
+    103,101,95,95,32,105,102,10,32,32,32,32,116,104,101,32,
+    108,111,97,100,101,114,32,100,105,100,32,110,111,116,46,10,
+    10,32,32,32,32,114,19,0,0,0,41,4,114,174,0,0,
+    0,114,163,0,0,0,114,181,0,0,0,218,11,95,103,99,
+    100,95,105,109,112,111,114,116,41,3,114,15,0,0,0,114,
+    161,0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,114,182,0,0,0,214,3,0,
+    0,115,8,0,0,0,0,9,12,1,8,1,12,1,114,182,
+    0,0,0,41,1,218,9,114,101,99,117,114,115,105,118,101,
+    99,3,0,0,0,1,0,0,0,8,0,0,0,17,0,0,
+    0,67,0,0,0,115,236,0,0,0,116,0,124,0,100,1,
+    131,2,114,232,120,220,124,1,68,0,93,212,125,4,116,1,
+    124,4,116,2,131,2,115,78,124,3,114,46,124,0,106,3,
+    100,2,23,0,125,5,110,4,100,3,125,5,116,4,100,4,
+    124,5,155,0,100,5,116,5,124,4,131,1,106,3,155,0,
+    157,4,131,1,130,1,113,16,124,4,100,6,107,2,114,122,
+    124,3,12,0,114,228,116,0,124,0,100,7,131,2,114,228,
+    116,6,124,0,124,0,106,7,124,2,100,8,100,9,141,4,
+    1,0,113,16,116,0,124,0,124,4,131,2,115,16,100,10,
+    106,8,124,0,106,3,124,4,131,2,125,6,121,14,116,9,
+    124,2,124,6,131,2,1,0,87,0,113,16,4,0,116,10,
+    107,10,114,226,1,0,125,7,1,0,122,38,124,7,106,11,
+    124,6,107,2,114,208,116,12,106,13,106,14,124,6,116,15,
+    131,2,100,11,107,9,114,208,119,16,130,0,87,0,89,0,
+    100,11,100,11,125,7,126,7,88,0,113,16,88,0,113,16,
+    87,0,124,0,83,0,41,12,122,238,70,105,103,117,114,101,
+    32,111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,
+    114,116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,
+    114,110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,
+    111,114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,
+    115,32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,
+    99,104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,
+    101,32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,
+    32,32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,
+    32,114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,
+    111,117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,
+    111,110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,
+    32,105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,
+    32,105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,
+    116,97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,
+    100,46,10,10,32,32,32,32,114,128,0,0,0,122,8,46,
+    95,95,97,108,108,95,95,122,13,96,96,102,114,111,109,32,
+    108,105,115,116,39,39,122,8,73,116,101,109,32,105,110,32,
+    122,18,32,109,117,115,116,32,98,101,32,115,116,114,44,32,
+    110,111,116,32,250,1,42,218,7,95,95,97,108,108,95,95,
+    84,41,1,114,183,0,0,0,122,5,123,125,46,123,125,78,
+    41,16,114,4,0,0,0,114,171,0,0,0,114,172,0,0,
+    0,114,1,0,0,0,114,173,0,0,0,114,13,0,0,0,
+    218,16,95,104,97,110,100,108,101,95,102,114,111,109,108,105,
+    115,116,114,185,0,0,0,114,38,0,0,0,114,59,0,0,
+    0,114,177,0,0,0,114,15,0,0,0,114,14,0,0,0,
+    114,80,0,0,0,114,30,0,0,0,114,180,0,0,0,41,
+    8,114,84,0,0,0,218,8,102,114,111,109,108,105,115,116,
+    114,178,0,0,0,114,183,0,0,0,218,1,120,90,5,119,
+    104,101,114,101,90,9,102,114,111,109,95,110,97,109,101,90,
+    3,101,120,99,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,186,0,0,0,229,3,0,0,115,42,0,0,
+    0,0,10,10,1,10,1,10,1,4,1,12,2,4,1,28,
+    2,8,1,16,1,10,1,10,1,10,1,14,1,2,1,14,
+    1,16,4,10,1,18,1,2,1,24,1,114,186,0,0,0,
+    99,1,0,0,0,0,0,0,0,3,0,0,0,6,0,0,
+    0,67,0,0,0,115,146,0,0,0,124,0,106,0,100,1,
+    131,1,125,1,124,0,106,0,100,2,131,1,125,2,124,1,
+    100,3,107,9,114,82,124,2,100,3,107,9,114,78,124,1,
+    124,2,106,1,107,3,114,78,116,2,106,3,100,4,124,1,
+    155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,4,
+    100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,3,
+    107,9,114,96,124,2,106,1,83,0,116,2,106,3,100,9,
+    116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,0,
+    125,1,100,11,124,0,107,7,114,142,124,1,106,5,100,12,
+    131,1,100,13,25,0,125,1,124,1,83,0,41,14,122,167,
+    67,97,108,99,117,108,97,116,101,32,119,104,97,116,32,95,
+    95,112,97,99,107,97,103,101,95,95,32,115,104,111,117,108,
+    100,32,98,101,46,10,10,32,32,32,32,95,95,112,97,99,
+    107,97,103,101,95,95,32,105,115,32,110,111,116,32,103,117,
+    97,114,97,110,116,101,101,100,32,116,111,32,98,101,32,100,
+    101,102,105,110,101,100,32,111,114,32,99,111,117,108,100,32,
+    98,101,32,115,101,116,32,116,111,32,78,111,110,101,10,32,
+    32,32,32,116,111,32,114,101,112,114,101,115,101,110,116,32,
+    116,104,97,116,32,105,116,115,32,112,114,111,112,101,114,32,
+    118,97,108,117,101,32,105,115,32,117,110,107,110,111,119,110,
+    46,10,10,32,32,32,32,114,131,0,0,0,114,90,0,0,
+    0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,32,
+    33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,101,
+    110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,0,
+    0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,108,
+    122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,32,
+    112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,115,
+    112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,97,
+    103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,97,
+    99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,97,
+    110,100,32,95,95,112,97,116,104,95,95,114,1,0,0,0,
+    114,128,0,0,0,114,118,0,0,0,114,19,0,0,0,41,
+    6,114,30,0,0,0,114,120,0,0,0,114,167,0,0,0,
+    114,168,0,0,0,114,169,0,0,0,114,119,0,0,0,41,
+    3,218,7,103,108,111,98,97,108,115,114,161,0,0,0,114,
+    83,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99,
+    107,97,103,101,95,95,11,4,0,0,115,30,0,0,0,0,
+    7,10,1,10,1,8,1,18,1,22,2,10,1,4,1,8,
+    1,6,2,6,2,10,1,8,1,8,1,14,1,114,192,0,
+    0,0,99,5,0,0,0,0,0,0,0,9,0,0,0,5,
+    0,0,0,67,0,0,0,115,166,0,0,0,124,4,100,1,
+    107,2,114,18,116,0,124,0,131,1,125,5,110,36,124,1,
+    100,2,107,9,114,30,124,1,110,2,105,0,125,6,116,1,
+    124,6,131,1,125,7,116,0,124,0,124,7,124,4,131,3,
+    125,5,124,3,115,150,124,4,100,1,107,2,114,84,116,0,
+    124,0,106,2,100,3,131,1,100,1,25,0,131,1,83,0,
+    124,0,115,92,124,5,83,0,116,3,124,0,131,1,116,3,
+    124,0,106,2,100,3,131,1,100,1,25,0,131,1,24,0,
+    125,8,116,4,106,5,124,5,106,6,100,2,116,3,124,5,
+    106,6,131,1,124,8,24,0,133,2,25,0,25,0,83,0,
+    110,12,116,7,124,5,124,3,116,0,131,3,83,0,100,2,
+    83,0,41,4,97,215,1,0,0,73,109,112,111,114,116,32,
+    97,32,109,111,100,117,108,101,46,10,10,32,32,32,32,84,
+    104,101,32,39,103,108,111,98,97,108,115,39,32,97,114,103,
+    117,109,101,110,116,32,105,115,32,117,115,101,100,32,116,111,
+    32,105,110,102,101,114,32,119,104,101,114,101,32,116,104,101,
+    32,105,109,112,111,114,116,32,105,115,32,111,99,99,117,114,
+    114,105,110,103,32,102,114,111,109,10,32,32,32,32,116,111,
+    32,104,97,110,100,108,101,32,114,101,108,97,116,105,118,101,
+    32,105,109,112,111,114,116,115,46,32,84,104,101,32,39,108,
+    111,99,97,108,115,39,32,97,114,103,117,109,101,110,116,32,
+    105,115,32,105,103,110,111,114,101,100,46,32,84,104,101,10,
+    32,32,32,32,39,102,114,111,109,108,105,115,116,39,32,97,
+    114,103,117,109,101,110,116,32,115,112,101,99,105,102,105,101,
+    115,32,119,104,97,116,32,115,104,111,117,108,100,32,101,120,
+    105,115,116,32,97,115,32,97,116,116,114,105,98,117,116,101,
+    115,32,111,110,32,116,104,101,32,109,111,100,117,108,101,10,
+    32,32,32,32,98,101,105,110,103,32,105,109,112,111,114,116,
+    101,100,32,40,101,46,103,46,32,96,96,102,114,111,109,32,
+    109,111,100,117,108,101,32,105,109,112,111,114,116,32,60,102,
+    114,111,109,108,105,115,116,62,96,96,41,46,32,32,84,104,
+    101,32,39,108,101,118,101,108,39,10,32,32,32,32,97,114,
+    103,117,109,101,110,116,32,114,101,112,114,101,115,101,110,116,
+    115,32,116,104,101,32,112,97,99,107,97,103,101,32,108,111,
+    99,97,116,105,111,110,32,116,111,32,105,109,112,111,114,116,
+    32,102,114,111,109,32,105,110,32,97,32,114,101,108,97,116,
+    105,118,101,10,32,32,32,32,105,109,112,111,114,116,32,40,
+    101,46,103,46,32,96,96,102,114,111,109,32,46,46,112,107,
+    103,32,105,109,112,111,114,116,32,109,111,100,96,96,32,119,
+    111,117,108,100,32,104,97,118,101,32,97,32,39,108,101,118,
+    101,108,39,32,111,102,32,50,41,46,10,10,32,32,32,32,
+    114,19,0,0,0,78,114,118,0,0,0,41,8,114,182,0,
+    0,0,114,192,0,0,0,218,9,112,97,114,116,105,116,105,
+    111,110,114,159,0,0,0,114,14,0,0,0,114,80,0,0,
+    0,114,1,0,0,0,114,186,0,0,0,41,9,114,15,0,
+    0,0,114,191,0,0,0,218,6,108,111,99,97,108,115,114,
+    187,0,0,0,114,162,0,0,0,114,84,0,0,0,90,8,
+    103,108,111,98,97,108,115,95,114,161,0,0,0,90,7,99,
+    117,116,95,111,102,102,114,10,0,0,0,114,10,0,0,0,
+    114,11,0,0,0,218,10,95,95,105,109,112,111,114,116,95,
+    95,38,4,0,0,115,26,0,0,0,0,11,8,1,10,2,
+    16,1,8,1,12,1,4,3,8,1,18,1,4,1,4,4,
+    26,3,32,2,114,195,0,0,0,99,1,0,0,0,0,0,
+    0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,38,
+    0,0,0,116,0,106,1,124,0,131,1,125,1,124,1,100,
+    0,107,8,114,30,116,2,100,1,124,0,23,0,131,1,130,
+    1,116,3,124,1,131,1,83,0,41,2,78,122,25,110,111,
+    32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,
+    32,110,97,109,101,100,32,41,4,114,142,0,0,0,114,146,
+    0,0,0,114,71,0,0,0,114,141,0,0,0,41,2,114,
+    15,0,0,0,114,83,0,0,0,114,10,0,0,0,114,10,
+    0,0,0,114,11,0,0,0,218,18,95,98,117,105,108,116,
+    105,110,95,102,114,111,109,95,110,97,109,101,73,4,0,0,
+    115,8,0,0,0,0,1,10,1,8,1,12,1,114,196,0,
+    0,0,99,2,0,0,0,0,0,0,0,12,0,0,0,12,
+    0,0,0,67,0,0,0,115,244,0,0,0,124,1,97,0,
+    124,0,97,1,116,2,116,1,131,1,125,2,120,86,116,1,
+    106,3,106,4,131,0,68,0,93,72,92,2,125,3,125,4,
+    116,5,124,4,124,2,131,2,114,28,124,3,116,1,106,6,
+    107,6,114,62,116,7,125,5,110,18,116,0,106,8,124,3,
+    131,1,114,28,116,9,125,5,110,2,113,28,116,10,124,4,
+    124,5,131,2,125,6,116,11,124,6,124,4,131,2,1,0,
+    113,28,87,0,116,1,106,3,116,12,25,0,125,7,120,54,
+    100,5,68,0,93,46,125,8,124,8,116,1,106,3,107,7,
+    114,144,116,13,124,8,131,1,125,9,110,10,116,1,106,3,
+    124,8,25,0,125,9,116,14,124,7,124,8,124,9,131,3,
+    1,0,113,120,87,0,121,12,116,13,100,2,131,1,125,10,
+    87,0,110,24,4,0,116,15,107,10,114,206,1,0,1,0,
+    1,0,100,3,125,10,89,0,110,2,88,0,116,14,124,7,
+    100,2,124,10,131,3,1,0,116,13,100,4,131,1,125,11,
+    116,14,124,7,100,4,124,11,131,3,1,0,100,3,83,0,
+    41,6,122,250,83,101,116,117,112,32,105,109,112,111,114,116,
+    108,105,98,32,98,121,32,105,109,112,111,114,116,105,110,103,
+    32,110,101,101,100,101,100,32,98,117,105,108,116,45,105,110,
+    32,109,111,100,117,108,101,115,32,97,110,100,32,105,110,106,
+    101,99,116,105,110,103,32,116,104,101,109,10,32,32,32,32,
+    105,110,116,111,32,116,104,101,32,103,108,111,98,97,108,32,
+    110,97,109,101,115,112,97,99,101,46,10,10,32,32,32,32,
+    65,115,32,115,121,115,32,105,115,32,110,101,101,100,101,100,
+    32,102,111,114,32,115,121,115,46,109,111,100,117,108,101,115,
+    32,97,99,99,101,115,115,32,97,110,100,32,95,105,109,112,
+    32,105,115,32,110,101,101,100,101,100,32,116,111,32,108,111,
+    97,100,32,98,117,105,108,116,45,105,110,10,32,32,32,32,
+    109,111,100,117,108,101,115,44,32,116,104,111,115,101,32,116,
+    119,111,32,109,111,100,117,108,101,115,32,109,117,115,116,32,
+    98,101,32,101,120,112,108,105,99,105,116,108,121,32,112,97,
+    115,115,101,100,32,105,110,46,10,10,32,32,32,32,114,167,
+    0,0,0,114,20,0,0,0,78,114,56,0,0,0,41,1,
+    114,167,0,0,0,41,16,114,49,0,0,0,114,14,0,0,
+    0,114,13,0,0,0,114,80,0,0,0,218,5,105,116,101,
+    109,115,114,171,0,0,0,114,70,0,0,0,114,142,0,0,
+    0,114,76,0,0,0,114,152,0,0,0,114,129,0,0,0,
+    114,134,0,0,0,114,1,0,0,0,114,196,0,0,0,114,
+    5,0,0,0,114,71,0,0,0,41,12,218,10,115,121,115,
+    95,109,111,100,117,108,101,218,11,95,105,109,112,95,109,111,
+    100,117,108,101,90,11,109,111,100,117,108,101,95,116,121,112,
+    101,114,15,0,0,0,114,84,0,0,0,114,94,0,0,0,
+    114,83,0,0,0,90,11,115,101,108,102,95,109,111,100,117,
+    108,101,90,12,98,117,105,108,116,105,110,95,110,97,109,101,
+    90,14,98,117,105,108,116,105,110,95,109,111,100,117,108,101,
+    90,13,116,104,114,101,97,100,95,109,111,100,117,108,101,90,
+    14,119,101,97,107,114,101,102,95,109,111,100,117,108,101,114,
+    10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,6,
+    95,115,101,116,117,112,80,4,0,0,115,50,0,0,0,0,
+    9,4,1,4,3,8,1,20,1,10,1,10,1,6,1,10,
+    1,6,2,2,1,10,1,14,3,10,1,10,1,10,1,10,
+    2,10,1,16,3,2,1,12,1,14,2,10,1,12,3,8,
+    1,114,200,0,0,0,99,2,0,0,0,0,0,0,0,3,
+    0,0,0,3,0,0,0,67,0,0,0,115,66,0,0,0,
+    116,0,124,0,124,1,131,2,1,0,116,1,106,2,106,3,
+    116,4,131,1,1,0,116,1,106,2,106,3,116,5,131,1,
+    1,0,100,1,100,2,108,6,125,2,124,2,97,7,124,2,
+    106,8,116,1,106,9,116,10,25,0,131,1,1,0,100,2,
+    83,0,41,3,122,50,73,110,115,116,97,108,108,32,105,109,
+    112,111,114,116,108,105,98,32,97,115,32,116,104,101,32,105,
+    109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,
+    32,105,109,112,111,114,116,46,114,19,0,0,0,78,41,11,
+    114,200,0,0,0,114,14,0,0,0,114,166,0,0,0,114,
+    110,0,0,0,114,142,0,0,0,114,152,0,0,0,218,26,
+    95,102,114,111,122,101,110,95,105,109,112,111,114,116,108,105,
+    98,95,101,120,116,101,114,110,97,108,114,116,0,0,0,218,
+    8,95,105,110,115,116,97,108,108,114,80,0,0,0,114,1,
+    0,0,0,41,3,114,198,0,0,0,114,199,0,0,0,114,
+    201,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,
+    0,0,0,114,202,0,0,0,127,4,0,0,115,12,0,0,
+    0,0,2,10,2,12,1,12,3,8,1,4,1,114,202,0,
+    0,0,41,2,78,78,41,1,78,41,2,78,114,19,0,0,
+    0,41,50,114,3,0,0,0,114,116,0,0,0,114,12,0,
+    0,0,114,16,0,0,0,114,51,0,0,0,114,29,0,0,
+    0,114,36,0,0,0,114,17,0,0,0,114,18,0,0,0,
+    114,41,0,0,0,114,42,0,0,0,114,45,0,0,0,114,
+    57,0,0,0,114,59,0,0,0,114,69,0,0,0,114,75,
+    0,0,0,114,78,0,0,0,114,85,0,0,0,114,96,0,
+    0,0,114,97,0,0,0,114,103,0,0,0,114,79,0,0,
+    0,114,129,0,0,0,114,134,0,0,0,114,137,0,0,0,
+    114,92,0,0,0,114,81,0,0,0,114,140,0,0,0,114,
+    141,0,0,0,114,82,0,0,0,114,142,0,0,0,114,152,
+    0,0,0,114,157,0,0,0,114,163,0,0,0,114,165,0,
+    0,0,114,170,0,0,0,114,174,0,0,0,90,15,95,69,
+    82,82,95,77,83,71,95,80,82,69,70,73,88,114,176,0,
+    0,0,114,179,0,0,0,218,6,111,98,106,101,99,116,114,
+    180,0,0,0,114,181,0,0,0,114,182,0,0,0,114,186,
+    0,0,0,114,192,0,0,0,114,195,0,0,0,114,196,0,
     0,0,114,200,0,0,0,114,202,0,0,0,114,10,0,0,
-    0,114,10,0,0,0,114,11,0,0,0,114,203,0,0,0,
-    120,4,0,0,115,12,0,0,0,0,2,10,2,12,1,12,
-    3,8,1,4,1,114,203,0,0,0,41,2,78,78,41,1,
-    78,41,2,78,114,19,0,0,0,41,50,114,3,0,0,0,
-    114,116,0,0,0,114,12,0,0,0,114,16,0,0,0,114,
-    51,0,0,0,114,29,0,0,0,114,36,0,0,0,114,17,
-    0,0,0,114,18,0,0,0,114,41,0,0,0,114,42,0,
-    0,0,114,45,0,0,0,114,57,0,0,0,114,59,0,0,
-    0,114,69,0,0,0,114,75,0,0,0,114,78,0,0,0,
-    114,85,0,0,0,114,96,0,0,0,114,97,0,0,0,114,
-    103,0,0,0,114,79,0,0,0,114,129,0,0,0,114,134,
-    0,0,0,114,137,0,0,0,114,92,0,0,0,114,81,0,
-    0,0,114,140,0,0,0,114,141,0,0,0,114,82,0,0,
-    0,114,142,0,0,0,114,152,0,0,0,114,157,0,0,0,
-    114,163,0,0,0,114,165,0,0,0,114,170,0,0,0,114,
-    174,0,0,0,90,15,95,69,82,82,95,77,83,71,95,80,
-    82,69,70,73,88,114,176,0,0,0,114,179,0,0,0,218,
-    6,111,98,106,101,99,116,114,180,0,0,0,114,181,0,0,
-    0,114,182,0,0,0,114,189,0,0,0,114,193,0,0,0,
-    114,196,0,0,0,114,197,0,0,0,114,201,0,0,0,114,
-    203,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,
-    0,0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,
-    101,62,8,0,0,0,115,94,0,0,0,4,17,4,2,8,
-    8,8,8,4,2,4,3,16,4,14,68,14,21,14,16,8,
-    37,8,17,8,11,14,8,8,11,8,12,8,16,8,36,14,
-    27,14,101,16,26,10,45,14,60,8,17,8,17,8,24,8,
-    29,8,23,8,15,14,73,14,77,14,13,8,9,8,9,10,
-    47,8,16,4,1,8,2,8,27,6,3,8,16,10,15,8,
-    31,8,27,18,35,8,7,8,47,
+    0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,
+    218,8,60,109,111,100,117,108,101,62,8,0,0,0,115,94,
+    0,0,0,4,17,4,2,8,8,8,8,4,2,4,3,16,
+    4,14,68,14,21,14,16,8,37,8,17,8,11,14,8,8,
+    11,8,12,8,16,8,36,14,27,14,101,16,26,10,45,14,
+    60,8,17,8,17,8,24,8,29,8,23,8,15,14,73,14,
+    77,14,13,8,9,8,9,10,47,8,16,4,1,8,2,8,
+    27,6,3,8,16,10,15,14,38,8,27,18,35,8,7,8,
+    47,
 };
index 22ca49c75629edc783844909655115b723466231..91a57c293b09b6aa287836d377e1f96f76f0ff66 100644 (file)
@@ -32,6 +32,9 @@
 #define TYPE_STOPITER           'S'
 #define TYPE_ELLIPSIS           '.'
 #define TYPE_INT                'i'
+/* TYPE_INT64 is not generated anymore.
+   Supported for backward compatibility only. */
+#define TYPE_INT64              'I'
 #define TYPE_FLOAT              'f'
 #define TYPE_BINARY_FLOAT       'g'
 #define TYPE_COMPLEX            'x'
@@ -777,6 +780,19 @@ r_long(RFILE *p)
     return x;
 }
 
+/* r_long64 deals with the TYPE_INT64 code. */
+static PyObject *
+r_long64(RFILE *p)
+{
+    const unsigned char *buffer = (const unsigned char *) r_string(8, p);
+    if (buffer == NULL) {
+        return NULL;
+    }
+    return _PyLong_FromByteArray(buffer, 8,
+                                 1 /* little endian */,
+                                 1 /* signed */);
+}
+
 static PyObject *
 r_PyLong(RFILE *p)
 {
@@ -976,6 +992,11 @@ r_object(RFILE *p)
         R_REF(retval);
         break;
 
+    case TYPE_INT64:
+        retval = r_long64(p);
+        R_REF(retval);
+        break;
+
     case TYPE_LONG:
         retval = r_PyLong(p);
         R_REF(retval);
index 65f9b7ea05dd79c71538dacaa6d024b6af8205e7..c0e088055a60fc0dd95a0c9a3a64397ffad4d762 100644 (file)
@@ -865,6 +865,8 @@ PyGILState_Ensure(void)
 {
     int current;
     PyThreadState *tcur;
+    int need_init_threads = 0;
+
     /* Note that we do not auto-init Python here - apart from
        potential races with 2 threads auto-initializing, pep-311
        spells out other issues.  Embedders are expected to have
@@ -873,10 +875,7 @@ PyGILState_Ensure(void)
     assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
     tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
     if (tcur == NULL) {
-        /* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
-           called from a new thread for the first time, we need the create the
-           GIL. */
-        PyEval_InitThreads();
+        need_init_threads = 1;
 
         /* Create a new thread state for this thread */
         tcur = PyThreadState_New(autoInterpreterState);
@@ -887,16 +886,28 @@ PyGILState_Ensure(void)
         tcur->gilstate_counter = 0;
         current = 0; /* new thread state is never current */
     }
-    else
+    else {
         current = PyThreadState_IsCurrent(tcur);
-    if (current == 0)
+    }
+
+    if (current == 0) {
         PyEval_RestoreThread(tcur);
+    }
+
     /* Update our counter in the thread-state - no need for locks:
        - tcur will remain valid as we hold the GIL.
        - the counter is safe as we are the only thread "allowed"
          to modify this value
     */
     ++tcur->gilstate_counter;
+
+    if (need_init_threads) {
+        /* At startup, Python has no concrete GIL. If PyGILState_Ensure() is
+           called from a new thread for the first time, we need the create the
+           GIL. */
+        PyEval_InitThreads();
+    }
+
     return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
 }
 
index 8befa546a92b1a65d41fc09f367351ebaf255f71..e644e2a6d5710dcc9a93d192ddcb7a39820c4b5d 100644 (file)
@@ -61,6 +61,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
                               PyCompilerFlags *);
 static void err_input(perrdetail *);
 static void err_free(perrdetail *);
+static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);
 
 /* Parse input from a file and execute it */
 
@@ -86,6 +87,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
     PyObject *filename, *v;
     int ret, err;
     PyCompilerFlags local_flags;
+    int nomem_count = 0;
 
     filename = PyUnicode_DecodeFSDefault(filename_str);
     if (filename == NULL) {
@@ -107,19 +109,29 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
         _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... "));
         Py_XDECREF(v);
     }
-    err = -1;
-    for (;;) {
-        ret = PyRun_InteractiveOneObject(fp, filename, flags);
-        _PY_DEBUG_PRINT_TOTAL_REFS();
-        if (ret == E_EOF) {
-            err = 0;
-            break;
+    err = 0;
+    do {
+        ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
+        if (ret == -1 && PyErr_Occurred()) {
+            /* Prevent an endless loop after multiple consecutive MemoryErrors
+             * while still allowing an interactive command to fail with a
+             * MemoryError. */
+            if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
+                if (++nomem_count > 16) {
+                    PyErr_Clear();
+                    err = -1;
+                    break;
+                }
+            } else {
+                nomem_count = 0;
+            }
+            PyErr_Print();
+            flush_io();
+        } else {
+            nomem_count = 0;
         }
-        /*
-        if (ret == E_NOMEM)
-            break;
-        */
-    }
+        _PY_DEBUG_PRINT_TOTAL_REFS();
+    } while (ret != E_EOF);
     Py_DECREF(filename);
     return err;
 }
@@ -148,8 +160,11 @@ static int PARSER_FLAGS(PyCompilerFlags *flags)
                    PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
 #endif
 
-int
-PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
+/* A PyRun_InteractiveOneObject() auxiliary function that does not print the
+ * error on failure. */
+static int
+PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
+                             PyCompilerFlags *flags)
 {
     PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name;
     mod_ty mod;
@@ -161,7 +176,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
 
     mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */
     if (mod_name == NULL) {
-        PyErr_Print();
         return -1;
     }
 
@@ -221,7 +235,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
             PyErr_Clear();
             return E_EOF;
         }
-        PyErr_Print();
         return -1;
     }
     m = PyImport_AddModuleObject(mod_name);
@@ -233,8 +246,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
     v = run_mod(mod, filename, d, d, flags, arena);
     PyArena_Free(arena);
     if (v == NULL) {
-        PyErr_Print();
-        flush_io();
         return -1;
     }
     Py_DECREF(v);
@@ -242,6 +253,19 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
     return 0;
 }
 
+int
+PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
+{
+    int res;
+
+    res = PyRun_InteractiveOneObjectEx(fp, filename, flags);
+    if (res == -1) {
+        PyErr_Print();
+        flush_io();
+    }
+    return res;
+}
+
 int
 PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
 {
@@ -624,9 +648,15 @@ PyErr_PrintEx(int set_sys_last_vars)
         return;
     /* Now we know v != NULL too */
     if (set_sys_last_vars) {
-        _PySys_SetObjectId(&PyId_last_type, exception);
-        _PySys_SetObjectId(&PyId_last_value, v);
-        _PySys_SetObjectId(&PyId_last_traceback, tb);
+        if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
+            PyErr_Clear();
+        }
+        if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
+            PyErr_Clear();
+        }
+        if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
+            PyErr_Clear();
+        }
     }
     hook = _PySys_GetObjectId(&PyId_excepthook);
     if (hook) {
@@ -811,13 +841,21 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
 
     if (seen != NULL) {
         /* Exception chaining */
-        if (PySet_Add(seen, value) == -1)
+        PyObject *value_id = PyLong_FromVoidPtr(value);
+        if (value_id == NULL || PySet_Add(seen, value_id) == -1)
             PyErr_Clear();
         else if (PyExceptionInstance_Check(value)) {
+            PyObject *check_id = NULL;
             cause = PyException_GetCause(value);
             context = PyException_GetContext(value);
             if (cause) {
-                res = PySet_Contains(seen, cause);
+                check_id = PyLong_FromVoidPtr(cause);
+                if (check_id == NULL) {
+                    res = -1;
+                } else {
+                    res = PySet_Contains(seen, check_id);
+                    Py_DECREF(check_id);
+                }
                 if (res == -1)
                     PyErr_Clear();
                 if (res == 0) {
@@ -829,7 +867,13 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
             }
             else if (context &&
                 !((PyBaseExceptionObject *)value)->suppress_context) {
-                res = PySet_Contains(seen, context);
+                check_id = PyLong_FromVoidPtr(context);
+                if (check_id == NULL) {
+                    res = -1;
+                } else {
+                    res = PySet_Contains(seen, check_id);
+                    Py_DECREF(check_id);
+                }
                 if (res == -1)
                     PyErr_Clear();
                 if (res == 0) {
@@ -842,6 +886,7 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
             Py_XDECREF(context);
             Py_XDECREF(cause);
         }
+        Py_XDECREF(value_id);
     }
     print_exception(f, value);
     if (err != 0)
index b416eff6b291e4fd3edc35aa3f366bc4c8a7de6e..19fdb55b066aaf1ded1031a10dff9750419b00d2 100644 (file)
@@ -84,12 +84,19 @@ _PyTime_Round(double x, _PyTime_round_t round)
     volatile double d;
 
     d = x;
-    if (round == _PyTime_ROUND_HALF_EVEN)
+    if (round == _PyTime_ROUND_HALF_EVEN){
         d = _PyTime_RoundHalfEven(d);
-    else if (round == _PyTime_ROUND_CEILING)
+    }
+    else if (round == _PyTime_ROUND_CEILING){
         d = ceil(d);
-    else
+    }
+    else if (round == _PyTime_ROUND_FLOOR) {
         d = floor(d);
+    }
+    else {
+        assert(round == _PyTime_ROUND_UP);
+        d = (d >= 0.0) ? ceil(d) : floor(d);
+    }
     return d;
 }
 
@@ -395,16 +402,29 @@ _PyTime_Divide(const _PyTime_t t, const _PyTime_t k,
         return x;
     }
     else if (round == _PyTime_ROUND_CEILING) {
-        if (t >= 0)
+        if (t >= 0){
             return (t + k - 1) / k;
-        else
+        }
+        else{
             return t / k;
+        }
     }
-    else {
-        if (t >= 0)
+    else if (round == _PyTime_ROUND_FLOOR){
+        if (t >= 0) {
             return t / k;
-        else
+        }
+        else{
             return (t - (k - 1)) / k;
+        }
+    }
+    else {
+        assert(round == _PyTime_ROUND_UP);
+        if (t >= 0) {
+            return (t + k - 1) / k;
+        }
+        else {
+            return (t - (k - 1)) / k;
+        }
     }
 }
 
index 9f8c568b08ad2184e4d9170191417a72d4255771..d9620675f7475ea1f7fde73637c15dec7c0d613d 100644 (file)
@@ -413,57 +413,68 @@ tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
     return err;
 }
 
+static int
+tb_print_line_repeated(PyObject *f, long cnt)
+{
+    int err;
+    PyObject *line = PyUnicode_FromFormat(
+            "  [Previous line repeated %ld more times]\n", cnt-3);
+    if (line == NULL) {
+        return -1;
+    }
+    err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
+    Py_DECREF(line);
+    return err;
+}
+
 static int
 tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
 {
     int err = 0;
-    long depth = 0;
+    Py_ssize_t depth = 0;
     PyObject *last_file = NULL;
     int last_line = -1;
     PyObject *last_name = NULL;
     long cnt = 0;
-    PyObject *line;
     PyTracebackObject *tb1 = tb;
     while (tb1 != NULL) {
         depth++;
         tb1 = tb1->tb_next;
     }
+    while (tb != NULL && depth > limit) {
+        depth--;
+        tb = tb->tb_next;
+    }
     while (tb != NULL && err == 0) {
-        if (depth <= limit) {
-            if (last_file != NULL &&
-                tb->tb_frame->f_code->co_filename == last_file &&
-                last_line != -1 && tb->tb_lineno == last_line &&
-                last_name != NULL &&
-                tb->tb_frame->f_code->co_name == last_name) {
-                    cnt++;
-                } else {
-                    if (cnt > 3) {
-                        line = PyUnicode_FromFormat(
-                        "  [Previous line repeated %d more times]\n", cnt-3);
-                        err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
-                        Py_DECREF(line);
-                    }
-                    last_file = tb->tb_frame->f_code->co_filename;
-                    last_line = tb->tb_lineno;
-                    last_name = tb->tb_frame->f_code->co_name;
-                    cnt = 0;
-                }
-            if (cnt < 3)
-                err = tb_displayline(f,
-                                     tb->tb_frame->f_code->co_filename,
-                                     tb->tb_lineno,
-                                     tb->tb_frame->f_code->co_name);
+        if (last_file != NULL &&
+            tb->tb_frame->f_code->co_filename == last_file &&
+            last_line != -1 && tb->tb_lineno == last_line &&
+            last_name != NULL && tb->tb_frame->f_code->co_name == last_name)
+        {
+            cnt++;
+        }
+        else {
+            if (cnt > 3) {
+                err = tb_print_line_repeated(f, cnt);
+            }
+            last_file = tb->tb_frame->f_code->co_filename;
+            last_line = tb->tb_lineno;
+            last_name = tb->tb_frame->f_code->co_name;
+            cnt = 0;
+        }
+        if (err == 0 && cnt < 3) {
+            err = tb_displayline(f,
+                                 tb->tb_frame->f_code->co_filename,
+                                 tb->tb_lineno,
+                                 tb->tb_frame->f_code->co_name);
+            if (err == 0) {
+                err = PyErr_CheckSignals();
+            }
         }
-        depth--;
         tb = tb->tb_next;
-        if (err == 0)
-            err = PyErr_CheckSignals();
     }
-    if (cnt > 3) {
-        line = PyUnicode_FromFormat(
-        "  [Previous line repeated %d more times]\n", cnt-3);
-        err = PyFile_WriteObject(line, f, Py_PRINT_RAW);
-        Py_DECREF(line);
+    if (err == 0 && cnt > 3) {
+        err = tb_print_line_repeated(f, cnt);
     }
     return err;
 }
@@ -484,26 +495,15 @@ PyTraceBack_Print(PyObject *v, PyObject *f)
         return -1;
     }
     limitv = PySys_GetObject("tracebacklimit");
-    if (limitv) {
-        PyObject *exc_type, *exc_value, *exc_tb;
-
-        PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-        limit = PyLong_AsLong(limitv);
-        if (limit == -1 && PyErr_Occurred()) {
-            if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
-                limit = PyTraceBack_LIMIT;
-            }
-            else {
-                Py_XDECREF(exc_type);
-                Py_XDECREF(exc_value);
-                Py_XDECREF(exc_tb);
-                return 0;
-            }
+    if (limitv && PyLong_Check(limitv)) {
+        int overflow;
+        limit = PyLong_AsLongAndOverflow(limitv, &overflow);
+        if (overflow > 0) {
+            limit = LONG_MAX;
         }
         else if (limit <= 0) {
-            limit = PyTraceBack_LIMIT;
+            return 0;
         }
-        PyErr_Restore(exc_type, exc_value, exc_tb);
     }
     err = PyFile_WriteString("Traceback (most recent call last):\n", f);
     if (!err)
index 88a720010ed21a910033938a99ef0bbea8bf7fb4..05c31da8f2a642e6386d227dbb5d8c9f6d04d7ce 100644 (file)
@@ -1,4 +1,4 @@
-This is Python version 3.6.3
+This is Python version 3.6.4
 ============================
 
 .. image:: https://travis-ci.org/python/cpython.svg?branch=3.6
index 75ac673737edbb48fc24004a2a244f502fe62333..f8663f0a521393322b3f4241739112802c2d831c 100755 (executable)
@@ -928,8 +928,8 @@ class CLanguage(Language):
             cpp_if = "#if " + conditional
             cpp_endif = "#endif /* " + conditional + " */"
 
-            if methoddef_define and f.name not in clinic.ifndef_symbols:
-                clinic.ifndef_symbols.add(f.name)
+            if methoddef_define and f.full_name not in clinic.ifndef_symbols:
+                clinic.ifndef_symbols.add(f.full_name)
                 methoddef_ifndef = normalize_snippet("""
                     #ifndef {methoddef_name}
                         #define {methoddef_name}
index 8335d4c87204e58cf9f868340f86c96ef1e9c66d..256a63e0a00d4e5db491b3efb1c3eeb8aeadb9c6 100755 (executable)
@@ -75,7 +75,6 @@ class ReDemo:
         self.boxes = []
         self.vars = []
         for name in ('IGNORECASE',
-                     'LOCALE',
                      'MULTILINE',
                      'DOTALL',
                      'VERBOSE'):
@@ -83,7 +82,7 @@ class ReDemo:
                 frame = Frame(self.master)
                 frame.pack(fill=X)
                 self.frames.append(frame)
-            val = getattr(re, name)
+            val = getattr(re, name).value
             var = IntVar()
             box = Checkbutton(frame,
                     variable=var, text=name,
index 3b101d7ba71bb9def71c63e014b189daed58e09d..c298cf0bf996405ac6ff49a345475385430af8e9 100644 (file)
     <ProjectGuid>{7A09B132-B3EE-499B-A700-A4B2157FEA3D}</ProjectGuid>\r
     <TargetName>PythonBA</TargetName>\r
   </PropertyGroup>\r
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
   <Import Project="..\..\wix.props" />\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
   <PropertyGroup Label="Configuration">\r
     <ConfigurationType>DynamicLibrary</ConfigurationType>\r
     <CharacterSet>Unicode</CharacterSet>\r
-    <IntDir>$(Py_IntDir)\$(Configuration)_$(Platform)_Setup\Bootstrap\</IntDir>\r
+    <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(PySourcePath)PCbuild\obj\</Py_IntDir>\r
+    <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(ProjectName)\</IntDir>\r
+    <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir>\r
     <OutDir>$(IntDir)</OutDir>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
index 02a456b3fd764d78c30fd342a1eadb6c6910daea..f6cff6fc351dc1837e521ae2146109e92b0d5e0f 100644 (file)
@@ -8,7 +8,6 @@
           IconSourceFile="..\..\..\PC\icons\setup.ico"
           Manufacturer="!(loc.Manufacturer)"
           AboutUrl="http://www.python.org/"
-          DisableModify="button"
           Compressed="no"
           dep:ProviderKey="CPython-$(var.MajorVersionNumber).$(var.MinorVersionNumber)$(var.PyArchExt)$(var.PyTestExt)">
     <BootstrapperApplication Id="PythonBA" SourceFile="$(var.BootstrapApp)">
index 40ad90433199b5d3b072d1f08a1a21a8eb5cfc27..8c59f09a07d69dd92fd5908bf950c3b8ac096372 100644 (file)
@@ -48,7 +48,7 @@
     </ItemGroup>\r
 \r
     <PropertyGroup>\r
-        <IntermediateOutputPath>$(Py_IntDir)\$(Configuration)_$(Platform)_Setup\$(OutputName)</IntermediateOutputPath>\r
+        <IntermediateOutputPath>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(OutputName)</IntermediateOutputPath>\r
         <IntermediateOutputPath Condition="'$(OutputSuffix)' != ''">$(IntermediateOutputPath)_$(OutputSuffix)</IntermediateOutputPath>\r
         <OutputPath Condition="'$(OutputPath)' == ''">$(BuildPath)</OutputPath>\r
         <OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath>\r
index 76dbc49ae82205ebe72abd42e30222d4da8b29f4..24fdae243884724d2e1215aebca024cc54542105 100644 (file)
@@ -25,7 +25,7 @@ except LookupError:
     sys.exit(1)
 
 URL = "https://www.python.org/ftp/python/{}/".format(m.group(1))
-
+REL = m.group(2) or ''
 
 FILES = [
     "core.msi",
@@ -64,7 +64,7 @@ PATHS = [
     "python-{}-webinstall.exe".format(m.group(0)),
     "python-{}-amd64.exe".format(m.group(0)),
     "python-{}-amd64-webinstall.exe".format(m.group(0)),
-] + ["win32{}/{}".format(m.group(2), f) for f in FILES] + ["amd64{}/{}".format(m.group(2), f) for f in FILES]
+] + ["win32{}/{}".format(REL, f) for f in FILES] + ["amd64{}/{}".format(REL, f) for f in FILES]
 
 print('Purged:')
 for n in PATHS:
index 80b0bd8d59c9fca6af24b4a2e37553247b8dc9e3..c4dddd9576e00cac14994f7b9fcc3abf68abda06 100644 (file)
@@ -8,8 +8,9 @@ set HOST=
 set USER=\r
 set TARGET=\r
 set DRYRUN=false\r
+set NOUPLOAD=\r
 set NOGPG=\r
-set PURGE_OPTION=/p:Purge=true\r
+set NOPURGE=\r
 set NOTEST=\r
 \r
 :CheckOpts\r
@@ -21,8 +22,9 @@ if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts
 if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts\r
 if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts\r
 if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-upload" (set NOUPLOAD=true) && shift && goto CheckOpts\r
 if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts\r
-if "%1" EQU "--skip-purge" (set PURGE_OPTION=) && shift && goto CheckOpts\r
+if "%1" EQU "--skip-purge" (set NOPURGE=true) && shift && goto CheckOpts\r
 if "%1" EQU "--skip-test" (set NOTEST=true) && shift && goto CheckOpts\r
 if "%1" EQU "-T" (set NOTEST=true) && shift && goto CheckOpts\r
 if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1\r
@@ -52,17 +54,43 @@ if defined NOGPG (
 call "%PCBUILD%find_msbuild.bat" %MSBUILD%\r
 if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)\r
 pushd "%D%"\r
-%MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION%\r
-%MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION%\r
+if not defined NOUPLOAD (\r
+    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86\r
+    if errorlevel 1 goto :failed\r
+    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false\r
+    if errorlevel 1 goto :failed\r
+)\r
+if not defined NOPURGE (\r
+    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge\r
+)\r
 if not defined NOTEST (\r
-    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86\r
-    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64\r
+    call :test x86\r
+    if errorlevel 1 goto :failed\r
+    call :test x64\r
+    if errorlevel 1 goto :failed\r
 )\r
 %MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86\r
+if errorlevel 1 goto :failed\r
 %MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false\r
+if errorlevel 1 goto :failed\r
+\r
 popd\r
 exit /B 0\r
 \r
+:test\r
+%MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1\r
+if errorlevel 1 (\r
+    echo Test failed - purging and retrying\r
+    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge\r
+    if errorlevel 1 exit /B\r
+    %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1\r
+)\r
+exit /B\r
+\r
+:failed\r
+popd\r
+exit /B\r
+\r
 :Help\r
 echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h]\r
 echo.\r
index dd82ee0fdfba0f8b24a56f37540ba102a0fb756b..1e51104357324d0fb63dde65e415665457148698 100644 (file)
@@ -10,7 +10,6 @@
         <IncludeDoc Condition="'$(IncludeDoc)' == ''">true</IncludeDoc>\r
         <BuildForRelease Condition="'$(BuildForRelease)' == ''">true</BuildForRelease>\r
         <DryRun Condition="'$(DryRun)' == ''">false</DryRun>\r
-        <Purge Condition="'$(Purge)' == ''">false</Purge>\r
     </PropertyGroup>\r
 \r
     <Import Project="msi.props" />\r
@@ -43,7 +42,8 @@
     <Target Name="_RunGpg" Condition="'$(GPG)' != ''" Inputs="@(File)" Outputs="$(IntermediateOutputPath)\gpg\%(FileName)%(Extension).asc">\r
         <MakeDir Directories="$(IntermediateOutputPath)gpg" />\r
         <Delete Files="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc" Condition="Exists('$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc')" />\r
-        <Exec Command="&quot;$(GPG)&quot; -ba -o &quot;$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc&quot; &quot;%(File.FullPath)&quot;" />\r
+        <Exec Command="&quot;$(GPG)&quot; -ba -o &quot;$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc&quot; &quot;%(File.FullPath)&quot;"\r
+              IgnoreExitCode="false" />\r
         <ItemGroup>\r
             <File Include="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc">\r
                 <CopyTo>%(File.CopyTo)</CopyTo>\r
     </Target>\r
     \r
     <Target Name="_Upload" Condition="!$(DryRun)">\r
-        <Exec Command="&quot;$(PLINK)&quot; $(User)@$(Host) mkdir %(File.CopyTo) ^&amp;^&amp; chgrp downloads %(File.CopyTo) ^&amp;^&amp; chmod g-w,o+rx %(File.CopyTo)\r
-&quot;$(PSCP)&quot; @(File,' ') $(User)@$(Host):%(File.CopyTo)\r
-&quot;$(PLINK)&quot; $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*\r
-" />\r
+        <Exec Command="&quot;$(PLINK)&quot; $(User)@$(Host) mkdir %(File.CopyTo) ^&amp;^&amp; chgrp downloads %(File.CopyTo) ^&amp;^&amp; chmod g-w,o+rx %(File.CopyTo)" ContinueOnError="true" />\r
+        <Exec Command="&quot;$(PSCP)&quot; @(File,' ') $(User)@$(Host):%(File.CopyTo)" />\r
+        <Exec Command="&quot;$(PLINK)&quot; $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" ContinueOnError="true" />\r
     </Target>\r
-    \r
+\r
     <Target Name="_PrintNames" Condition="$(DryRun)">\r
-        <Exec Command="echo &quot;$(PLINK)&quot; $(User)@$(Host) mkdir %(File.CopyTo) ^&amp;^&amp; chgrp downloads %(File.CopyTo) ^&amp;^&amp; chmod g-w,o+rx %(File.CopyTo)\r
-echo &quot;$(PSCP)&quot; @(File,' ') $(User)@$(Host):%(File.CopyTo)\r
-echo &quot;$(PLINK)&quot; $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*\r
-echo.\r
-echo." />\r
-    </Target>\r
-    \r
-    <Target Name="_Purge" Condition="$(Purge) and !$(DryRun)">\r
-        <Error Condition="!Exists('$(PythonExe)')" Text="No Python executable available at $(PythonExe)" />\r
-        <Exec Command="&quot;$(PythonExe)&quot; purge.py $(PythonVersion)" />\r
+        <Exec Command="echo &quot;$(PLINK)&quot; $(User)@$(Host) mkdir %(File.CopyTo) ^&amp;^&amp; chgrp downloads %(File.CopyTo) ^&amp;^&amp; chmod g-w,o+rx %(File.CopyTo)" />\r
+        <Exec Command="echo &quot;$(PSCP)&quot; @(File,' ') $(User)@$(Host):%(File.CopyTo)" />\r
+        <Exec Command="echo &quot;$(PLINK)&quot; $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" />\r
     </Target>\r
     \r
     <Target Name="_TestLayout">\r
@@ -82,6 +74,7 @@ echo." />
                 <LogFile>$(OutputPath)\%(Filename)_layoutlog\%(Filename).log</LogFile>\r
             </WebInstaller>\r
         </ItemGroup>\r
+        <Error Text="Could not find installer" Condition="@(WebInstaller) == ''" />\r
         <RemoveDir Directories="%(WebInstaller.SourceDir)" Condition="Exists('%(WebInstaller.SourceDir)')" />\r
         <RemoveDir Directories="%(WebInstaller.LayoutDir)" Condition="Exists('%(WebInstaller.LayoutDir)')" />\r
         <RemoveDir Directories="%(WebInstaller.LogDir)" Condition="Exists('%(WebInstaller.LogDir)')" />\r
@@ -95,14 +88,22 @@ echo." />
         <Message Text="Successfully downloaded %(WebInstaller.Filename)%(WebInstaller.Extension) layout" Importance="high" />\r
     </Target>\r
     \r
-    <Target Name="Upload" DependsOnTargets="_ValidateProperties;_RunGpg;_PrintNames;_Upload;_Purge" />\r
+    <Target Name="Upload" DependsOnTargets="_ValidateProperties;_RunGpg;_PrintNames;_Upload" />\r
     <Target Name="Test" DependsOnTargets="_TestLayout" />\r
     \r
+    <Target Name="Purge">\r
+        <Error Condition="!Exists('$(PythonExe)')" Text="No Python executable available at $(PythonExe)" />\r
+        <Exec Command="echo &quot;$(PythonExe)&quot; purge.py $(PythonVersion)" Condition="$(DryRun)" />\r
+        <Exec Command="&quot;$(PythonExe)&quot; purge.py $(PythonVersion)" Condition="!$(DryRun)" />\r
+        <Message Text="Purged uploaded files" Importance="high" />\r
+    </Target>\r
+    \r
     <Target Name="ShowHashes">\r
         <ItemGroup>\r
             <UserFiles Include="@(File)" Condition="'%(File.CopyTo)' == '$(EXETarget)'" />\r
         </ItemGroup>\r
         \r
+        <Error Text="No files generated" Condition="@(UserFiles) == ''" />\r
         <Exec Command="&quot;$(PythonExe)&quot; generate_md5.py @(UserFiles->'&quot;%(FullPath)&quot;',' ')" />\r
     </Target>\r
     \r
index 652d3940a49a403f26719d5d4529376b4600a59e..215e2bd4e54261302b8514b432aab8658acf03a4 100755 (executable)
@@ -33,7 +33,7 @@ write_slave = "ask"
 write_master = "ask"
 
 def main():
-    global always_no, always_yes
+    global default_answer, always_no, always_yes, create_files
     global create_directories, write_master, write_slave
     opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:")
     for o, a in opts:
diff --git a/Tools/scripts/update_file.py b/Tools/scripts/update_file.py
new file mode 100644 (file)
index 0000000..224585c
--- /dev/null
@@ -0,0 +1,28 @@
+"""
+A script that replaces an old file with a new one, only if the contents
+actually changed.  If not, the new file is simply deleted.
+
+This avoids wholesale rebuilds when a code (re)generation phase does not
+actually change the in-tree generated code.
+"""
+
+import os
+import sys
+
+
+def main(old_path, new_path):
+    with open(old_path, 'rb') as f:
+        old_contents = f.read()
+    with open(new_path, 'rb') as f:
+        new_contents = f.read()
+    if old_contents != new_contents:
+        os.replace(new_path, old_path)
+    else:
+        os.unlink(new_path)
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        print("Usage: %s <path to be updated> <path with new contents>" % (sys.argv[0],))
+        sys.exit(1)
+    main(sys.argv[1], sys.argv[2])
index 994e420818ed12e3659bb94a8d6f56490d6d8b73..ce5bbd85308c5a0c1a8467ab44ee8a96a6f76c11 100755 (executable)
@@ -41,15 +41,14 @@ import tarfile
 log = logging.getLogger("multissl")
 
 OPENSSL_OLD_VERSIONS = [
-     "0.9.8zc",
      "0.9.8zh",
      "1.0.1u",
 ]
 
 OPENSSL_RECENT_VERSIONS = [
      "1.0.2",
-     "1.0.2l",
-     "1.1.0f",
+     "1.0.2m",
+     "1.1.0g",
 ]
 
 LIBRESSL_OLD_VERSIONS = [
index ed305a89b4b75eb25a592efda25983f78a536f96..ea1baef55d3035259760bb0fd17bed083fa61903 100755 (executable)
--- a/configure
+++ b/configure
@@ -3536,14 +3536,14 @@ then
                for as_dir in $PATH
                do
                        IFS=$as_save_IFS
-                       if test -x $as_dir/gcc; then
+                       if test -x "${as_dir}/gcc"; then
                                if test -z "${found_gcc}"; then
-                                       found_gcc=$as_dir/gcc
+                                       found_gcc="${as_dir}/gcc"
                                fi
                        fi
-                       if test -x $as_dir/clang; then
+                       if test -x "${as_dir}/clang"; then
                                if test -z "${found_clang}"; then
-                                       found_clang=$as_dir/clang
+                                       found_clang="${as_dir}/clang"
                                fi
                        fi
                done
@@ -15897,6 +15897,10 @@ $as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h
 
 fi
 
+# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
+# structs since version 5.7.  If the macro is defined as zero before including
+# [n]curses.h, ncurses will expose fields of the structs regardless of the
+# configuration.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5
 $as_echo_n "checking whether WINDOW has _flags... " >&6; }
 if ${ac_cv_window_has_flags+:} false; then :
@@ -15904,7 +15908,10 @@ if ${ac_cv_window_has_flags+:} false; then :
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <curses.h>
+
+  #define NCURSES_OPAQUE 0
+  #include <curses.h>
+
 int
 main ()
 {
@@ -15935,6 +15942,36 @@ $as_echo "#define WINDOW_HAS_FLAGS 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_pad" >&5
+$as_echo_n "checking for is_pad... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef is_pad
+void *x=is_pad
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_term_resized" >&5
 $as_echo_n "checking for is_term_resized... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -16010,6 +16047,216 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for immedok" >&5
+$as_echo_n "checking for immedok... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef immedok
+void *x=immedok
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_IMMEDOK 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for syncok" >&5
+$as_echo_n "checking for syncok... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef syncok
+void *x=syncok
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_SYNCOK 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wchgat" >&5
+$as_echo_n "checking for wchgat... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef wchgat
+void *x=wchgat
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_WCHGAT 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for filter" >&5
+$as_echo_n "checking for filter... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef filter
+void *x=filter
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_FILTER 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for has_key" >&5
+$as_echo_n "checking for has_key... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef has_key
+void *x=has_key
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_HAS_KEY 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeahead" >&5
+$as_echo_n "checking for typeahead... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef typeahead
+void *x=typeahead
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_TYPEAHEAD 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for use_env" >&5
+$as_echo_n "checking for use_env... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <curses.h>
+int
+main ()
+{
+
+#ifndef use_env
+void *x=use_env
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_CURSES_USE_ENV 1" >>confdefs.h
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 # last curses configure check
@@ -16306,7 +16553,7 @@ do
 done
 
 
-SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
+SRCDIRS="Parser Objects Python Modules Programs"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5
 $as_echo_n "checking for build directories... " >&6; }
 for dir in $SRCDIRS; do
index e400fa187de7d714100cb5e68c5ec6b90c4ad49c..fc1dba6b029158a9e9c89417c38e40b77e210ee1 100644 (file)
@@ -642,14 +642,14 @@ then
                for as_dir in $PATH
                do
                        IFS=$as_save_IFS
-                       if test -x $as_dir/gcc; then
+                       if test -x "${as_dir}/gcc"; then
                                if test -z "${found_gcc}"; then
-                                       found_gcc=$as_dir/gcc
+                                       found_gcc="${as_dir}/gcc"
                                fi
                        fi
-                       if test -x $as_dir/clang; then
+                       if test -x "${as_dir}/clang"; then
                                if test -z "${found_clang}"; then
-                                       found_clang=$as_dir/clang
+                                       found_clang="${as_dir}/clang"
                                fi
                        fi
                done
@@ -4993,9 +4993,16 @@ then
   [Define if mvwdelch in curses.h is an expression.])
 fi
 
+# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
+# structs since version 5.7.  If the macro is defined as zero before including
+# [n]curses.h, ncurses will expose fields of the structs regardless of the
+# configuration.
 AC_MSG_CHECKING(whether WINDOW has _flags)
 AC_CACHE_VAL(ac_cv_window_has_flags,
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+  #define NCURSES_OPAQUE 0
+  #include <curses.h>
+]], [[
   WINDOW *w;
   w->_flags = 0;
 ]])],
@@ -5010,6 +5017,17 @@ then
   [Define if WINDOW in curses.h offers a field _flags.])
 fi
 
+AC_MSG_CHECKING(for is_pad)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef is_pad
+void *x=is_pad
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_IS_PAD, 1, Define if you have the 'is_pad' function or macro.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
 AC_MSG_CHECKING(for is_term_resized)
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=is_term_resized]])],
   [AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.)
@@ -5030,6 +5048,83 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=resizeterm
    AC_MSG_RESULT(yes)],
   [AC_MSG_RESULT(no)]
 )
+
+AC_MSG_CHECKING(for immedok)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef immedok
+void *x=immedok
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_IMMEDOK, 1, Define if you have the 'immedok' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for syncok)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef syncok
+void *x=syncok
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_SYNCOK, 1, Define if you have the 'syncok' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for wchgat)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef wchgat
+void *x=wchgat
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_WCHGAT, 1, Define if you have the 'wchgat' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for filter)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef filter
+void *x=filter
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_FILTER, 1, Define if you have the 'filter' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for has_key)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef has_key
+void *x=has_key
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_HAS_KEY, 1, Define if you have the 'has_key' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for typeahead)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef typeahead
+void *x=typeahead
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_TYPEAHEAD, 1, Define if you have the 'typeahead' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
+
+AC_MSG_CHECKING(for use_env)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
+#ifndef use_env
+void *x=use_env
+#endif
+]])],
+  [AC_DEFINE(HAVE_CURSES_USE_ENV, 1, Define if you have the 'use_env' function.)
+   AC_MSG_RESULT(yes)],
+  [AC_MSG_RESULT(no)]
+)
 # last curses configure check
 CPPFLAGS=$ac_save_cppflags
 
@@ -5207,7 +5302,7 @@ do
 done
 
 AC_SUBST(SRCDIRS)
-SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
+SRCDIRS="Parser Objects Python Modules Programs"
 AC_MSG_CHECKING(for build directories)
 for dir in $SRCDIRS; do
     if test ! -d $dir; then
index cdcb5704a8552ca1cd9b3af289e0252b9a9562fb..bc2693b0b2148dd4c8371607a4314de2d7e75742 100644 (file)
 /* Define if you have the 'ctermid_r' function. */
 #undef HAVE_CTERMID_R
 
+/* Define if you have the 'filter' function. */
+#undef HAVE_CURSES_FILTER
+
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
+/* Define if you have the 'has_key' function. */
+#undef HAVE_CURSES_HAS_KEY
+
+/* Define if you have the 'immedok' function. */
+#undef HAVE_CURSES_IMMEDOK
+
+/* Define if you have the 'is_pad' function or macro. */
+#undef HAVE_CURSES_IS_PAD
+
 /* Define if you have the 'is_term_resized' function. */
 #undef HAVE_CURSES_IS_TERM_RESIZED
 
 /* Define if you have the 'resize_term' function. */
 #undef HAVE_CURSES_RESIZE_TERM
 
+/* Define if you have the 'syncok' function. */
+#undef HAVE_CURSES_SYNCOK
+
+/* Define if you have the 'typeahead' function. */
+#undef HAVE_CURSES_TYPEAHEAD
+
+/* Define if you have the 'use_env' function. */
+#undef HAVE_CURSES_USE_ENV
+
+/* Define if you have the 'wchgat' function. */
+#undef HAVE_CURSES_WCHGAT
+
 /* Define to 1 if you have the declaration of `isfinite', and to 0 if you
    don't. */
 #undef HAVE_DECL_ISFINITE
index 1cd15039970b8d1367252fc21916ca64663e60ac..0d644db8573e51b323babd5ff762f176be78caa9 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -60,6 +60,31 @@ def add_dir_to_list(dirlist, dir):
             return
     dirlist.insert(0, dir)
 
+def sysroot_paths(make_vars, subdirs):
+    """Get the paths of sysroot sub-directories.
+
+    * make_vars: a sequence of names of variables of the Makefile where
+      sysroot may be set.
+    * subdirs: a sequence of names of subdirectories used as the location for
+      headers or libraries.
+    """
+
+    dirs = []
+    for var_name in make_vars:
+        var = sysconfig.get_config_var(var_name)
+        if var is not None:
+            m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var)
+            if m is not None:
+                sysroot = m.group(1).strip('"')
+                for subdir in subdirs:
+                    if os.path.isabs(subdir):
+                        subdir = subdir[1:]
+                    path = os.path.join(sysroot, subdir)
+                    if os.path.isdir(path):
+                        dirs.append(path)
+                break
+    return dirs
+
 def macosx_sdk_root():
     """
     Return the directory of the current OSX SDK,
@@ -544,18 +569,23 @@ class PyBuildExt(build_ext):
             add_dir_to_list(self.compiler.include_dirs,
                             sysconfig.get_config_var("INCLUDEDIR"))
 
+        system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib']
+        system_include_dirs = ['/usr/include']
         # lib_dirs and inc_dirs are used to search for files;
         # if a file is found in one of those directories, it can
         # be assumed that no additional -I,-L directives are needed.
         if not cross_compiling:
-            lib_dirs = self.compiler.library_dirs + [
-                '/lib64', '/usr/lib64',
-                '/lib', '/usr/lib',
-                ]
-            inc_dirs = self.compiler.include_dirs + ['/usr/include']
+            lib_dirs = self.compiler.library_dirs + system_lib_dirs
+            inc_dirs = self.compiler.include_dirs + system_include_dirs
         else:
-            lib_dirs = self.compiler.library_dirs[:]
-            inc_dirs = self.compiler.include_dirs[:]
+            # Add the sysroot paths. 'sysroot' is a compiler option used to
+            # set the logical path of the standard system headers and
+            # libraries.
+            lib_dirs = (self.compiler.library_dirs +
+                        sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs))
+            inc_dirs = (self.compiler.include_dirs +
+                        sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'),
+                                      system_include_dirs))
         exts = []
         missing = []
 
@@ -1496,6 +1526,7 @@ class PyBuildExt(build_ext):
         if '--with-system-expat' in sysconfig.get_config_var("CONFIG_ARGS"):
             expat_inc = []
             define_macros = []
+            extra_compile_args = []
             expat_lib = ['expat']
             expat_sources = []
             expat_depends = []
@@ -1507,6 +1538,7 @@ class PyBuildExt(build_ext):
                 # call XML_SetHashSalt(), expat entropy sources are not needed
                 ('XML_POOR_ENTROPY', '1'),
             ]
+            extra_compile_args = []
             expat_lib = []
             expat_sources = ['expat/xmlparse.c',
                              'expat/xmlrole.c',
@@ -1524,8 +1556,15 @@ class PyBuildExt(build_ext):
                              'expat/xmltok_impl.h'
                              ]
 
+            cc = sysconfig.get_config_var('CC').split()[0]
+            ret = os.system(
+                      '"%s" -Werror -Wimplicit-fallthrough -E -xc /dev/null >/dev/null 2>&1' % cc)
+            if ret >> 8 == 0:
+                extra_compile_args.append('-Wno-implicit-fallthrough')
+
         exts.append(Extension('pyexpat',
                               define_macros = define_macros,
+                              extra_compile_args = extra_compile_args,
                               include_dirs = expat_inc,
                               libraries = expat_lib,
                               sources = ['pyexpat.c'] + expat_sources,